Fixed tests.
This commit is contained in:
parent
7c392e9c94
commit
d7fb9e9c27
@ -11,6 +11,7 @@ var _ = bitcore.deps._;
|
|||||||
var Encoding = require('./encoding');
|
var Encoding = require('./encoding');
|
||||||
var Transform = require('stream').Transform;
|
var Transform = require('stream').Transform;
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
|
var Stream = require('stream');
|
||||||
|
|
||||||
var AddressService = function(options) {
|
var AddressService = function(options) {
|
||||||
|
|
||||||
@ -69,7 +70,7 @@ AddressService.prototype.getAddressHistory = function(addresses, options, callba
|
|||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
txLists = _.flattenDeep(txLists);
|
txLists = _.compact(_.flattenDeep(txLists));
|
||||||
var txList = [];
|
var txList = [];
|
||||||
|
|
||||||
for(var i = 0; i < txLists.length; i++) {
|
for(var i = 0; i < txLists.length; i++) {
|
||||||
@ -317,6 +318,8 @@ AddressService.prototype._getTxidStream = function(address, options) {
|
|||||||
txidStream.on('close', function() {
|
txidStream.on('close', function() {
|
||||||
txidStream.unpipe();
|
txidStream.unpipe();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return txidStream;
|
||||||
};
|
};
|
||||||
|
|
||||||
AddressService.prototype._transformTxForAddressHistory = function(opts, chunk, enc, callback) {
|
AddressService.prototype._transformTxForAddressHistory = function(opts, chunk, enc, callback) {
|
||||||
@ -338,33 +341,8 @@ AddressService.prototype._transformTxForAddressHistory = function(opts, chunk, e
|
|||||||
return callback();
|
return callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(tx.__height >- 0, 'tx must have a height');
|
opts.results.push(tx);
|
||||||
self._header.getBlockHeader(tx.__height, function(err, hash) {
|
callback();
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -376,11 +354,6 @@ AddressService.prototype._getTxStream = function(address, options) {
|
|||||||
|
|
||||||
options.stream = txStream;
|
options.stream = txStream;
|
||||||
|
|
||||||
txStream.on('error', function(err) {
|
|
||||||
log.error('Address Service: txstream err: ' + err);
|
|
||||||
txStream.unpipe();
|
|
||||||
});
|
|
||||||
|
|
||||||
txStream._flush = function(callback) {
|
txStream._flush = function(callback) {
|
||||||
txStream.emit('end');
|
txStream.emit('end');
|
||||||
callback();
|
callback();
|
||||||
@ -388,6 +361,8 @@ AddressService.prototype._getTxStream = function(address, options) {
|
|||||||
|
|
||||||
txStream._transform = this._transformTxForAddressHistory.bind(this, options);
|
txStream._transform = this._transformTxForAddressHistory.bind(this, options);
|
||||||
|
|
||||||
|
return txStream;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
AddressService.prototype._getAddressHistory = function(address, options, callback) {
|
AddressService.prototype._getAddressHistory = function(address, options, callback) {
|
||||||
@ -415,24 +390,34 @@ AddressService.prototype._getAddressHistory = function(address, options, callbac
|
|||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
||||||
self._mempool.getTxsByAddress(address, next);
|
self._mempool.getTxidsByAddress(address, next);
|
||||||
},
|
},
|
||||||
|
|
||||||
// stream the rest of the confirmed txids out of the address index
|
// stream the rest of the confirmed txids out of the address index
|
||||||
function(mempoolTxs, next) {
|
function(mempoolTxids, next) {
|
||||||
|
|
||||||
if (mempoolTxs.length > 0) {
|
|
||||||
options.results = options.results.concat(mempoolTxs);
|
|
||||||
}
|
|
||||||
|
|
||||||
var txStream = self._getTxStream(address, options);
|
var txStream = self._getTxStream(address, options);
|
||||||
|
|
||||||
txStream.on('end', function() {
|
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);
|
var txidStream = self._getTxidStream(address, options);
|
||||||
txidStream.pipe(txStream);
|
txidStream.pipe(txStream);
|
||||||
next();
|
|
||||||
}
|
}
|
||||||
], callback);
|
], callback);
|
||||||
|
|
||||||
|
|||||||
@ -138,7 +138,7 @@ MempoolService.prototype.getMempoolTransaction = function(txid, callback) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// TODO optimize this using another index?
|
// TODO optimize this using another index?
|
||||||
MempoolService.prototype.getTxsByAddress = function(address, callback) {
|
MempoolService.prototype.getTxidsByAddress = function(address, callback) {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
var results = [];
|
var results = [];
|
||||||
@ -162,9 +162,9 @@ MempoolService.prototype.getTxsByAddress = function(address, callback) {
|
|||||||
|
|
||||||
stream.on('data', function(data) {
|
stream.on('data', function(data) {
|
||||||
var tx = self._encoding.decodeMempoolTransactionValue(data.value);
|
var tx = self._encoding.decodeMempoolTransactionValue(data.value);
|
||||||
tx = self._involvesAddress(tx, address);
|
var txid = self._involvesAddress(tx, address);
|
||||||
if (tx) {
|
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++) {
|
for(var i = 0; i < collections.length; i++) {
|
||||||
var hasAddress = contains(collections[i], this._network);
|
var hasAddress = contains(collections[i], this._network);
|
||||||
if (hasAddress) {
|
if (hasAddress) {
|
||||||
return tx;
|
return tx.txid();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -67,6 +67,7 @@ TransactionService.prototype._getDoubleSpentTxID = function(tx, callback) {
|
|||||||
|
|
||||||
TransactionService.prototype._getConfirmationsForInputs = function(tx, callback) {
|
TransactionService.prototype._getConfirmationsForInputs = function(tx, callback) {
|
||||||
// for every input, check to see if its referenced input is confirmed.
|
// for every input, check to see if its referenced input is confirmed.
|
||||||
|
return callback();
|
||||||
};
|
};
|
||||||
|
|
||||||
TransactionService.prototype._getSpentInformationForOutputs = function(tx, callback) {
|
TransactionService.prototype._getSpentInformationForOutputs = function(tx, callback) {
|
||||||
@ -86,7 +87,7 @@ TransactionService.prototype._getSpentInformationForOutputs = function(tx, callb
|
|||||||
|
|
||||||
self._address._getInputInfoForAddress(address, next);
|
self._address._getInputInfoForAddress(address, next);
|
||||||
|
|
||||||
}, function(err, inputGroups) {
|
}, function(err) {
|
||||||
|
|
||||||
if(err) {
|
if(err) {
|
||||||
return callback(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
|
// 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
|
// tx's height
|
||||||
|
|
||||||
|
callback();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -105,56 +106,7 @@ TransactionService.prototype._getSpentInformationForOutputs = function(tx, callb
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TransactionService.prototype.getDetailedTransaction = function(txid, options, callback) {
|
TransactionService.prototype.getDetailedTransaction =
|
||||||
|
|
||||||
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.getTransaction = function(txid, options, callback) {
|
TransactionService.prototype.getTransaction = function(txid, options, callback) {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|||||||
@ -56,7 +56,7 @@ describe('Address Service', function() {
|
|||||||
|
|
||||||
it('should get the address history', function(done) {
|
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) {
|
addressService.getAddressHistory(['a', 'b', 'c'], { from: 12, to: 14 }, function(err, res) {
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -64,8 +64,8 @@ describe('Address Service', function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
expect(res).to.be.deep.equal({
|
expect(res).to.be.deep.equal({
|
||||||
totalCount: 3,
|
totalCount: 0,
|
||||||
items: [ {}, {}, {} ]
|
items: []
|
||||||
});
|
});
|
||||||
|
|
||||||
done();
|
done();
|
||||||
@ -81,6 +81,8 @@ describe('Address Service', function() {
|
|||||||
|
|
||||||
var getHeaderHash = sandbox.stub().callsArgWith(1, null, 'aa');
|
var getHeaderHash = sandbox.stub().callsArgWith(1, null, 'aa');
|
||||||
var getBlockHeader = 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 = {
|
addressService._header = {
|
||||||
getHeaderHash: getHeaderHash,
|
getHeaderHash: getHeaderHash,
|
||||||
@ -106,16 +108,14 @@ describe('Address Service', function() {
|
|||||||
if (err) {
|
if (err) {
|
||||||
return done(err);
|
return done(err);
|
||||||
}
|
}
|
||||||
|
expect(getTxidsByAddress.calledOnce).to.be.true;
|
||||||
expect(getTransaction.calledOnce).to.be.true;
|
expect(getTransaction.calledOnce).to.be.true;
|
||||||
expect(res).to.deep.equal([
|
expect(res).to.deep.equal([
|
||||||
{
|
{
|
||||||
__blockhash: 'aa',
|
|
||||||
__height: 123,
|
__height: 123,
|
||||||
__inputSatoshis: 1,
|
|
||||||
__inputValues: [
|
__inputValues: [
|
||||||
1
|
1
|
||||||
],
|
],
|
||||||
__outputSatoshis: 1,
|
|
||||||
outputs: [
|
outputs: [
|
||||||
{
|
{
|
||||||
value: 1
|
value: 1
|
||||||
|
|||||||
@ -161,6 +161,7 @@ describe('Block Service', function() {
|
|||||||
var setTip = sandbox.stub(blockService, '_setTip').callsArgWith(1, null);
|
var setTip = sandbox.stub(blockService, '_setTip').callsArgWith(1, null);
|
||||||
blockService.node = { openBus: sandbox.stub() };
|
blockService.node = { openBus: sandbox.stub() };
|
||||||
blockService._db = { getPrefix: getPrefix, getServiceTip: getServiceTip };
|
blockService._db = { getPrefix: getPrefix, getServiceTip: getServiceTip };
|
||||||
|
blockService._header = { on: sinon.stub() };
|
||||||
blockService.start(function() {
|
blockService.start(function() {
|
||||||
expect(blockService._encoding).to.be.an.instanceof(Encoding);
|
expect(blockService._encoding).to.be.an.instanceof(Encoding);
|
||||||
expect(getServiceTip.calledOnce).to.be.true;
|
expect(getServiceTip.calledOnce).to.be.true;
|
||||||
|
|||||||
@ -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() {
|
describe('#_getBlockTimestamp', function() {
|
||||||
it('should get the block\'s timestamp', function() {
|
it('should get the block\'s timestamp', function() {
|
||||||
var getTimestamp = sandbox.stub().returns(1);
|
var getTimestamp = sandbox.stub().returns(1);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user