You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

446 lines
11KB

  1. var fs = require('fs');
  2. var stream = fs.createWriteStream("proglog.txt");
  3. var utils = require("./utils.js");
  4. var genesisCoinbaseTransactionTxid = "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b";
  5. var genesisCoinbaseTransaction = {
  6. "hex": "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0804ffff001d02fd04ffffffff0100f2052a01000000434104f5eeb2b10c944c6b9fbcfff94c35bdeecd93df977882babc7f3a2cf7f5c81d3b09a68db7f0e04f21de5d4230e75e6dbe7ad16eefe0d4325a62067dc6f369446aac00000000",
  7. "txid": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
  8. "hash": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
  9. "size": 204,
  10. "vsize": 204,
  11. "version": 1,
  12. "confirmations":475000,
  13. "vin": [
  14. {
  15. "coinbase": "04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73",
  16. "sequence": 4294967295
  17. }
  18. ],
  19. "vout": [
  20. {
  21. "value": 50,
  22. "n": 0,
  23. "scriptPubKey": {
  24. "asm": "04f5eeb2b10c944c6b9fbcfff94c35bdeecd93df977882babc7f3a2cf7f5c81d3b09a68db7f0e04f21de5d4230e75e6dbe7ad16eefe0d4325a62067dc6f369446a OP_CHECKSIG",
  25. "hex": "4104f5eeb2b10c944c6b9fbcfff94c35bdeecd93df977882babc7f3a2cf7f5c81d3b09a68db7f0e04f21de5d4230e75e6dbe7ad16eefe0d4325a62067dc6f369446aac",
  26. "reqSigs": 1,
  27. "type": "pubkey",
  28. "addresses": [
  29. "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
  30. ]
  31. }
  32. }
  33. ],
  34. "blockhash": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
  35. "time": 1230988505,
  36. "blocktime": 1230988505
  37. };
  38. function getInfo() {
  39. return new Promise(function(resolve, reject) {
  40. client.cmd('getinfo', function(err, result, resHeaders) {
  41. if (err) {
  42. console.log("Error 3207fh0f: " + err);
  43. reject(err);
  44. return;
  45. }
  46. resolve(result);
  47. });
  48. });
  49. }
  50. function getMiningInfo() {
  51. return new Promise(function(resolve, reject) {
  52. client.cmd('getmininginfo', function(err, result, resHeaders) {
  53. if (err) {
  54. console.log("Error 3207fh0f: " + err);
  55. reject(err);
  56. return;
  57. }
  58. resolve(result);
  59. });
  60. });
  61. }
  62. function getMempoolInfo() {
  63. return new Promise(function(resolve, reject) {
  64. client.cmd('getmempoolinfo', function(err, result, resHeaders) {
  65. if (err) {
  66. console.log("Error 23407rhwe07fg: " + err);
  67. reject(err);
  68. return;
  69. }
  70. resolve(result);
  71. });
  72. });
  73. }
  74. function getMempoolStats() {
  75. return new Promise(function(resolve, reject) {
  76. client.cmd('getrawmempool', true, function(err, result, resHeaders) {
  77. if (err) {
  78. console.log("Error 428thwre0ufg: " + err);
  79. reject(err);
  80. return;
  81. }
  82. var compiledResult = {};
  83. compiledResult.count = 0;
  84. compiledResult.fee_0_5 = 0;
  85. compiledResult.fee_6_10 = 0;
  86. compiledResult.fee_11_25 = 0;
  87. compiledResult.fee_26_50 = 0;
  88. compiledResult.fee_51_75 = 0;
  89. compiledResult.fee_76_100 = 0;
  90. compiledResult.fee_101_150 = 0;
  91. compiledResult.fee_151_max = 0;
  92. var totalFee = 0;
  93. for (var txid in result) {
  94. var txMempoolInfo = result[txid];
  95. totalFee += txMempoolInfo.modifiedfee;
  96. var feeRate = Math.round(txMempoolInfo.modifiedfee * 100000000 / txMempoolInfo.size);
  97. if (feeRate <= 5) {
  98. compiledResult.fee_0_5++;
  99. } else if (feeRate <= 10) {
  100. compiledResult.fee_6_10++;
  101. } else if (feeRate <= 25) {
  102. compiledResult.fee_11_25++;
  103. } else if (feeRate <= 50) {
  104. compiledResult.fee_26_50++;
  105. } else if (feeRate <= 75) {
  106. compiledResult.fee_51_75++;
  107. } else if (feeRate <= 100) {
  108. compiledResult.fee_76_100++;
  109. } else if (feeRate <= 150) {
  110. compiledResult.fee_101_150++;
  111. } else {
  112. compiledResult.fee_151_max++;
  113. }
  114. compiledResult.count++;
  115. }
  116. compiledResult.totalFee = totalFee;
  117. resolve(compiledResult);
  118. });
  119. });
  120. }
  121. function getBlockByHeight(blockHeight) {
  122. console.log("getBlockByHeightzz: " + blockHeight);
  123. console.log("xxxxxxxxxxxxxxxxxxxxxxxxxxxxx \n");
  124. //*************************************************************************************
  125. stream.write('block:'+blockHeight);
  126. return new Promise(function(resolve, reject) {
  127. var client = global.client;
  128. client.cmd('getblockhash', blockHeight, function(err, result, resHeaders) {
  129. if (err) {
  130. console.log("Error 0928317yr3w: " + err);
  131. reject(err);
  132. return;
  133. }
  134. client.cmd('getblock', result, function(err2, result2, resHeaders2) {
  135. if (err2) {
  136. console.log("Error 320fh7e0hg: " + err2);
  137. reject(err2);
  138. return;
  139. }
  140. resolve({ success:true, getblockhash:result, getblock:result2 });
  141. });
  142. });
  143. });
  144. }
  145. function getBlocksByHeight(blockHeights) {
  146. console.log("getBlocksByHeight: " + blockHeights);
  147. console.log("getBlockByHeightzz: " + blockHeights);
  148. console.log("xxxxxxxxxxxxxxxxxxxxxxxxxxxxx \n");
  149. //*************************************************************************************
  150. stream.write('block:'+blockHeights+"\n");
  151. return new Promise(function(resolve, reject) {
  152. var batch = [];
  153. for (var i = 0; i < blockHeights.length; i++) {
  154. batch.push({
  155. method: 'getblockhash',
  156. params: [ blockHeights[i] ]
  157. });
  158. }
  159. var blockHashes = [];
  160. client.cmd(batch, function(err, result, resHeaders) {
  161. blockHashes.push(result);
  162. if (blockHashes.length == batch.length) {
  163. var batch2 = [];
  164. for (var i = 0; i < blockHashes.length; i++) {
  165. batch2.push({
  166. method: 'getblock',
  167. params: [ blockHashes[i] ]
  168. });
  169. }
  170. var blocks = [];
  171. client.cmd(batch2, function(err2, result2, resHeaders2) {
  172. if (err2) {
  173. console.log("Error 138ryweufdf: " + err2);
  174. }
  175. blocks.push(result2);
  176. if (blocks.length == batch2.length) {
  177. resolve(blocks);
  178. }
  179. });
  180. }
  181. });
  182. });
  183. }
  184. function getBlockByHash(blockHash) {
  185. console.log("getBlockByHash: " + blockHash);
  186. return new Promise(function(resolve, reject) {
  187. var client = global.client;
  188. client.cmd('getblock', blockHash, function(err, result, resHeaders) {
  189. if (err) {
  190. console.log("Error 0u2fgewue: " + err);
  191. reject(err);
  192. return;
  193. }
  194. resolve(result);
  195. });
  196. });
  197. }
  198. function getTransactionInputs(rpcClient, transaction, inputLimit=0) {
  199. console.log("getTransactionInputs: " + transaction.txid);
  200. return new Promise(function(resolve, reject) {
  201. var txids = [];
  202. for (var i = 0; i < transaction.vin.length; i++) {
  203. if (i < inputLimit || inputLimit == 0) {
  204. txids.push(transaction.vin[i].txid);
  205. }
  206. }
  207. getRawTransactions(txids).then(function(inputTransactions) {
  208. resolve({ txid:transaction.txid, inputTransactions:inputTransactions });
  209. });
  210. });
  211. }
  212. function getRawTransaction(txid) {
  213. return new Promise(function(resolve, reject) {
  214. if (txid == genesisCoinbaseTransactionTxid) {
  215. getBlockByHeight(0).then(function(blockZeroResult) {
  216. var result = genesisCoinbaseTransaction;
  217. result.confirmations = blockZeroResult.getblock.confirmations;
  218. resolve(result);
  219. });
  220. return;
  221. }
  222. client.cmd('getrawtransaction', txid, 1, function(err, result, resHeaders) {
  223. if (err) {
  224. console.log("Error 329813yre823: " + err);
  225. reject(err);
  226. return;
  227. }
  228. resolve(result);
  229. });
  230. });
  231. }
  232. function getRawTransactions(txids) {
  233. console.log("getRawTransactions: " + txids);
  234. return new Promise(function(resolve, reject) {
  235. if (!txids || txids.length == 0) {
  236. resolve([]);
  237. return;
  238. }
  239. if (txids.length == 1 && txids[0] == "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b") {
  240. // copy the "confirmations" field from genesis block to the genesis-coinbase tx
  241. getBlockByHeight(0).then(function(blockZeroResult) {
  242. var result = genesisCoinbaseTransaction;
  243. result.confirmations = blockZeroResult.getblock.confirmations;
  244. resolve([result]);
  245. }).catch(function(err) {
  246. reject(err);
  247. return;
  248. });
  249. return;
  250. }
  251. var requests = [];
  252. for (var i = 0; i < txids.length; i++) {
  253. var txid = txids[i];
  254. if (txid) {
  255. requests.push({
  256. method: 'getrawtransaction',
  257. params: [ txid, 1 ]
  258. });
  259. }
  260. }
  261. var requestBatches = utils.splitArrayIntoChunks(requests, 20);
  262. executeBatchesSequentially(requestBatches, function(results) {
  263. resolve(results);
  264. });
  265. });
  266. }
  267. function executeBatchesSequentially(batches, resultFunc) {
  268. var batchId = utils.getRandomString(20, 'aA#');
  269. console.log("Starting " + batches.length + "-item batch " + batchId + "...");
  270. executeBatchesSequentiallyInternal(batchId, batches, 0, [], resultFunc);
  271. }
  272. function executeBatchesSequentiallyInternal(batchId, batches, currentIndex, accumulatedResults, resultFunc) {
  273. if (currentIndex == batches.length) {
  274. console.log("Finishing batch " + batchId + "...");
  275. resultFunc(accumulatedResults);
  276. return;
  277. }
  278. console.log("Executing item #" + (currentIndex + 1) + " (of " + batches.length + ") for batch " + batchId);
  279. var count = batches[currentIndex].length;
  280. client.cmd(batches[currentIndex], function(err, result, resHeaders) {
  281. if (err) {
  282. console.log("Error f83024hf4: " + err);
  283. }
  284. accumulatedResults.push(result);
  285. count--;
  286. if (count == 0) {
  287. executeBatchesSequentiallyInternal(batchId, batches, currentIndex + 1, accumulatedResults, resultFunc);
  288. }
  289. });
  290. }
  291. function getBlockData(rpcClient, blockHash, txLimit, txOffset) {
  292. console.log("getBlockData: " + blockHash);
  293. return new Promise(function(resolve, reject) {
  294. client.cmd('getblock', blockHash, function(err2, result2, resHeaders2) {
  295. if (err2) {
  296. console.log("Error 3017hfwe0f: " + err2);
  297. reject(err2);
  298. return;
  299. }
  300. var txids = [];
  301. for (var i = txOffset; i < Math.min(txOffset + txLimit, result2.tx.length); i++) {
  302. txids.push(result2.tx[i]);
  303. }
  304. getRawTransactions(txids).then(function(transactions) {
  305. var txInputsByTransaction = {};
  306. var promises = [];
  307. for (var i = 0; i < transactions.length; i++) {
  308. var transaction = transactions[i];
  309. if (transaction) {
  310. promises.push(getTransactionInputs(client, transaction, 10));
  311. }
  312. }
  313. Promise.all(promises).then(function() {
  314. var results = arguments[0];
  315. for (var i = 0; i < results.length; i++) {
  316. var resultX = results[i];
  317. txInputsByTransaction[resultX.txid] = resultX.inputTransactions;
  318. }
  319. resolve({ getblock:result2, transactions:transactions, txInputsByTransaction:txInputsByTransaction });
  320. });
  321. });
  322. });
  323. });
  324. }
  325. module.exports = {
  326. getInfo: getInfo,
  327. getMiningInfo: getMiningInfo,
  328. getMempoolInfo: getMempoolInfo,
  329. getBlockByHeight: getBlockByHeight,
  330. getBlocksByHeight: getBlocksByHeight,
  331. getBlockByHash: getBlockByHash,
  332. getTransactionInputs: getTransactionInputs,
  333. getBlockData: getBlockData,
  334. getRawTransaction: getRawTransaction,
  335. getRawTransactions: getRawTransactions,
  336. getMempoolStats: getMempoolStats
  337. };