diff --git a/app/api/coreApi.js b/app/api/coreApi.js index 67233f1..a1bbc47 100644 --- a/app/api/coreApi.js +++ b/app/api/coreApi.js @@ -588,7 +588,13 @@ function getBlocksByHash(blockHashes) { } Promise.all(promises).then(function(results) { - resolve(results); + var result = {}; + + results.forEach(function(item) { + result[item.hash] = item; + }); + + resolve(result); }).catch(function(err) { reject(err); @@ -876,6 +882,7 @@ module.exports = { getBlockByHeight: getBlockByHeight, getBlocksByHeight: getBlocksByHeight, getBlockByHash: getBlockByHash, + getBlocksByHash: getBlocksByHash, getBlockByHashWithTransactions: getBlockByHashWithTransactions, getRawTransaction: getRawTransaction, getRawTransactions: getRawTransactions, diff --git a/routes/baseActionsRouter.js b/routes/baseActionsRouter.js index 67c030e..2003c78 100644 --- a/routes/baseActionsRouter.js +++ b/routes/baseActionsRouter.js @@ -664,58 +664,112 @@ router.get("/address/:address", function(req, res, next) { if (addressDetails.txids) { var txids = addressDetails.txids; + + // if the active addressApi gives us blockHeightsByTxid, it saves us work, so try to use it var blockHeightsByTxid = {}; + if (addressDetails.blockHeightsByTxid) { + blockHeightsByTxid = addressDetails.blockHeightsByTxid; + } res.locals.txids = txids; coreApi.getRawTransactionsWithInputs(txids).then(function(rawTxResult) { res.locals.transactions = rawTxResult.transactions; res.locals.txInputsByTransaction = rawTxResult.txInputsByTransaction; - - var addrGainsByTx = {}; - var addrLossesByTx = {}; - - res.locals.addrGainsByTx = addrGainsByTx; - res.locals.addrLossesByTx = addrLossesByTx; + // for coinbase txs, we need the block height in order to calculate subsidy to display + var coinbaseTxs = []; for (var i = 0; i < rawTxResult.transactions.length; i++) { var tx = rawTxResult.transactions[i]; - var txInputs = rawTxResult.txInputsByTransaction[tx.txid]; - blockHeightsByTxid[tx.txid] = tx.height; - - for (var j = 0; j < tx.vout.length; j++) { - if (tx.vout[j].value > 0 && tx.vout[j].scriptPubKey && tx.vout[j].scriptPubKey.addresses && tx.vout[j].scriptPubKey.addresses.includes(address)) { - if (addrGainsByTx[tx.txid] == null) { - addrGainsByTx[tx.txid] = new Decimal(0); + for (var j = 0; j < tx.vin.length; j++) { + if (tx.vin[j].coinbase) { + // addressApi sometimes has blockHeightByTxid already available, otherwise we need to query for it + if (!blockHeightsByTxid[tx.txid]) { + coinbaseTxs.push(tx); } - - addrGainsByTx[tx.txid] = addrGainsByTx[tx.txid].plus(new Decimal(tx.vout[j].value)); } } + } - for (var j = 0; j < tx.vin.length; j++) { - var txInput = txInputs[j]; - var vinJ = tx.vin[j]; - if (txInput != null) { - if (txInput.vout[vinJ.vout] && txInput.vout[vinJ.vout].scriptPubKey && txInput.vout[vinJ.vout].scriptPubKey.addresses && txInput.vout[vinJ.vout].scriptPubKey.addresses.includes(address)) { - if (addrLossesByTx[tx.txid] == null) { - addrLossesByTx[tx.txid] = new Decimal(0); + var coinbaseTxBlockHashes = []; + var blockHashesByTxid = {}; + coinbaseTxs.forEach(function(tx) { + coinbaseTxBlockHashes.push(tx.blockhash); + blockHashesByTxid[tx.txid] = tx.blockhash; + }); + + var blockHeightsPromises = []; + if (coinbaseTxs.length > 0) { + // we need to query some blockHeights by hash for some coinbase txs + blockHeightsPromises.push(new Promise(function(resolve2, reject2) { + coreApi.getBlocksByHash(coinbaseTxBlockHashes).then(function(blocksByHashResult) { + for (var txid in blockHashesByTxid) { + if (blockHashesByTxid.hasOwnProperty(txid)) { + blockHeightsByTxid[txid] = blocksByHashResult[blockHashesByTxid[txid]].height; + } + } + + resolve2(); + + }).catch(function(err) { + utils.logError("78ewrgwetg3", err); + + reject2(err); + }); + })); + } + + Promise.all(blockHeightsPromises).then(function() { + var addrGainsByTx = {}; + var addrLossesByTx = {}; + + res.locals.addrGainsByTx = addrGainsByTx; + res.locals.addrLossesByTx = addrLossesByTx; + + for (var i = 0; i < rawTxResult.transactions.length; i++) { + var tx = rawTxResult.transactions[i]; + var txInputs = rawTxResult.txInputsByTransaction[tx.txid]; + + for (var j = 0; j < tx.vout.length; j++) { + if (tx.vout[j].value > 0 && tx.vout[j].scriptPubKey && tx.vout[j].scriptPubKey.addresses && tx.vout[j].scriptPubKey.addresses.includes(address)) { + if (addrGainsByTx[tx.txid] == null) { + addrGainsByTx[tx.txid] = new Decimal(0); } - addrLossesByTx[tx.txid] = addrLossesByTx[tx.txid].plus(new Decimal(txInput.vout[vinJ.vout].value)); + addrGainsByTx[tx.txid] = addrGainsByTx[tx.txid].plus(new Decimal(tx.vout[j].value)); + } + } + + for (var j = 0; j < tx.vin.length; j++) { + var txInput = txInputs[j]; + var vinJ = tx.vin[j]; + + if (txInput != null) { + if (txInput.vout[vinJ.vout] && txInput.vout[vinJ.vout].scriptPubKey && txInput.vout[vinJ.vout].scriptPubKey.addresses && txInput.vout[vinJ.vout].scriptPubKey.addresses.includes(address)) { + if (addrLossesByTx[tx.txid] == null) { + addrLossesByTx[tx.txid] = new Decimal(0); + } + + addrLossesByTx[tx.txid] = addrLossesByTx[tx.txid].plus(new Decimal(txInput.vout[vinJ.vout].value)); + } } } + + //debugLog("tx: " + JSON.stringify(tx)); + //debugLog("txInputs: " + JSON.stringify(txInputs)); } - //debugLog("tx: " + JSON.stringify(tx)); - //debugLog("txInputs: " + JSON.stringify(txInputs)); - } + res.locals.blockHeightsByTxid = blockHeightsByTxid; + + resolve(); - res.locals.blockHeightsByTxid = blockHeightsByTxid; + }).catch(function(err) { + utils.logError("230wefrhg0egt3", err); - resolve(); + reject(err); + }); }).catch(function(err) { utils.logError("asdgf07uh23", err);