diff --git a/addresses.txt b/addresses.txt new file mode 100644 index 00000000..174cedb9 --- /dev/null +++ b/addresses.txt @@ -0,0 +1 @@ +mtLDA41NWe9rLm7nuMvAnTs2SbP49cz1ZR diff --git a/lib/services/address/index.js b/lib/services/address/index.js index c628a529..94369bf1 100644 --- a/lib/services/address/index.js +++ b/lib/services/address/index.js @@ -16,7 +16,6 @@ var utils = require('../../utils'); var AddressService = function(options) { BaseService.call(this, options); - this._tx = this.node.services.transaction; this._header = this.node.services.header; this._block = this.node.services.block; this._timestamp = this.node.services.timestamp; @@ -32,7 +31,6 @@ var AddressService = function(options) { this._network = 'testnet'; } - }; inherits(AddressService, BaseService); @@ -46,8 +44,80 @@ AddressService.dependencies = [ 'mempool' ]; -// ---- public function prototypes +AddressService.prototype._applySpendingTxsToOutputs = function(tx, options, callback) { + + var self = this; + + async.eachOfLimit(tx.outputs, 4, function(output, index, next) { + + var address = utils.getAddress(output, self._network); + + if (!address || !tx.__height) { + return next(); + } + + self.getAddressHistory(address, { start: tx.__height }, function(err, history) { + + if (err) { + return next(err); + } + + // there should be zero or one tx count, if there are more, then this output was double spent + if (history.totalCount === 1) { + var spentTx = history.items[0]; + + tx.outputs[index].spentTxId = spentTx.txid(); + + for(var i = 0; i < spentTx.inputs.length; i++) { + var input = spentTx.inputs[i]; + if (input.prevout.txid() === tx.txid()) { + output.spentIndex = i; + } + } + + assert(output.spentIndex >= 0, 'Transaction Service: found spending tx, but could not find index.'); + + output.spentHeight = tx.__height || 0; + } + next(); + + }); + + }, function(err) { + + if (err) { + return callback(err); + } + +console.log(tx.outputs[0].spentTxId); + callback(null, tx); + + }); + +}; + +AddressService.prototype.getTransactionWithAddressInfo = function(txid, options, callback) { + + var self = this; + self._transaction.getTransaction(txid, options, function(err, tx) { + + if (err) { + return callback(err); + } + + if (!tx) { + return callback(); + } + + // locate any tx that spent this tx's outputs + self._applySpendingTxsToOutputs(tx, options, callback); + + }); + +}; + AddressService.prototype.getAddressHistory = function(addresses, options, callback) { + var self = this; options = options || {}; @@ -73,7 +143,7 @@ AddressService.prototype.getAddressHistory = function(addresses, options, callba } // TODO: these should already be ordered correctly, please check - txList = utils.dedupByTxid(txList); + txList = utils.dedupByTxid(txList); txList = utils.orderByConfirmations(txList); var results = { @@ -369,7 +439,7 @@ AddressService.prototype._transformTxForAddressHistory = function(opts, chunk, e return callback(); } - self._tx.getTransaction(txid, opts, function(err, tx) { + self._transaction.getTransaction(txid, opts, function(err, tx) { if (err) { log.error('Address Service: gettransaction ' + err); diff --git a/lib/services/transaction/index.js b/lib/services/transaction/index.js index a6ef3551..a72a4c5a 100644 --- a/lib/services/transaction/index.js +++ b/lib/services/transaction/index.js @@ -51,64 +51,6 @@ TransactionService.prototype.getAPIMethods = function() { ]; }; -TransactionService.prototype._getDoubleSpentTxID = function(tx, callback) { - // for there to be a tx in our mempool that is double spending this tx, - // then at least one other tx in the mempool must be spending at least one of the - // outputs that this tx is spending - - // TODO - // we don't index the mempool to easily handle this because we would have to exhaustively - // search through all of the mempool txs - - // we should probably have an index whose key is prevtxid + output index + spendingtxid and no value - // then we could quickly loop over all inputs and get their spending txids in a list. - // then subtract the list and this will be your double spending txids. - - // when a new block comes in, it may confirm up to one of those tx's. It should be very easily to - // delete the correct one because we have the block and the tx. - return callback(); - -}; - -TransactionService.prototype._getConfirmationsForInputs = function(tx, callback) { - // for every input, check to see if its referenced input is confirmed. - return callback(); -}; - -TransactionService.prototype._getSpentInformationForOutputs = function(tx, callback) { - - var self = this; - - async.mapLimit(tx.outputs, 4, function(output, next) { - - var address = output.getAddress(); - - if (!address) { - return next(); - } - - address.network = self._network; - address = address.toString(); - - self._address._getInputInfoForAddress(address, next); - - }, function(err) { - - if(err) { - return callback(err); - } - - // we have an array for every output representing all the input info for the address - // we need to take each txid in the input info and get the tx but only if the height is greater this - // tx's height - - callback(); - - }); - -}; - -TransactionService.prototype.getDetailedTransaction = TransactionService.prototype.getTransaction = function(txid, options, callback) { var self = this;