From 599d1166cfe71d3dc81e02faae7b11c4df3a8f89 Mon Sep 17 00:00:00 2001 From: eordano Date: Thu, 19 Mar 2015 15:13:23 -0300 Subject: [PATCH] Add heightConfirmed for outputs --- lib/services/address.js | 21 +++++++++++++--- lib/services/block.js | 4 ++- lib/services/transaction.js | 49 ++++++++++++++++++------------------- 3 files changed, 45 insertions(+), 29 deletions(-) diff --git a/lib/services/address.js b/lib/services/address.js index a6248949..2f2bae40 100644 --- a/lib/services/address.js +++ b/lib/services/address.js @@ -44,6 +44,16 @@ AddressService.prototype.getSummary = function(address, confirmations) { }); }; +AddressService.processOutput = function(data) { + var elements = data.key.split('-'); + var output = _.extend(JSON.parse(data.value), { + address: elements[1], + txId: elements[2], + outputIndex: elements[3] + }); + return output; +}; + AddressService.prototype.getAllOutputs = function(address) { var results = []; var self = this; @@ -53,7 +63,7 @@ AddressService.prototype.getAllOutputs = function(address) { gte: TransactionService.Index.getOutputsForAddress(address, NULLTXHASH, 0), lte: TransactionService.Index.getOutputsForAddress(address, LASTTXHASH, MAXOUTPUT) }).on('data', function(element) { - results.push(element.value); + results.push(AddressService.processOutput(element)); }).on('close', function() { reject(); }).on('end', function() { @@ -71,7 +81,7 @@ AddressService.prototype.getSpent = function(address) { gte: TransactionService.Index.getSpentOutputsForAddress(address, NULLTXHASH, 0), lte: TransactionService.Index.getSpentOutputsForAddress(address, LASTTXHASH, MAXOUTPUT) }).on('data', function(element) { - results.push(element.value); + results.push(JSON.parse(element.value)); }).on('error', function(err) { return reject(err); }).on('end', function() { @@ -98,8 +108,12 @@ AddressService.prototype.buildAddressSummary = function(address, tip, allOutputs sent: 0, received: 0 }; + + var outputValues = {}; + _.each(allOutputs, function(output) { var value = output.satoshis; + outputValues[output.txId + '-' + output.outputIndex] = value; result.unconfirmed.balance += value; result.unconfirmed.received += value; if (tip.height - output.heightConfirmed - 1 >= confirmations) { @@ -108,7 +122,8 @@ AddressService.prototype.buildAddressSummary = function(address, tip, allOutputs } }); _.each(spent, function(output) { - var value = output.satoshis; + var value = outputValues[output.spendInput.prevTxId + '-' + output.spendInput.outputIndex]; + if (!transactionsAppended[output.spentTx]) { transactionsAppended[output.spentTx] = true; result.transactions.push(output.spentTx); diff --git a/lib/services/block.js b/lib/services/block.js index 2721e449..5ea2155a 100644 --- a/lib/services/block.js +++ b/lib/services/block.js @@ -97,7 +97,7 @@ BlockService.blockRPCtoBitcore = function(blockData, transactions) { $.checkArgument(_.all(transactions, function(transaction) { return transaction instanceof bitcore.Transaction; }), 'All transactions must be instances of bitcore.Transaction'); - return new bitcore.Block({ + var block = new bitcore.Block({ header: new bitcore.BlockHeader({ version: blockData.version, prevHash: blockData.previousblockhash ? @@ -115,6 +115,8 @@ BlockService.blockRPCtoBitcore = function(blockData, transactions) { }), transactions: transactions }); + block.height = blockData.height; + return block; }; /** diff --git a/lib/services/transaction.js b/lib/services/transaction.js index 8298a635..99f2ce7d 100644 --- a/lib/services/transaction.js +++ b/lib/services/transaction.js @@ -110,7 +110,7 @@ TransactionService.prototype._confirmOutput = function(ops, block, transaction) ops.push({ type: 'put', key: Index.getOutput(transaction.id, index), - value: output.toObject() + value: output.toJSON() }); var address; // TODO: Move this logic to bitcore @@ -124,7 +124,9 @@ TransactionService.prototype._confirmOutput = function(ops, block, transaction) ops.push({ type: 'put', key: Index.getOutputsForAddress(address, transaction.id, index), - value: output.toObject() + value: JSON.stringify(_.extend(output.toObject(), { + heightConfirmed: block.height + })) }); } }; @@ -139,13 +141,13 @@ TransactionService.prototype._confirmInput = function(ops, block, transaction) { ops.push({ type: 'put', key: Index.getOutput(transaction.id, index), - value: _.extend(input.toObject(), { + value: JSON.stringify(_.extend(input.toObject(), { heightConfirmed: block.height - }) + })) }); var script = input.script; if (!(script.isPublicKeyHashIn() || script.isPublicKeyIn() || script.isScriptHashIn())) { - return Promise.resolve(); + return; } return self._getAddressForInput(input).then(function(address) { @@ -153,12 +155,12 @@ TransactionService.prototype._confirmInput = function(ops, block, transaction) { ops.push({ type: 'put', key: Index.getSpentOutputsForAddress(address, transaction.id, index), - value: { + value: JSON.stringify({ heightSpent: block.height, spentTx: transaction.id, spentTxInputIndex: index, spendInput: input.toObject() - } + }) }); } }); @@ -171,40 +173,37 @@ TransactionService.prototype._getAddressForInput = function(input) { if (script.isPublicKeyHashIn()) { var hash = bitcore.crypto.Hash.sha256ripemd160(script.chunks[0].buf); - return Promise.resolve(new bitcore.Address( + return new bitcore.Address( hash, bitcore.Networks.defaultNetwork, bitcore.Address.PayToPublicKeyHash - )); + ); } else if (script.isPublicKeyIn()) { return self.getTransaction(input.prevTxId.toString('hex')).then(function(transaction) { var outputScript = transaction.outputs[input.outputIndex].script; if (outputScript.isPublicKeyOut()) { - return Promise.resolve(new bitcore.Address( + return new bitcore.Address( bitcore.crypto.Hash.sha256ripemd160(outputScript.chunks[0].buf), bitcore.Networks.defaultNetwork, bitcore.Address.PayToPublicKeyHash - )); - } else { - return Promise.resolve(undefined); + ); } + return; }); } else { - return Promise.resolve(new bitcore.Script(script.chunks[script.chunks.length - 1]).toAddress()); + return new bitcore.Script(script.chunks[script.chunks.length - 1]).toAddress(); } }; TransactionService.prototype._confirmTransaction = function(ops, block, transaction) { var self = this; - return Promise.try(function() { - ops.push({ - type: 'put', - key: Index.getBlockForTransaction(transaction), - value: block.id - }); - return Promise.all( - _.each(transaction.outputs, self._confirmOutput(ops, block, transaction)) - .concat( - _.each(transaction.inputs, self._confirmInput(ops, block, transaction)) - )); + ops.push({ + type: 'put', + key: Index.getBlockForTransaction(transaction), + value: block.id }); + return Promise.all( + _.map(transaction.outputs, self._confirmOutput(ops, block, transaction)) + .concat( + _.map(transaction.inputs, self._confirmInput(ops, block, transaction)) + )); }; module.exports = TransactionService;