diff --git a/lib/services/address/index.js b/lib/services/address/index.js index f928139b..6d3c63f8 100644 --- a/lib/services/address/index.js +++ b/lib/services/address/index.js @@ -11,6 +11,7 @@ var _ = bitcore.deps._; var Encoding = require('./encoding'); var Transform = require('stream').Transform; var assert = require('assert'); +var Stream = require('stream'); var AddressService = function(options) { @@ -69,7 +70,7 @@ AddressService.prototype.getAddressHistory = function(addresses, options, callba return callback(err); } - txLists = _.flattenDeep(txLists); + txLists = _.compact(_.flattenDeep(txLists)); var txList = []; for(var i = 0; i < txLists.length; i++) { @@ -317,6 +318,8 @@ AddressService.prototype._getTxidStream = function(address, options) { txidStream.on('close', function() { txidStream.unpipe(); }); + + return txidStream; }; AddressService.prototype._transformTxForAddressHistory = function(opts, chunk, enc, callback) { @@ -338,33 +341,8 @@ AddressService.prototype._transformTxForAddressHistory = function(opts, chunk, e return callback(); } - assert(tx.__height >- 0, 'tx must have a height'); - self._header.getBlockHeader(tx.__height, function(err, hash) { - - if(err) { - log.error('Address Service: getblockheader ' + err); - opts.stream.emit('error', err); - return callback(); - } - - tx.__blockhash = hash; - - var outputSatoshis = 0; - tx.outputs.forEach(function(output) { - outputSatoshis += output.value; - }); - - var inputSatoshis = 0; - tx.__inputValues.forEach(function(value) { - inputSatoshis += value; - }); - - tx.__outputSatoshis = outputSatoshis; - tx.__inputSatoshis = inputSatoshis; - opts.results.push(tx); - callback(); - - }); + opts.results.push(tx); + callback(); }); @@ -376,11 +354,6 @@ AddressService.prototype._getTxStream = function(address, options) { options.stream = txStream; - txStream.on('error', function(err) { - log.error('Address Service: txstream err: ' + err); - txStream.unpipe(); - }); - txStream._flush = function(callback) { txStream.emit('end'); callback(); @@ -388,6 +361,8 @@ AddressService.prototype._getTxStream = function(address, options) { txStream._transform = this._transformTxForAddressHistory.bind(this, options); + return txStream; + }; AddressService.prototype._getAddressHistory = function(address, options, callback) { @@ -415,24 +390,34 @@ AddressService.prototype._getAddressHistory = function(address, options, callbac return next(); } - self._mempool.getTxsByAddress(address, next); + self._mempool.getTxidsByAddress(address, next); }, // stream the rest of the confirmed txids out of the address index - function(mempoolTxs, next) { - - if (mempoolTxs.length > 0) { - options.results = options.results.concat(mempoolTxs); - } + function(mempoolTxids, next) { var txStream = self._getTxStream(address, options); + txStream.on('end', function() { - return callback(null, options.results); + return next(null, options.results); }); + txStream.on('error', function(err) { + log.error('Address Service: txstream err: ' + err); + txStream.unpipe(); + }); + + if (mempoolTxids.length > 0) { + var mempoolxidStream = new Stream.Readable({ objectMode: true }); + mempoolxidStream.pipe(txStream); + mempoolTxids.forEach(function(txid) { + mempoolxidStream.push(txid); + }); + mempoolxidStream.unpipe(); + } + var txidStream = self._getTxidStream(address, options); txidStream.pipe(txStream); - next(); } ], callback); diff --git a/lib/services/mempool/index.js b/lib/services/mempool/index.js index 3188405a..49adac35 100644 --- a/lib/services/mempool/index.js +++ b/lib/services/mempool/index.js @@ -138,7 +138,7 @@ MempoolService.prototype.getMempoolTransaction = function(txid, callback) { }; // TODO optimize this using another index? -MempoolService.prototype.getTxsByAddress = function(address, callback) { +MempoolService.prototype.getTxidsByAddress = function(address, callback) { var self = this; var results = []; @@ -162,9 +162,9 @@ MempoolService.prototype.getTxsByAddress = function(address, callback) { stream.on('data', function(data) { var tx = self._encoding.decodeMempoolTransactionValue(data.value); - tx = self._involvesAddress(tx, address); + var txid = self._involvesAddress(tx, address); if (tx) { - results.push(tx); + results.push(txid); } }); @@ -193,7 +193,7 @@ MempoolService.prototype._involvesAddress = function(tx, address) { for(var i = 0; i < collections.length; i++) { var hasAddress = contains(collections[i], this._network); if (hasAddress) { - return tx; + return tx.txid(); } } diff --git a/lib/services/transaction/index.js b/lib/services/transaction/index.js index 4173e5f8..8d6e4b23 100644 --- a/lib/services/transaction/index.js +++ b/lib/services/transaction/index.js @@ -67,6 +67,7 @@ TransactionService.prototype._getDoubleSpentTxID = function(tx, 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) { @@ -86,7 +87,7 @@ TransactionService.prototype._getSpentInformationForOutputs = function(tx, callb self._address._getInputInfoForAddress(address, next); - }, function(err, inputGroups) { + }, function(err) { if(err) { return callback(err); @@ -96,7 +97,7 @@ TransactionService.prototype._getSpentInformationForOutputs = function(tx, callb // 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(); @@ -105,56 +106,7 @@ TransactionService.prototype._getSpentInformationForOutputs = function(tx, callb }; -TransactionService.prototype.getDetailedTransaction = function(txid, options, callback) { - - var self = this; - - self.getTransaction(txid, options, function(err, tx) { - - if(err) { - return callback(err); - } - - if (!tx) { - return callback(); - } - - // add in the following: - // 1. double spend tx id - // 2. is confirmed - // 3. for every input: is input confirmed - // 4. for every output: spent tx id (some future tx) - // 5. for every output: spent tx index - // 6. for every output: spent tx height - - // is confirmed: does this tx appear in at least one block - tx.isConfirmed = tx.confirmations > 0; - - async.parallel([ - function(next) { - // double spend tx: did another tx in our mempool attempt to spend ANY of the same outputs that our inputs are trying to spend? - self._getDoubleSpentTxID(tx, next); - }, - // is input confirmed: on every input, place a field for whether or not the input's output is confirmed - function(next) { - self._getConfirmationsForInputs(tx, next); - }, - // get spent inforamtion for outputs - function(next) { - self._getSpentInformationForOutputs(tx, next); - } - ], function(err) { - - if(err) { - return callback(err); - } - - callback(null, tx); - }); - }); - -}; - +TransactionService.prototype.getDetailedTransaction = TransactionService.prototype.getTransaction = function(txid, options, callback) { var self = this; diff --git a/test/services/address/index.unit.js b/test/services/address/index.unit.js index f06dd9f7..d013f7ed 100644 --- a/test/services/address/index.unit.js +++ b/test/services/address/index.unit.js @@ -56,7 +56,7 @@ describe('Address Service', function() { it('should get the address history', function(done) { - sandbox.stub(addressService, '_getAddressHistory').callsArgWith(2, null, {}); + sandbox.stub(addressService, '_getAddressHistory').callsArgWith(2, null, null); addressService.getAddressHistory(['a', 'b', 'c'], { from: 12, to: 14 }, function(err, res) { if (err) { @@ -64,8 +64,8 @@ describe('Address Service', function() { } expect(res).to.be.deep.equal({ - totalCount: 3, - items: [ {}, {}, {} ] + totalCount: 0, + items: [] }); done(); @@ -81,6 +81,8 @@ describe('Address Service', function() { var getHeaderHash = sandbox.stub().callsArgWith(1, null, 'aa'); var getBlockHeader = sandbox.stub().callsArgWith(1, null, 'aa'); + var getTxidsByAddress = sandbox.stub().callsArgWith(1, null, []); + addressService._mempool = { getTxidsByAddress: getTxidsByAddress }; addressService._header = { getHeaderHash: getHeaderHash, @@ -106,16 +108,14 @@ describe('Address Service', function() { if (err) { return done(err); } + expect(getTxidsByAddress.calledOnce).to.be.true; expect(getTransaction.calledOnce).to.be.true; expect(res).to.deep.equal([ { - __blockhash: 'aa', __height: 123, - __inputSatoshis: 1, __inputValues: [ 1 ], - __outputSatoshis: 1, outputs: [ { value: 1 diff --git a/test/services/block/index.unit.js b/test/services/block/index.unit.js index ef44c2d4..8750b61c 100644 --- a/test/services/block/index.unit.js +++ b/test/services/block/index.unit.js @@ -161,6 +161,7 @@ describe('Block Service', function() { var setTip = sandbox.stub(blockService, '_setTip').callsArgWith(1, null); blockService.node = { openBus: sandbox.stub() }; blockService._db = { getPrefix: getPrefix, getServiceTip: getServiceTip }; + blockService._header = { on: sinon.stub() }; blockService.start(function() { expect(blockService._encoding).to.be.an.instanceof(Encoding); expect(getServiceTip.calledOnce).to.be.true; diff --git a/test/services/transaction/index.unit.js b/test/services/transaction/index.unit.js index 86aa1a80..e7dbd9ab 100644 --- a/test/services/transaction/index.unit.js +++ b/test/services/transaction/index.unit.js @@ -46,19 +46,6 @@ describe('Transaction Service', function() { }); }); - describe('#sendTransaction', function() { - it('should send a raw transaction', function(done) { - var sendTransaction = sandbox.stub().callsArg(0); - txService._p2p = { sendTransaction: sendTransaction }; - txService.sendTransaction(function(err) { - if (err) { - return done(err); - } - done(); - }); - }); - }); - describe('#_getBlockTimestamp', function() { it('should get the block\'s timestamp', function() { var getTimestamp = sandbox.stub().returns(1);