From 8f11a338344ccb9a6afde66e26a6de5459670060 Mon Sep 17 00:00:00 2001 From: Braydon Fuller Date: Mon, 16 May 2016 17:34:40 -0400 Subject: [PATCH] test: add getBlockOverview unit tests and refactor --- lib/services/bitcoind.js | 86 ++++++++------------- test/services/bitcoind.unit.js | 134 +++++++++++++++++++++++++++++++++ 2 files changed, 165 insertions(+), 55 deletions(-) diff --git a/lib/services/bitcoind.js b/lib/services/bitcoind.js index 7f4c68a9..6b199ec0 100644 --- a/lib/services/bitcoind.js +++ b/lib/services/bitcoind.js @@ -1378,6 +1378,22 @@ Bitcoin.prototype.getAddressSummary = function(addressArg, options, callback) { }; +Bitcoin.prototype._maybeGetBlockHash = function(blockArg, callback) { + var self = this; + if (_.isNumber(blockArg)) { + self._tryAll(function(done) { + self.client.getBlockHash(blockArg, function(err, response) { + if (err) { + return done(self._wrapRPCError(err)); + } + done(null, response.result); + }); + }, callback); + } else { + callback(null, blockArg); + } +}; + /** * Will retrieve a block as a Node.js Buffer * @param {String|Number} block - A block hash or block height number @@ -1387,7 +1403,10 @@ Bitcoin.prototype.getRawBlock = function(blockArg, callback) { // TODO apply performance patch to the RPC method for raw data var self = this; - function queryBlock(blockhash) { + function queryBlock(err, blockhash) { + if (err) { + return callback(err); + } self._tryAll(function(done) { self.client.getBlock(blockhash, false, function(err, response) { if (err) { @@ -1406,23 +1425,7 @@ Bitcoin.prototype.getRawBlock = function(blockArg, callback) { callback(null, cachedBlock); }); } else { - if (_.isNumber(blockArg)) { - self._tryAll(function(done) { - self.client.getBlockHash(blockArg, function(err, response) { - if (err) { - return callback(self._wrapRPCError(err)); - } - done(null, response.result); - }); - }, function(err, blockhash) { - if (err) { - return callback(err); - } - queryBlock(blockhash); - }); - } else { - queryBlock(blockArg); - } + self._maybeGetBlockHash(blockArg, queryBlock); } }; @@ -1434,7 +1437,10 @@ Bitcoin.prototype.getRawBlock = function(blockArg, callback) { Bitcoin.prototype.getBlockOverview = function(blockArg, callback) { var self = this; - function queryBlock(blockhash) { + function queryBlock(err, blockhash) { + if (err) { + return callback(err); + } var cachedBlock = self.blockOverviewCache.get(blockhash); if (cachedBlock) { return setImmediate(function() { @@ -1470,23 +1476,7 @@ Bitcoin.prototype.getBlockOverview = function(blockArg, callback) { } } - if (_.isNumber(blockArg)) { - self._tryAll(function(done) { - self.client.getBlockHash(blockArg, function(err, response) { - if (err) { - return done(self._wrapRPCError(err)); - } - done(null, response.result); - }); - }, function(err, blockhash) { - if (err) { - return callback(err); - } - queryBlock(blockhash); - }); - } else { - queryBlock(blockArg); - } + self._maybeGetBlockHash(blockArg, queryBlock); }; /** @@ -1498,7 +1488,10 @@ Bitcoin.prototype.getBlock = function(blockArg, callback) { // TODO apply performance patch to the RPC method for raw data var self = this; - function queryBlock(blockhash) { + function queryBlock(err, blockhash) { + if (err) { + return callback(err); + } var cachedBlock = self.blockCache.get(blockhash); if (cachedBlock) { return setImmediate(function() { @@ -1518,24 +1511,7 @@ Bitcoin.prototype.getBlock = function(blockArg, callback) { } } - if (_.isNumber(blockArg)) { - self._tryAll(function(done) { - self.client.getBlockHash(blockArg, function(err, response) { - if (err) { - return done(self._wrapRPCError(err)); - } - done(null, response.result); - }); - }, function(err, blockhash) { - if (err) { - return callback(err); - } - queryBlock(blockhash); - }); - } else { - queryBlock(blockArg); - } - + self._maybeGetBlockHash(blockArg, queryBlock); }; /** diff --git a/test/services/bitcoind.unit.js b/test/services/bitcoind.unit.js index 49c0e679..87ff5abb 100644 --- a/test/services/bitcoind.unit.js +++ b/test/services/bitcoind.unit.js @@ -2769,6 +2769,140 @@ describe('Bitcoin Service', function() { }); }); + describe('#_maybeGetBlockHash', function() { + it('will get the block hash if argument is a number', function(done) { + var bitcoind = new BitcoinService(baseConfig); + var getBlockHash = sinon.stub().callsArgWith(1, null, { + result: 'blockhash' + }); + bitcoind.nodes.push({ + client: { + getBlockHash: getBlockHash + } + }); + bitcoind._maybeGetBlockHash(10, function(err, hash) { + if (err) { + return done(err); + } + hash.should.equal('blockhash'); + getBlockHash.callCount.should.equal(1); + done(); + }); + }); + it('will try multiple nodes if one fails', function(done) { + var bitcoind = new BitcoinService(baseConfig); + var getBlockHash = sinon.stub().callsArgWith(1, null, { + result: 'blockhash' + }); + getBlockHash.onCall(0).callsArgWith(1, {code: -1, message: 'test'}); + bitcoind.tryAllInterval = 1; + bitcoind.nodes.push({ + client: { + getBlockHash: getBlockHash + } + }); + bitcoind.nodes.push({ + client: { + getBlockHash: getBlockHash + } + }); + bitcoind._maybeGetBlockHash(10, function(err, hash) { + if (err) { + return done(err); + } + hash.should.equal('blockhash'); + getBlockHash.callCount.should.equal(2); + done(); + }); + }); + it('will give error from getBlockHash', function(done) { + var bitcoind = new BitcoinService(baseConfig); + var getBlockHash = sinon.stub().callsArgWith(1, {code: -1, message: 'test'}); + bitcoind.tryAllInterval = 1; + bitcoind.nodes.push({ + client: { + getBlockHash: getBlockHash + } + }); + bitcoind.nodes.push({ + client: { + getBlockHash: getBlockHash + } + }); + bitcoind._maybeGetBlockHash(10, function(err, hash) { + getBlockHash.callCount.should.equal(2); + err.should.be.instanceOf(Error); + err.message.should.equal('test'); + err.code.should.equal(-1); + done(); + }); + }); + }); + + describe('#getBlockOverview', function() { + var blockhash = '00000000050a6d07f583beba2d803296eb1e9d4980c4a20f206c584e89a4f02b'; + it('will handle error from maybeGetBlockHash', function(done) { + var bitcoind = new BitcoinService(baseConfig); + bitcoind._maybeGetBlockHash = sinon.stub().callsArgWith(1, new Error('test')); + bitcoind.getBlockOverview(blockhash, function(err) { + err.should.be.instanceOf(Error); + done(); + }); + }); + it('will give expected result', function(done) { + var bitcoind = new BitcoinService(baseConfig); + var blockResult = { + hash: blockhash, + version: 536870912, + confirmations: 5, + height: 828781, + chainwork: '00000000000000000000000000000000000000000000000ad467352c93bc6a3b', + previousblockhash: '0000000000000504235b2aff578a48470dbf6b94dafa9b3703bbf0ed554c9dd9', + nextblockhash: '00000000000000eedd967ec155f237f033686f0924d574b946caf1b0e89551b8', + merkleroot: '124e0f3fb5aa268f102b0447002dd9700988fc570efcb3e0b5b396ac7db437a9', + time: 1462979126, + mediantime: 1462976771, + nonce: 2981820714, + bits: '1a13ca10', + difficulty: 847779.0710240941 + }; + var getBlock = sinon.stub().callsArgWith(2, null, { + result: blockResult + }); + bitcoind.nodes.push({ + client: { + getBlock: getBlock + } + }); + function checkBlock(blockOverview) { + blockOverview.hash.should.equal('00000000050a6d07f583beba2d803296eb1e9d4980c4a20f206c584e89a4f02b'); + blockOverview.version.should.equal(536870912); + blockOverview.confirmations.should.equal(5); + blockOverview.height.should.equal(828781); + blockOverview.chainWork.should.equal('00000000000000000000000000000000000000000000000ad467352c93bc6a3b'); + blockOverview.prevHash.should.equal('0000000000000504235b2aff578a48470dbf6b94dafa9b3703bbf0ed554c9dd9'); + blockOverview.nextHash.should.equal('00000000000000eedd967ec155f237f033686f0924d574b946caf1b0e89551b8'); + blockOverview.merkleRoot.should.equal('124e0f3fb5aa268f102b0447002dd9700988fc570efcb3e0b5b396ac7db437a9'); + blockOverview.time.should.equal(1462979126); + blockOverview.medianTime.should.equal(1462976771); + blockOverview.nonce.should.equal(2981820714); + blockOverview.bits.should.equal('1a13ca10'); + blockOverview.difficulty.should.equal(847779.0710240941); + } + bitcoind.getBlockOverview(blockhash, function(err, blockOverview) { + if (err) { + return done(err); + } + checkBlock(blockOverview); + bitcoind.getBlockOverview(blockhash, function(err, blockOverview) { + checkBlock(blockOverview); + getBlock.callCount.should.equal(1); + done(); + }); + }); + }); + }); + describe('#estimateFee', function() { it('will give rpc error', function(done) { var bitcoind = new BitcoinService(baseConfig);