diff --git a/app/api/coreApi.js b/app/api/coreApi.js index 5dd9a2e..0a54dba 100644 --- a/app/api/coreApi.js +++ b/app/api/coreApi.js @@ -326,29 +326,66 @@ function getRawTransactions(txids) { }); } -function getMinerFromCoinbaseTx(tx) { - if (global.miningPoolsConfig) { - for (var coinbaseTag in global.miningPoolsConfig.coinbase_tags) { - if (global.miningPoolsConfig.coinbase_tags.hasOwnProperty(coinbaseTag)) { - if (utils.hex2ascii(tx.vin[0].coinbase).indexOf(coinbaseTag) != -1) { - return global.miningPoolsConfig.coinbase_tags[coinbaseTag]; - } +function getBlockByHashWithTransactions(blockHash, txLimit, txOffset) { + return new Promise(function(resolve, reject) { + getBlockByHash(blockHash).then(function(block) { + var txids = []; + + if (txOffset > 0) { + txids.push(block.tx[0]); } - } - for (var payoutAddress in global.miningPoolsConfig.payout_addresses) { - if (global.miningPoolsConfig.payout_addresses.hasOwnProperty(payoutAddress)) { - return global.miningPoolsConfig.payout_addresses[payoutAddress]; + for (var i = txOffset; i < (txOffset + txLimit); i++) { + txids.push(block.tx[i]); } - } - } - return null; -} + getRawTransactions(txids).then(function(transactions) { + if (transactions.length == txids.length) { + block.coinbaseTx = transactions[0]; + block.miner = utils.getMinerFromCoinbaseTx(block.coinbaseTx); + } -function getBlockByHashWithTransactions(blockHash, txLimit, txOffset) { - return tryCacheThenRpcApi(miscCache, "getBlockByHashWithTransactions-" + blockHash + "-" + txLimit + "-" + txOffset, 3600000, function() { - return rpcApi.getBlockByHashWithTransactions(blockHash, txLimit, txOffset); + // if we're on page 2, we don't really want it anymore... + if (txOffset > 0) { + transactions.shift(); + } + + var maxInputsTracked = 10; + var vinTxids = []; + for (var i = 0; i < transactions.length; i++) { + var transaction = transactions[i]; + + if (transaction) { + for (var j = 0; j < Math.min(maxInputsTracked, transaction.vin.length); j++) { + if (transaction.vin[j].txid) { + vinTxids.push(transaction.vin[j].txid); + } + } + } + } + + var txInputsByTransaction = {}; + getRawTransactions(vinTxids).then(function(vinTransactions) { + var vinTxById = {}; + + vinTransactions.forEach(function(tx) { + vinTxById[tx.txid] = tx; + }); + + transactions.forEach(function(tx) { + txInputsByTransaction[tx.txid] = []; + + for (var i = 0; i < Math.min(maxInputsTracked, tx.vin.length); i++) { + if (vinTxById[tx.vin[i].txid]) { + txInputsByTransaction[tx.txid].push(vinTxById[tx.vin[i].txid]); + } + } + + resolve({ getblock:block, transactions:transactions, txInputsByTransaction:txInputsByTransaction }); + }); + }); + }); + }); }); } diff --git a/app/api/mockApi.js b/app/api/mockApi.js index f6d3671..d850235 100644 --- a/app/api/mockApi.js +++ b/app/api/mockApi.js @@ -283,197 +283,6 @@ function getMinerFromCoinbaseTx(tx) { return null; } -function getBlockByHashWithTransactions(blockHash, txLimit, txOffset) { - return new Promise(function(resolve, reject) { - resolve({ - getblock:{ - "hash": blockHash, - "confirmations": 3, - "strippedsize": 56098, - "size": 65384, - "weight": 233678, - "height": 123456, - "version": 536870912, - "versionHex": "20000000", - "merkleroot": "567a3d773b07372179ad651edc02776f851020af69b7375a68ad89557dcbff5b", - "tx": [ - "a97a04ebcaaca0ec80a6b2f295171eb8b082b4bc5446cd085444c304dca6f014", - "223fdd9cae01f3253adc0f0133cc8e6bebdb6f1481dfa0cd9cbfebff656f32f8", - ], - "time": 1529848136, - "mediantime": 1529846560, - "nonce": 3615953854, - "bits": "17376f56", - "difficulty": "5077499034879.017", - "chainwork": "00000000000000000000000000000000000000000226420affb91a60111258b4", - "previousblockhash": "0000000000000000003147c5229962ca4e38714fc5aee8cf38670cf1a4ef297b", - "nextblockhash": "0000000000000000003382a0eef5b127c5d5ea270c85d9db3f3c605d32287cc5" - }, - transactions: [ - { - "txid": "a97a04ebcaaca0ec80a6b2f295171eb8b082b4bc5446cd085444c304dca6f014", - "hash": "a97a04ebcaaca0ec80a6b2f295171eb8b082b4bc5446cd085444c304dca6f014", - "version": 1, - "size": 237, - "vsize": 210, - "locktime": 0, - "vin": [ - { - "coinbase": "03851208fabe6d6d7bf60491521f081d77fa018fb41a167dd447bf20e7d2487426c3cee65332cdb50100000000000000266508019fcf7fcb7b01002ffd0c2f736c7573682f", - "sequence": 0 - } - ], - "vout": [ - { - "value": 12.51946416, - "n": 0, - "scriptPubKey": { - "asm": "OP_DUP OP_HASH160 7c154ed1dc59609e3d26abb2df2ea3d587cd8c41 OP_EQUALVERIFY OP_CHECKSIG", - "hex": "76a9147c154ed1dc59609e3d26abb2df2ea3d587cd8c4188ac", - "reqSigs": 1, - "type": "pubkeyhash", - "addresses": [ - "1CK6KHY6MHgYvmRQ4PAafKYDrg1ejbH1cE" - ] - } - }, - { - "value": 0, - "n": 1, - "scriptPubKey": { - "asm": "OP_RETURN aa21a9ed2b367f88dbcc39b83e89703d5425a9b51fa3d2d921b8f39a42bc54492b986281", - "hex": "6a24aa21a9ed2b367f88dbcc39b83e89703d5425a9b51fa3d2d921b8f39a42bc54492b986281", - "type": "nulldata" - } - } - ], - "hex": "010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff4503851208fabe6d6d7bf60491521f081d77fa018fb41a167dd447bf20e7d2487426c3cee65332cdb50100000000000000266508019fcf7fcb7b01002ffd0c2f736c7573682f0000000002b02f9f4a000000001976a9147c154ed1dc59609e3d26abb2df2ea3d587cd8c4188ac0000000000000000266a24aa21a9ed2b367f88dbcc39b83e89703d5425a9b51fa3d2d921b8f39a42bc54492b9862810120000000000000000000000000000000000000000000000000000000000000000000000000", - "blockhash": "000000000000000000001542470d8261b9e5a2c3c2be2e2ab292d1a4c8250b12", - "confirmations": 3, - "time": 1529848136, - "blocktime": 1529848136 - }, - { - "txid": "223fdd9cae01f3253adc0f0133cc8e6bebdb6f1481dfa0cd9cbfebff656f32f8", - "hash": "223fdd9cae01f3253adc0f0133cc8e6bebdb6f1481dfa0cd9cbfebff656f32f8", - "version": 1, - "size": 237, - "vsize": 210, - "locktime": 0, - "vin": [ - { - "coinbase": "03851208fabe6d6d7bf60491521f081d77fa018fb41a167dd447bf20e7d2487426c3cee65332cdb50100000000000000266508019fcf7fcb7b01002ffd0c2f736c7573682f", - "sequence": 0 - } - ], - "vout": [ - { - "value": 12.51946416, - "n": 0, - "scriptPubKey": { - "asm": "OP_DUP OP_HASH160 7c154ed1dc59609e3d26abb2df2ea3d587cd8c41 OP_EQUALVERIFY OP_CHECKSIG", - "hex": "76a9147c154ed1dc59609e3d26abb2df2ea3d587cd8c4188ac", - "reqSigs": 1, - "type": "pubkeyhash", - "addresses": [ - "1CK6KHY6MHgYvmRQ4PAafKYDrg1ejbH1cE" - ] - } - }, - { - "value": 0, - "n": 1, - "scriptPubKey": { - "asm": "OP_RETURN aa21a9ed2b367f88dbcc39b83e89703d5425a9b51fa3d2d921b8f39a42bc54492b986281", - "hex": "6a24aa21a9ed2b367f88dbcc39b83e89703d5425a9b51fa3d2d921b8f39a42bc54492b986281", - "type": "nulldata" - } - } - ], - "hex": "010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff4503851208fabe6d6d7bf60491521f081d77fa018fb41a167dd447bf20e7d2487426c3cee65332cdb50100000000000000266508019fcf7fcb7b01002ffd0c2f736c7573682f0000000002b02f9f4a000000001976a9147c154ed1dc59609e3d26abb2df2ea3d587cd8c4188ac0000000000000000266a24aa21a9ed2b367f88dbcc39b83e89703d5425a9b51fa3d2d921b8f39a42bc54492b9862810120000000000000000000000000000000000000000000000000000000000000000000000000", - "blockhash": "000000000000000000001542470d8261b9e5a2c3c2be2e2ab292d1a4c8250b12", - "confirmations": 3, - "time": 1529848136, - "blocktime": 1529848136 - } - ], - txInputsByTransaction: {} - }); - /*client.command('getblock', blockHash, function(errGetblock, resultGetblock, resHeadersGetblock) { - if (errGetblock) { - console.log("Error 3017hfwe0f: " + errGetblock); - - reject(errGetblock); - - return; - } - - var txids = []; - - // make sure we have the coinbase transaction since it can indicate - // "block" info that we might want to display (miner) - if (txOffset > 0) { - txids.push(resultGetblock.tx[0]); - } - - for (var i = txOffset; i < Math.min(txOffset + txLimit, resultGetblock.tx.length); i++) { - txids.push(resultGetblock.tx[i]); - } - - var maxInputsTracked = 10; - getRawTransactions(txids).then(function(transactions) { - var txInputsByTransaction = {}; - - // even if we're on "page 2" of transactions we pull the coinbase - // tx first so that we can store it - resultGetblock.coinbaseTx = transactions[0]; - resultGetblock.miner = getMinerFromCoinbaseTx(transactions[0]); - - // if we're on page 2, we don't really want it anymore... - if (txOffset > 0) { - transactions.shift(); - } - - var vinTxids = []; - var promises = []; - for (var i = 0; i < transactions.length; i++) { - var transaction = transactions[i]; - - if (transaction) { - //console.log("xyz: " + JSON.stringify(transaction.vin)); - - for (var j = 0; j < Math.min(maxInputsTracked, transaction.vin.length); j++) { - if (transaction.vin[j].txid) { - vinTxids.push(transaction.vin[j].txid); - } - } - } - } - - getRawTransactions(vinTxids).then(function(vinTransactions) { - var vinTxById = {}; - - vinTransactions.forEach(function(tx) { - vinTxById[tx.txid] = tx; - }); - - transactions.forEach(function(tx) { - txInputsByTransaction[tx.txid] = []; - - for (var i = 0; i < Math.min(maxInputsTracked, tx.vin.length); i++) { - if (vinTxById[tx.vin[i].txid]) { - txInputsByTransaction[tx.txid].push(vinTxById[tx.vin[i].txid]); - } - } - - resolve({ getblock:resultGetblock, transactions:transactions, txInputsByTransaction:txInputsByTransaction }); - }); - }); - }); - });*/ - }); -} - function getHelp() { return new Promise(function(resolve, reject) { reject("Not implemented"); diff --git a/app/api/rpcApi.js b/app/api/rpcApi.js index 3191bd5..9c31031 100644 --- a/app/api/rpcApi.js +++ b/app/api/rpcApi.js @@ -110,7 +110,7 @@ function getBlocksByHash(blockHashes) { getRawTransactions(coinbaseTxids).then(function(coinbaseTxs) { for (var i = 0; i < blocks.length; i++) { blocks[i].coinbaseTx = coinbaseTxs[i]; - blocks[i].miner = getMinerFromCoinbaseTx(coinbaseTxs[i]); + blocks[i].miner = utils.getMinerFromCoinbaseTx(coinbaseTxs[i]); } resolve(blocks); @@ -191,115 +191,6 @@ function getRawTransactions(txids) { }); } -function getMinerFromCoinbaseTx(tx) { - if (global.miningPoolsConfig) { - for (var payoutAddress in global.miningPoolsConfig.payout_addresses) { - if (global.miningPoolsConfig.payout_addresses.hasOwnProperty(payoutAddress)) { - if (tx.vout && tx.vout.length > 0 && tx.vout[0].scriptPubKey && tx.vout[0].scriptPubKey.addresses && tx.vout[0].scriptPubKey.addresses.length > 0) { - if (tx.vout[0].scriptPubKey.addresses[0] == payoutAddress) { - var minerInfo = global.miningPoolsConfig.payout_addresses[payoutAddress]; - minerInfo.identifiedBy = "payout address " + payoutAddress; - - return minerInfo; - } - } - } - } - - for (var coinbaseTag in global.miningPoolsConfig.coinbase_tags) { - if (global.miningPoolsConfig.coinbase_tags.hasOwnProperty(coinbaseTag)) { - if (utils.hex2ascii(tx.vin[0].coinbase).indexOf(coinbaseTag) != -1) { - var minerInfo = global.miningPoolsConfig.coinbase_tags[coinbaseTag]; - minerInfo.identifiedBy = "coinbase tag '" + coinbaseTag + "'"; - - return minerInfo; - } - } - } - } - - return null; -} - -function getBlockByHashWithTransactions(blockHash, txLimit, txOffset) { - console.log("getBlockByHashWithTransactions: " + blockHash); - - return new Promise(function(resolve, reject) { - client.command('getblock', blockHash, function(errGetblock, resultGetblock, resHeadersGetblock) { - if (errGetblock) { - console.log("Error 3017hfwe0f: " + errGetblock); - - reject(errGetblock); - - return; - } - - var txids = []; - - // make sure we have the coinbase transaction since it can indicate - // "block" info that we might want to display (miner) - if (txOffset > 0) { - txids.push(resultGetblock.tx[0]); - } - - for (var i = txOffset; i < Math.min(txOffset + txLimit, resultGetblock.tx.length); i++) { - txids.push(resultGetblock.tx[i]); - } - - var maxInputsTracked = 10; - getRawTransactions(txids).then(function(transactions) { - var txInputsByTransaction = {}; - - // even if we're on "page 2" of transactions we pull the coinbase - // tx first so that we can store it - resultGetblock.coinbaseTx = transactions[0]; - resultGetblock.miner = getMinerFromCoinbaseTx(transactions[0]); - - // if we're on page 2, we don't really want it anymore... - if (txOffset > 0) { - transactions.shift(); - } - - var vinTxids = []; - var promises = []; - for (var i = 0; i < transactions.length; i++) { - var transaction = transactions[i]; - - if (transaction) { - //console.log("xyz: " + JSON.stringify(transaction.vin)); - - for (var j = 0; j < Math.min(maxInputsTracked, transaction.vin.length); j++) { - if (transaction.vin[j].txid) { - vinTxids.push(transaction.vin[j].txid); - } - } - } - } - - getRawTransactions(vinTxids).then(function(vinTransactions) { - var vinTxById = {}; - - vinTransactions.forEach(function(tx) { - vinTxById[tx.txid] = tx; - }); - - transactions.forEach(function(tx) { - txInputsByTransaction[tx.txid] = []; - - for (var i = 0; i < Math.min(maxInputsTracked, tx.vin.length); i++) { - if (vinTxById[tx.vin[i].txid]) { - txInputsByTransaction[tx.txid].push(vinTxById[tx.vin[i].txid]); - } - } - - resolve({ getblock:resultGetblock, transactions:transactions, txInputsByTransaction:txInputsByTransaction }); - }); - }); - }); - }); - }); -} - function getHelp() { return new Promise(function(resolve, reject) { client.command('help', function(err, result, resHeaders) { diff --git a/app/utils.js b/app/utils.js index 0b83d3e..24c745c 100644 --- a/app/utils.js +++ b/app/utils.js @@ -149,6 +149,40 @@ function seededRandomIntBetween(seed, min, max) { return (min + (max - min) * rand); } +function getMinerFromCoinbaseTx(tx) { + if (tx == null) { + return null; + } + + if (global.miningPoolsConfig) { + for (var payoutAddress in global.miningPoolsConfig.payout_addresses) { + if (global.miningPoolsConfig.payout_addresses.hasOwnProperty(payoutAddress)) { + if (tx.vout && tx.vout.length > 0 && tx.vout[0].scriptPubKey && tx.vout[0].scriptPubKey.addresses && tx.vout[0].scriptPubKey.addresses.length > 0) { + if (tx.vout[0].scriptPubKey.addresses[0] == payoutAddress) { + var minerInfo = global.miningPoolsConfig.payout_addresses[payoutAddress]; + minerInfo.identifiedBy = "payout address " + payoutAddress; + + return minerInfo; + } + } + } + } + + for (var coinbaseTag in global.miningPoolsConfig.coinbase_tags) { + if (global.miningPoolsConfig.coinbase_tags.hasOwnProperty(coinbaseTag)) { + if (hex2ascii(tx.vin[0].coinbase).indexOf(coinbaseTag) != -1) { + var minerInfo = global.miningPoolsConfig.coinbase_tags[coinbaseTag]; + minerInfo.identifiedBy = "coinbase tag '" + coinbaseTag + "'"; + + return minerInfo; + } + } + } + } + + return null; +} + module.exports = { redirectToConnectPageIfNeeded: redirectToConnectPageIfNeeded, @@ -161,5 +195,6 @@ module.exports = { addThousandsSeparators: addThousandsSeparators, formatCurrencyAmountInSmallestUnits: formatCurrencyAmountInSmallestUnits, seededRandom: seededRandom, - seededRandomIntBetween: seededRandomIntBetween + seededRandomIntBetween: seededRandomIntBetween, + getMinerFromCoinbaseTx: getMinerFromCoinbaseTx };