test: increase test coverage of bitcoind service

This commit is contained in:
Braydon Fuller 2016-05-24 13:07:51 -04:00
parent 35a1b6dd04
commit 3fef6f5ffc
2 changed files with 172 additions and 27 deletions

View File

@ -1338,12 +1338,8 @@ Bitcoin.prototype._paginateTxids = function(fullTxids, fromArg, toArg) {
var txids;
var from = parseInt(fromArg);
var to = parseInt(toArg);
if (from >= 0 && to >= 0) {
$.checkState(from < to, '"from" (' + from + ') is expected to be less than "to" (' + to + ')');
txids = fullTxids.slice(from, to);
} else {
txids = fullTxids;
}
$.checkState(from < to, '"from" (' + from + ') is expected to be less than "to" (' + to + ')');
txids = fullTxids.slice(from, to);
return txids;
};
@ -1363,7 +1359,10 @@ Bitcoin.prototype.getAddressHistory = function(addressArg, options, callback) {
var queryMempool = _.isUndefined(options.queryMempool) ? true : options.queryMempool;
var addressStrings = this._getAddressStrings(addresses);
if ((options.to - options.from) > self.maxTransactionHistory) {
var fromArg = parseInt(options.from || 0);
var toArg = parseInt(options.to || self.maxTransactionHistory);
if ((toArg - fromArg) > self.maxTransactionHistory) {
return callback(new Error(
'"from" (' + options.from + ') and "to" (' + options.to + ') range should be less than or equal to ' +
self.maxTransactionHistory
@ -1377,7 +1376,7 @@ Bitcoin.prototype.getAddressHistory = function(addressArg, options, callback) {
var totalCount = txids.length;
try {
txids = self._paginateTxids(txids, options.from, options.to);
txids = self._paginateTxids(txids, fromArg, toArg);
} catch(e) {
return callback(e);
}
@ -1424,12 +1423,12 @@ Bitcoin.prototype.getAddressSummary = function(addressArg, options, callback) {
var fromArg = parseInt(options.from || 0);
var toArg = parseInt(options.to || self.maxTxids);
if ((toArg - fromArg) > self.maxTxids) {
return callback(new Error(
'"from" (' + fromArg + ') and "to" (' + toArg + ') range should be less than or equal to ' +
self.maxTxids
));
}
if ((toArg - fromArg) > self.maxTxids) {
return callback(new Error(
'"from" (' + fromArg + ') and "to" (' + toArg + ') range should be less than or equal to ' +
self.maxTxids
));
}
var paginatedTxids;
try {
paginatedTxids = self._paginateTxids(allTxids, fromArg, toArg);
@ -1751,19 +1750,13 @@ Bitcoin.prototype.estimateFee = function(blocks, callback) {
Bitcoin.prototype.sendTransaction = function(tx, options, callback) {
var self = this;
var allowAbsurdFees = false;
var txString;
if (tx instanceof Transaction) {
txString = tx.serialize();
} else {
txString = tx;
}
if (_.isFunction(options) && _.isUndefined(callback)) {
callback = options;
} else if (_.isObject(options)) {
allowAbsurdFees = options.allowAbsurdFees;
}
this.client.sendRawTransaction(txString, allowAbsurdFees, function(err, response) {
this.client.sendRawTransaction(tx, allowAbsurdFees, function(err, response) {
if (err) {
return callback(self._wrapRPCError(err));
}
@ -1880,14 +1873,13 @@ Bitcoin.prototype.getDetailedTransaction = function(txid, callback) {
if (!tx.coinbase) {
tx.inputSatoshis += input.valueSat;
}
var script;
var scriptAsm;
var script = null;
var scriptAsm = null;
if (input.scriptSig) {
script = input.scriptSig.hex;
scriptAsm = input.scriptSig.asm;
} else if (input.coinbase) {
script = input.coinbase;
scriptAsm = null;
}
tx.inputs.push({
prevTxId: input.txid || null,
@ -1908,7 +1900,7 @@ Bitcoin.prototype.getDetailedTransaction = function(txid, callback) {
var out = result.vout[outputIndex];
tx.outputSatoshis += out.valueSat;
var address = null;
if (out.scriptPubKey && out.scriptPubKey.addresses && out.scriptPubKey.addresses.length > 0) {
if (out.scriptPubKey.addresses.length === 1) {
address = out.scriptPubKey.addresses[0];
}
tx.outputs.push({

View File

@ -944,6 +944,35 @@ describe('Bitcoin Service', function() {
bitcoind._updateTip(node, message);
bitcoind._updateTip(node, message);
});
it('will not call syncPercentage if node is stopping', function(done) {
var config = {
node: {
network: bitcore.Networks.testnet
},
spawn: {
datadir: 'testdir',
exec: 'testpath'
}
};
var bitcoind = new BitcoinService(config);
bitcoind.syncPercentage = sinon.stub();
bitcoind._resetCaches = sinon.stub();
bitcoind.node.stopping = true;
var node = {
client: {
getBlock: sinon.stub().callsArgWith(1, null, {
result: {
height: 10
}
})
}
};
bitcoind.on('tip', function() {
bitcoind.syncPercentage.callCount.should.equal(0);
done();
});
bitcoind._updateTip(node, message);
});
});
describe('#_getAddressesFromTransaction', function() {
@ -1268,6 +1297,16 @@ describe('Bitcoin Service', function() {
done();
});
});
it('will call callback if reindex is not enabled', function(done) {
var bitcoind = new BitcoinService(baseConfig);
var node = {
_reindex: false
};
bitcoind._checkReindex(node, function() {
node._reindex.should.equal(false);
done();
});
});
});
describe('#_loadTipFromNode', function() {
@ -2078,7 +2117,7 @@ describe('Bitcoin Service', function() {
});
});
describe('#_getTxidsMempool', function() {
describe('#_getTxidsFromMempool', function() {
it('will filter to txids', function() {
var bitcoind = new BitcoinService(baseConfig);
var deltas = [
@ -2098,6 +2137,24 @@ describe('Bitcoin Service', function() {
txids[1].should.equal('txid1');
txids[2].should.equal('txid2');
});
it('will not include duplicates', function() {
var bitcoind = new BitcoinService(baseConfig);
var deltas = [
{
txid: 'txid0',
},
{
txid: 'txid0',
},
{
txid: 'txid1',
}
];
var txids = bitcoind._getTxidsFromMempool(deltas);
txids.length.should.equal(2);
txids[0].should.equal('txid0');
txids[1].should.equal('txid1');
});
});
describe('#_getHeightRangeQuery', function() {
@ -2332,6 +2389,14 @@ describe('Bitcoin Service', function() {
afterEach(function() {
sandbox.restore();
});
it('should get 0 confirmation', function() {
var tx = new Transaction(txhex);
tx.height = -1;
var bitcoind = new BitcoinService(baseConfig);
bitcoind.height = 10;
var confirmations = bitcoind._getConfirmationsDetail(tx);
confirmations.should.equal(0);
});
it('should get 1 confirmation', function() {
var tx = new Transaction(txhex);
tx.height = 10;
@ -3420,6 +3485,21 @@ describe('Bitcoin Service', function() {
hash.should.equal(tx.hash);
});
});
it('missing callback will throw error', function() {
var bitcoind = new BitcoinService(baseConfig);
var sendRawTransaction = sinon.stub().callsArgWith(2, null, {
result: tx.hash
});
bitcoind.nodes.push({
client: {
sendRawTransaction: sendRawTransaction
}
});
var transaction = bitcore.Transaction();
(function() {
bitcoind.sendTransaction(transaction);
}).should.throw(Error);
});
});
describe('#getRawTransaction', function() {
@ -3684,7 +3764,7 @@ describe('Bitcoin Service', function() {
});
it('should set coinbase to true', function(done) {
var bitcoind = new BitcoinService(baseConfig);
var rawTransaction = _.clone(rpcRawTransaction);
var rawTransaction = JSON.parse((JSON.stringify(rpcRawTransaction)));
delete rawTransaction.vin[0];
rawTransaction.vin = [
{
@ -3705,6 +3785,79 @@ describe('Bitcoin Service', function() {
done();
});
});
it('will not include address if address length is zero', function(done) {
var bitcoind = new BitcoinService(baseConfig);
var rawTransaction = JSON.parse((JSON.stringify(rpcRawTransaction)));
rawTransaction.vout[0].scriptPubKey.addresses = [];
bitcoind.nodes.push({
client: {
getRawTransaction: sinon.stub().callsArgWith(2, null, {
result: rawTransaction
})
}
});
var txid = '2d950d00494caf6bfc5fff2a3f839f0eb50f663ae85ce092bc5f9d45296ae91f';
bitcoind.getDetailedTransaction(txid, function(err, tx) {
should.exist(tx);
should.equal(tx.outputs[0].address, null);
done();
});
});
it('will not include address if address length is greater than 1', function(done) {
var bitcoind = new BitcoinService(baseConfig);
var rawTransaction = JSON.parse((JSON.stringify(rpcRawTransaction)));
rawTransaction.vout[0].scriptPubKey.addresses = ['one', 'two'];
bitcoind.nodes.push({
client: {
getRawTransaction: sinon.stub().callsArgWith(2, null, {
result: rawTransaction
})
}
});
var txid = '2d950d00494caf6bfc5fff2a3f839f0eb50f663ae85ce092bc5f9d45296ae91f';
bitcoind.getDetailedTransaction(txid, function(err, tx) {
should.exist(tx);
should.equal(tx.outputs[0].address, null);
done();
});
});
it('will not include script if input missing scriptSig or coinbase', function(done) {
var bitcoind = new BitcoinService(baseConfig);
var rawTransaction = JSON.parse((JSON.stringify(rpcRawTransaction)));
delete rawTransaction.vin[0].scriptSig;
delete rawTransaction.vin[0].coinbase;
bitcoind.nodes.push({
client: {
getRawTransaction: sinon.stub().callsArgWith(2, null, {
result: rawTransaction
})
}
});
var txid = '2d950d00494caf6bfc5fff2a3f839f0eb50f663ae85ce092bc5f9d45296ae91f';
bitcoind.getDetailedTransaction(txid, function(err, tx) {
should.exist(tx);
should.equal(tx.inputs[0].script, null);
done();
});
});
it('will set height to -1 if missing height', function(done) {
var bitcoind = new BitcoinService(baseConfig);
var rawTransaction = JSON.parse((JSON.stringify(rpcRawTransaction)));
delete rawTransaction.height;
bitcoind.nodes.push({
client: {
getRawTransaction: sinon.stub().callsArgWith(2, null, {
result: rawTransaction
})
}
});
var txid = '2d950d00494caf6bfc5fff2a3f839f0eb50f663ae85ce092bc5f9d45296ae91f';
bitcoind.getDetailedTransaction(txid, function(err, tx) {
should.exist(tx);
should.equal(tx.height, -1);
done();
});
});
});
describe('#getBestBlockHash', function() {