From 630492b67a6e503a255d179793545e37245307ea Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 29 Apr 2015 12:24:47 -0300 Subject: [PATCH 01/12] add additional checks to /v1/blocks --- api/controllers/blocks.js | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/api/controllers/blocks.js b/api/controllers/blocks.js index 8eafd3ea..38514522 100644 --- a/api/controllers/blocks.js +++ b/api/controllers/blocks.js @@ -68,12 +68,31 @@ Blocks.list = function(req, res) { var offset = parseInt(req.query.offset || 0); var limit = parseInt(req.query.limit || 10); + if (from < 0) { + res.status(422); + res.send('/v1/blocks/ "from" must be valid block height (a positive integer)'); + return; + } + if (to < 0) { + res.status(422); + res.send('/v1/blocks/ "to" must be valid block height (a positive integer)'); + return; + } + if (offset < 0) { + res.status(422); + res.send('/v1/blocks/ "offset" must be a positive integer'); + return; + } + if (limit < 0) { + res.status(422); + res.send('/v1/blocks/ "limit" must be a positive integer'); + return; + } if (to < from) { res.status(422); res.send('/v1/blocks/ "to" must be >= "from"'); return; } - // TODO: add more parameter validation // TODO: return block_summary instead of block_full node.blockService.listBlocks(from, to, offset, limit) From d6aeb2d81a50c77584299eae6955eef7acf585ed Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 29 Apr 2015 12:26:29 -0300 Subject: [PATCH 02/12] remove logging --- lib/services/block.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/services/block.js b/lib/services/block.js index d52f1f42..418a5944 100644 --- a/lib/services/block.js +++ b/lib/services/block.js @@ -210,14 +210,13 @@ BlockService.prototype.listBlocks = function(from, to, offset, limit) { if (height > end) { return; } - console.log('fetching block', height); return self.getBlockByHeight(height) .then(function(block) { blocks.push(block.toObject()); return fetchBlock(height + 1); }) .catch(function(err) { - console.log(err); + // block not found, ignore }); }; return fetchBlock(start) From 6974c35a05fff8e8a647a1c90cc040acffbd1b86 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 29 Apr 2015 19:05:22 -0300 Subject: [PATCH 03/12] upgrade to bitcore v0.12.0 --- api/test/data/blocks.js | 2 +- api/test/v1/blocks.js | 8 +++++--- package.json | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/api/test/data/blocks.js b/api/test/data/blocks.js index f43d8d67..cd82ccbf 100644 --- a/api/test/data/blocks.js +++ b/api/test/data/blocks.js @@ -9,7 +9,7 @@ blockHexs.map(function(hex) { var block = new Block(new Buffer(hex, 'hex')); return block; }).forEach(function(block) { - mockBlocks[block.id] = block; + mockBlocks[block.id] = block.toObject(); }); module.exports = mockBlocks; diff --git a/api/test/v1/blocks.js b/api/test/v1/blocks.js index 18a541f0..6a1537a2 100644 --- a/api/test/v1/blocks.js +++ b/api/test/v1/blocks.js @@ -53,13 +53,15 @@ describe('BitcoreHTTP v1 blocks routes', function() { var start = from - 1e5; var end = to - 1e5; var section = blockList.slice(start, end); - return Promise.resolve(section.slice(offset, offset + limit)); + var ret = section.slice(offset, offset + limit); + console.log(ret); + return Promise.resolve(ret); }; app = require('../app')(nodeMock); agent = request(app); }); - describe('/blocks', function() { + describe.only('/blocks', function() { it('works with default parameters', function(cb) { agent.get('/v1/blocks/') .expect(200) @@ -95,7 +97,7 @@ describe('BitcoreHTTP v1 blocks routes', function() { it('returns latest block', function(cb) { agent.get('/v1/blocks/latest') .expect(200) - .expect(lastBlock.toJSON(), cb); + .expect(lastBlock, cb); }); }); describe('/blocks/:blockHash', function() { diff --git a/package.json b/package.json index 915775c0..e4c62dd5 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "dependencies": { "async": "0.9.0", "bitcoind-rpc": "^0.2.1", - "bitcore": "bitpay/bitcore", + "bitcore": "^0.12.0", "bitcore-p2p": "^0.13.0", "bluebird": "^2.9.12", "body-parser": "^1.12.0", From 739e306c50848efcaaf85373a3e15093740d1dbd Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 29 Apr 2015 20:10:29 -0300 Subject: [PATCH 04/12] one integration test working --- api/controllers/blocks.js | 6 ++++-- api/test/app.js | 10 +++++++++- api/test/data/blocks.js | 2 +- api/test/v1/blocks.js | 21 ++++++++++++--------- lib/services/block.js | 7 ++++--- 5 files changed, 30 insertions(+), 16 deletions(-) diff --git a/api/controllers/blocks.js b/api/controllers/blocks.js index 38514522..2fc43835 100644 --- a/api/controllers/blocks.js +++ b/api/controllers/blocks.js @@ -97,7 +97,9 @@ Blocks.list = function(req, res) { // TODO: return block_summary instead of block_full node.blockService.listBlocks(from, to, offset, limit) .then(function(blocks) { - res.send(blocks); + res.send(blocks.map(function(b) { + return b.toObject(); + })); }); }; @@ -110,7 +112,7 @@ Blocks.getLatest = function(req, res) { }; Blocks.get = function(req, res) { - $.checkState(req.block instanceof Block); + $.checkState(req.block instanceof Block, JSON.stringify(req.block)); res.send(req.block.toObject()); }; diff --git a/api/test/app.js b/api/test/app.js index b0443d8e..96449c15 100644 --- a/api/test/app.js +++ b/api/test/app.js @@ -1,7 +1,15 @@ 'use strict'; var BitcoreHTTP = require('../lib/http'); +var bitcore = require('bitcore'); module.exports = function(nodeMock) { - return process.env.INTEGRATION === 'true' ? BitcoreHTTP.create().app : new BitcoreHTTP(nodeMock).app; + if (process.env.INTEGRATION === 'true') { + var config = require('config'); + var network = config.get('BitcoreHTTP.BitcoreNode').network; + console.log('Starting test suite', network, 'network'); + bitcore.Networks.defaultNetwork = bitcore.Networks.get(network); + return BitcoreHTTP.create(config.get('BitcoreHTTP')).app; + } + return new BitcoreHTTP(nodeMock).app; }; diff --git a/api/test/data/blocks.js b/api/test/data/blocks.js index cd82ccbf..f43d8d67 100644 --- a/api/test/data/blocks.js +++ b/api/test/data/blocks.js @@ -9,7 +9,7 @@ blockHexs.map(function(hex) { var block = new Block(new Buffer(hex, 'hex')); return block; }).forEach(function(block) { - mockBlocks[block.id] = block.toObject(); + mockBlocks[block.id] = block; }); module.exports = mockBlocks; diff --git a/api/test/v1/blocks.js b/api/test/v1/blocks.js index 6a1537a2..0502a64d 100644 --- a/api/test/v1/blocks.js +++ b/api/test/v1/blocks.js @@ -54,50 +54,53 @@ describe('BitcoreHTTP v1 blocks routes', function() { var end = to - 1e5; var section = blockList.slice(start, end); var ret = section.slice(offset, offset + limit); - console.log(ret); return Promise.resolve(ret); }; app = require('../app')(nodeMock); agent = request(app); }); - describe.only('/blocks', function() { + var toObject = function(b) { + return b.toObject(); + }; + + describe('/blocks', function() { it('works with default parameters', function(cb) { agent.get('/v1/blocks/') .expect(200) - .expect(JSON.stringify(blockList), cb); + .expect(blockList.map(toObject), cb); }); it('fails with to= "from"', cb); }); - it('works with to/from parameters', function(cb) { + it.only('works with to/from parameters', function(cb) { agent.get('/v1/blocks/?from=100000&to=100001') .expect(200) - .expect(JSON.stringify([firstBlock]), cb); + .expect([firstBlock.toObject()], cb); }); it('works with limit/offset parameters', function(cb) { agent.get('/v1/blocks/?limit=1&offset=1') .expect(200) - .expect(JSON.stringify([secondBlock]), cb); + .expect([secondBlock.toObject()], cb); }); it('works with all parameters', function(cb) { agent.get('/v1/blocks/?from=100005&to=100020&limit=3&offset=2') .expect(200) - .expect(JSON.stringify(last3), cb); + .expect(last3.map(toObject), cb); }); it('works with all parameters 2', function(cb) { agent.get('/v1/blocks/?from=100000&to=100005&limit=2&offset=2') .expect(200) - .expect(JSON.stringify(some2), cb); + .expect(some2.map(toObject), cb); }); }); describe('/blocks/latest', function() { it('returns latest block', function(cb) { agent.get('/v1/blocks/latest') .expect(200) - .expect(lastBlock, cb); + .expect(lastBlock.toObject(), cb); }); }); describe('/blocks/:blockHash', function() { diff --git a/lib/services/block.js b/lib/services/block.js index 418a5944..523c22ba 100644 --- a/lib/services/block.js +++ b/lib/services/block.js @@ -91,7 +91,7 @@ BlockService.blockRPCtoBitcore = function(blockData) { nonce: blockData.nonce, bits: new bitcore.deps.bnjs( new bitcore.deps.Buffer(blockData.bits, 'hex') - ), + ).toNumber(), merkleRoot: bitcore.util.buffer.reverse( new bitcore.deps.Buffer(blockData.merkleroot, 'hex') ) @@ -192,6 +192,7 @@ BlockService.prototype.getBlockByHeight = function(height) { * @param {Number} to ditto, but for the upper limit, non inclusive * @param {Number} offset skip the first offset blocks * @param {Number} limit max amount of blocks returned + * @return {Array} a list of blocks * */ BlockService.prototype.listBlocks = function(from, to, offset, limit) { @@ -207,12 +208,12 @@ BlockService.prototype.listBlocks = function(from, to, offset, limit) { var blocks = []; // TODO: optimize: precompute heights and fetch all blocks in parallel? var fetchBlock = function(height) { - if (height > end) { + if (height >= end) { return; } return self.getBlockByHeight(height) .then(function(block) { - blocks.push(block.toObject()); + blocks.push(block); return fetchBlock(height + 1); }) .catch(function(err) { From 30dcb132dfaf7d7b784d164b86859cda32da8474 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 29 Apr 2015 20:22:25 -0300 Subject: [PATCH 05/12] 2 integration tests working --- api/test/app.js | 7 ++++++- api/test/v1/blocks.js | 20 +++++++++++--------- lib/services/block.js | 6 ++++-- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/api/test/app.js b/api/test/app.js index 96449c15..2551e032 100644 --- a/api/test/app.js +++ b/api/test/app.js @@ -3,13 +3,18 @@ var BitcoreHTTP = require('../lib/http'); var bitcore = require('bitcore'); +var _app = null; module.exports = function(nodeMock) { if (process.env.INTEGRATION === 'true') { + if (_app) { + return _app; + } var config = require('config'); var network = config.get('BitcoreHTTP.BitcoreNode').network; console.log('Starting test suite', network, 'network'); bitcore.Networks.defaultNetwork = bitcore.Networks.get(network); - return BitcoreHTTP.create(config.get('BitcoreHTTP')).app; + _app = BitcoreHTTP.create(config.get('BitcoreHTTP')).app; + return _app; } return new BitcoreHTTP(nodeMock).app; }; diff --git a/api/test/v1/blocks.js b/api/test/v1/blocks.js index 0502a64d..9578b56f 100644 --- a/api/test/v1/blocks.js +++ b/api/test/v1/blocks.js @@ -75,15 +75,17 @@ describe('BitcoreHTTP v1 blocks routes', function() { .expect(422) .expect('/v1/blocks/ "to" must be >= "from"', cb); }); - it.only('works with to/from parameters', function(cb) { - agent.get('/v1/blocks/?from=100000&to=100001') - .expect(200) - .expect([firstBlock.toObject()], cb); - }); - it('works with limit/offset parameters', function(cb) { - agent.get('/v1/blocks/?limit=1&offset=1') - .expect(200) - .expect([secondBlock.toObject()], cb); + describe.only('go', function() { + it('works with to/from parameters', function(cb) { + agent.get('/v1/blocks/?from=100000&to=100001') + .expect(200) + .expect([firstBlock.toObject()], cb); + }); + it('works with limit/offset parameters', function(cb) { + agent.get('/v1/blocks/?from=100000&limit=1&offset=1') + .expect(200) + .expect([secondBlock.toObject()], cb); + }); }); it('works with all parameters', function(cb) { agent.get('/v1/blocks/?from=100005&to=100020&limit=3&offset=2') diff --git a/lib/services/block.js b/lib/services/block.js index 523c22ba..ae230e25 100644 --- a/lib/services/block.js +++ b/lib/services/block.js @@ -204,12 +204,14 @@ BlockService.prototype.listBlocks = function(from, to, offset, limit) { var self = this; var start = from + offset; - var end = Math.min(to, start + limit - 1); + var end = Math.min(to, start + limit); var blocks = []; + //console.log(from, to, offset, limit); + //console.log(start, end); // TODO: optimize: precompute heights and fetch all blocks in parallel? var fetchBlock = function(height) { if (height >= end) { - return; + return Promise.resolve(); } return self.getBlockByHeight(height) .then(function(block) { From 9ac13de824ec4aab8d23648fc64d21cf01b281fe Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 29 Apr 2015 20:32:33 -0300 Subject: [PATCH 06/12] many more integration tests passing --- api/controllers/blocks.js | 3 +++ api/test/v1/blocks.js | 28 +++++++++++++++------------- lib/services/block.js | 7 ++++--- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/api/controllers/blocks.js b/api/controllers/blocks.js index 2fc43835..f316e255 100644 --- a/api/controllers/blocks.js +++ b/api/controllers/blocks.js @@ -30,6 +30,9 @@ Blocks.blockHashParam = function(req, res, next, blockHash) { .then(next) .catch(BitcoreNode.errors.Blocks.NotFound, function() { res.status(404).send('Block with id ' + blockHash + ' not found'); + }) + .catch(function() { + console.log(arguments); }); }; diff --git a/api/test/v1/blocks.js b/api/test/v1/blocks.js index 9578b56f..73e32266 100644 --- a/api/test/v1/blocks.js +++ b/api/test/v1/blocks.js @@ -64,9 +64,9 @@ describe('BitcoreHTTP v1 blocks routes', function() { return b.toObject(); }; - describe('/blocks', function() { + describe.only('/blocks', function() { it('works with default parameters', function(cb) { - agent.get('/v1/blocks/') + agent.get('/v1/blocks/?from=100000') .expect(200) .expect(blockList.map(toObject), cb); }); @@ -75,17 +75,15 @@ describe('BitcoreHTTP v1 blocks routes', function() { .expect(422) .expect('/v1/blocks/ "to" must be >= "from"', cb); }); - describe.only('go', function() { - it('works with to/from parameters', function(cb) { - agent.get('/v1/blocks/?from=100000&to=100001') - .expect(200) - .expect([firstBlock.toObject()], cb); - }); - it('works with limit/offset parameters', function(cb) { - agent.get('/v1/blocks/?from=100000&limit=1&offset=1') - .expect(200) - .expect([secondBlock.toObject()], cb); - }); + it('works with to/from parameters', function(cb) { + agent.get('/v1/blocks/?from=100000&to=100001') + .expect(200) + .expect([firstBlock.toObject()], cb); + }); + it('works with limit/offset parameters', function(cb) { + agent.get('/v1/blocks/?from=100000&limit=1&offset=1') + .expect(200) + .expect([secondBlock.toObject()], cb); }); it('works with all parameters', function(cb) { agent.get('/v1/blocks/?from=100005&to=100020&limit=3&offset=2') @@ -100,6 +98,10 @@ describe('BitcoreHTTP v1 blocks routes', function() { }); describe('/blocks/latest', function() { it('returns latest block', function(cb) { + if (process.env.INTEGRATION === 'true') { + // can't test this as latest block will always change + return cb(); + } agent.get('/v1/blocks/latest') .expect(200) .expect(lastBlock.toObject(), cb); diff --git a/lib/services/block.js b/lib/services/block.js index ae230e25..7920f92d 100644 --- a/lib/services/block.js +++ b/lib/services/block.js @@ -109,11 +109,12 @@ BlockService.blockRPCtoBitcore = function(blockData) { * @return {Promise} a promise that will always be rejected */ var blockNotFound = function(err) { - if (err) { + if (err instanceof Error) { throw err; } - var hash = err; - throw new errors.Blocks.NotFound(hash); + if (err.message === 'Block not found') { + throw new errors.Blocks.NotFound(); + } }; /** From c8c4d28d420446f8592ece7db899dd30ce0253eb Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 29 Apr 2015 20:37:10 -0300 Subject: [PATCH 07/12] all block integration tests working --- api/controllers/blocks.js | 3 +++ api/test/v1/blocks.js | 2 +- lib/services/block.js | 7 +++---- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/api/controllers/blocks.js b/api/controllers/blocks.js index f316e255..a1ed647e 100644 --- a/api/controllers/blocks.js +++ b/api/controllers/blocks.js @@ -48,6 +48,9 @@ Blocks.heightParam = function(req, res, next, height) { .then(next) .catch(BitcoreNode.errors.Blocks.NotFound, function() { res.status(404).send('Block with height ' + height + ' not found'); + }) + .catch(function() { + console.log(arguments); }); }; diff --git a/api/test/v1/blocks.js b/api/test/v1/blocks.js index 73e32266..863de1e9 100644 --- a/api/test/v1/blocks.js +++ b/api/test/v1/blocks.js @@ -64,7 +64,7 @@ describe('BitcoreHTTP v1 blocks routes', function() { return b.toObject(); }; - describe.only('/blocks', function() { + describe('/blocks', function() { it('works with default parameters', function(cb) { agent.get('/v1/blocks/?from=100000') .expect(200) diff --git a/lib/services/block.js b/lib/services/block.js index 7920f92d..d499e6c1 100644 --- a/lib/services/block.js +++ b/lib/services/block.js @@ -109,12 +109,11 @@ BlockService.blockRPCtoBitcore = function(blockData) { * @return {Promise} a promise that will always be rejected */ var blockNotFound = function(err) { - if (err instanceof Error) { - throw err; - } - if (err.message === 'Block not found') { + if (err.message === 'Block not found' || + err.message === 'Block height out of range') { throw new errors.Blocks.NotFound(); } + throw err; }; /** From fdb4051e87979cb26539c1a34d0b0152952d80e4 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 29 Apr 2015 20:37:32 -0300 Subject: [PATCH 08/12] add mocha.opts --- api/test/mocha.opts | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 api/test/mocha.opts diff --git a/api/test/mocha.opts b/api/test/mocha.opts new file mode 100644 index 00000000..19d98572 --- /dev/null +++ b/api/test/mocha.opts @@ -0,0 +1,2 @@ +--recursive +-R spec From 62948352d9bf998e4c322c1a4399af414f9930bc Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 29 Apr 2015 21:06:36 -0300 Subject: [PATCH 09/12] fix regressions --- test/networkmonitor.js | 1 - test/services/block.js | 11 ++++++----- test/services/transaction.js | 27 +++++---------------------- 3 files changed, 11 insertions(+), 28 deletions(-) diff --git a/test/networkmonitor.js b/test/networkmonitor.js index 3674eff9..f7ed4e6f 100644 --- a/test/networkmonitor.js +++ b/test/networkmonitor.js @@ -67,7 +67,6 @@ describe('NetworkMonitor', function() { it('broadcasts errors in underlying peer', function(cb) { var nm = new NetworkMonitor(busMock, peerMock); nm.on('error', function() { - console.log('under'); cb(); }); nm.start(); diff --git a/test/services/block.js b/test/services/block.js index a329113b..58f28141 100644 --- a/test/services/block.js +++ b/test/services/block.js @@ -80,7 +80,7 @@ describe('BlockService', function() { describe('block confirmation', function() { - var mockRpc, transactionMock, database, blockService, writeLock; + var mockRpc, transactionMock, database, blockService; var thenCaller = { then: function(arg) { @@ -118,7 +118,7 @@ describe('BlockService', function() { var expectedOps = [{ type: 'put', key: 'header-000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f', - value: '{"version":1,"prevHash":"0000000000000000000000000000000000000000000000000000000000000000","merkleRoot":"3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a","time":1231006505,"bits":486604799,"nonce":2083236893}' + value: '{"version":1,"prevHash":"0000000000000000000000000000000000000000000000000000000000000000","merkleRoot":"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b","time":1231006505,"bits":486604799,"nonce":2083236893}' }, { type: 'put', key: 'nxt-0000000000000000000000000000000000000000000000000000000000000000', @@ -149,10 +149,10 @@ describe('BlockService', function() { it('makes the expected calls when confirming the block #170', function(callback) { database.batchAsync = function(ops) { - ops.should.deep.equal([{ + var eops = [{ type: 'put', key: 'header-00000000d1145790a8694403d4063f323d499e655c83426834d4ce2f8dd4a2ee', - value: '{"version":1,"prevHash":"55bd840a78798ad0da853f68974f3d183e2bd1db6a842c1feecf222a00000000","merkleRoot":"ff104ccb05421ab93e63f8c3ce5c2c2e9dbb37de2764b3a3175c8166562cac7d","time":1231731025,"bits":486604799,"nonce":1889418792}' + value: '{"version":1,"prevHash":"000000002a22cfee1f2c846adbd12b3e183d4f97683f85dad08a79780a84bd55","merkleRoot":"7dac2c5666815c17a3b36427de37bb9d2e2c5ccec3f8633eb91a4205cb4c10ff","time":1231731025,"bits":486604799,"nonce":1889418792}' }, { type: 'put', key: 'nxt-000000002a22cfee1f2c846adbd12b3e183d4f97683f85dad08a79780a84bd55', @@ -173,7 +173,8 @@ describe('BlockService', function() { type: 'put', key: 'tip', value: block170.id - }]); + }]; + ops.should.deep.equal(eops); return callback(); }; blockService.writeLock.onFirstCall().returns(thenCaller); diff --git a/test/services/transaction.js b/test/services/transaction.js index 4994ad3a..f8b9c723 100644 --- a/test/services/transaction.js +++ b/test/services/transaction.js @@ -107,40 +107,23 @@ describe('TransactionService', function() { } }); service._confirmTransaction(ops, block170, block170.transactions[1]).then(function() { - ops.map(function(k) { - if (bitcore.util.js.isValidJSON(k.value)) { - k.value = JSON.parse(k.value); - } - return k; - }).should.deep.equal([{ + ops.should.deep.equal([{ type: 'put', key: 'btx-f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16', value: '00000000d1145790a8694403d4063f323d499e655c83426834d4ce2f8dd4a2ee' }, { type: 'put', key: 'txo-f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16-0', - value: { - satoshis: 1000000000, - script: '65 0x04ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84c OP_CHECKSIG' - } + value: '{"satoshis":1000000000,"script":"65 0x04ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84c OP_CHECKSIG"}' }, { type: 'put', key: 'txo-f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16-1', - value: { - satoshis: 4000000000, - script: '65 0x0411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3 OP_CHECKSIG' - } + value: '{"satoshis":4000000000,"script":"65 0x0411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3 OP_CHECKSIG"}' }, { type: 'put', key: 'txo-f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16-0', - value: { - prevTxId: '0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9', - outputIndex: 0, - sequenceNumber: 4294967295, - script: '71 0x304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901', - heightConfirmed: 170 - } - }, ]); + value: '{"prevTxId":"0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9","outputIndex":0,"sequenceNumber":4294967295,"script":"47304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901","scriptString":"71 0x304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901","heightConfirmed":170}' + }]); /* TODO: This should work if address spent is accepted for public key. Add test for P2PKH if not accepted * { type: 'put', key: 'txas-12cbQLTFMXRnSzktFkuoG3eHoMeFtpTu3S-f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16-0', From 749b8db70ca6384cdff93d0677cae9ee7ecf2eaf Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 29 Apr 2015 21:13:31 -0300 Subject: [PATCH 10/12] add current height to /v1/node --- api/test/v1/node.js | 1 + lib/node.js | 1 + 2 files changed, 2 insertions(+) diff --git a/api/test/v1/node.js b/api/test/v1/node.js index 16ebcad6..1a6ee28c 100644 --- a/api/test/v1/node.js +++ b/api/test/v1/node.js @@ -21,6 +21,7 @@ describe('BitcoreHTTP v1 node routes', function() { peerCount: 8, version: 'test', network: 'test', + height: 1234, }; nodeMock.getStatus = function() { return Promise.resolve(nodeMock.status); diff --git a/lib/node.js b/lib/node.js index b24f9790..bd0724ba 100644 --- a/lib/node.js +++ b/lib/node.js @@ -188,6 +188,7 @@ BitcoreNode.prototype.getStatus = function() { peerCount: this.networkMonitor.getConnectedPeers(), version: pjson.version, network: bitcore.Networks.defaultNetwork.name, + height: this.blockchain.getCurrentHeight(), }); }; From ae03c8e454d2247b8aef88f9748cc4aaa3003ad4 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 29 Apr 2015 21:26:40 -0300 Subject: [PATCH 11/12] towards polishing tx api --- api/controllers/transactions.js | 3 +++ api/test/v1/transactions.js | 4 ++-- lib/services/transaction.js | 23 +++++++++++++++-------- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/api/controllers/transactions.js b/api/controllers/transactions.js index 2dd73599..5bf4244f 100644 --- a/api/controllers/transactions.js +++ b/api/controllers/transactions.js @@ -32,6 +32,9 @@ Transactions.txHashParam = function(req, res, next, txHash) { .then(next) .catch(BitcoreNode.errors.Transactions.NotFound, function() { res.status(404).send('Transaction with id ' + txHash + ' not found'); + }) + .catch(function() { + console.log(arguments); }); }; diff --git a/api/test/v1/transactions.js b/api/test/v1/transactions.js index bb30b3b0..71e731b4 100644 --- a/api/test/v1/transactions.js +++ b/api/test/v1/transactions.js @@ -15,7 +15,7 @@ var BitcoreHTTP = require('../../lib/http'); var BitcoreNode = require('../../../'); var mockTransactions = require('../data/transactions'); -describe('BitcoreHTTP v1 transactions routes', function() { +describe.only('BitcoreHTTP v1 transactions routes', function() { // mocks var mockValidTx = new Transaction(); @@ -37,7 +37,7 @@ describe('BitcoreHTTP v1 transactions routes', function() { } return Promise.resolve(); }; - app = new BitcoreHTTP(nodeMock).app; + app = require('../app')(nodeMock); agent = request(app); }); diff --git a/lib/services/transaction.js b/lib/services/transaction.js index e4987d76..d042a28c 100644 --- a/lib/services/transaction.js +++ b/lib/services/transaction.js @@ -20,6 +20,7 @@ var LevelUp = require('levelup'); var Promise = require('bluebird'); var bitcore = require('bitcore'); var config = require('config'); +var BitcoreNode = require('../../'); var _ = bitcore.deps._; var $ = bitcore.util.preconditions; @@ -53,7 +54,7 @@ var Index = { output: 'txo-', // txo-- -> serialized Output spent: 'txs-', // txo---- -> block height of confirmation for spend address: 'txa-', // txa-
-- -> Output - addressSpent: 'txas-', + addressSpent: 'txas-', // txa-
-- -> { // heightSpent: number, (may be -1 for unconfirmed tx) // spentTx: string, spentTxInputIndex: number, spendInput: Input @@ -84,10 +85,14 @@ function TransactionService(opts) { } TransactionService.Index = Index; -TransactionService.transactionRPCtoBitcore = function(rpcResponse) { - if (rpcResponse.error) { - throw new bitcore.Error(rpcResponse.error); +var txNotFound = function(error) { + if (error.message === 'No information available about transaction') { + throw new BitcoreNode.errors.Transactions.NotFound(); } + throw error; +}; + +TransactionService.transactionRPCtoBitcore = function(rpcResponse) { return new bitcore.Transaction(rpcResponse.result); }; @@ -99,10 +104,12 @@ TransactionService.prototype.getTransaction = function(transactionId) { } return Promise.try(function() { - return self.rpc.getRawTransactionAsync(transactionId); - }).then(function(rawTransaction) { - return TransactionService.transactionRPCtoBitcore(rawTransaction); - }); + return self.rpc.getRawTransactionAsync(transactionId); + }) + .catch(txNotFound) + .then(function(rawTransaction) { + return TransactionService.transactionRPCtoBitcore(rawTransaction); + }); }; TransactionService.prototype._confirmOutput = function(ops, block, transaction) { From 085d8f2e39893dc251c7c3a418a6a2ff659fca90 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 29 Apr 2015 21:46:46 -0300 Subject: [PATCH 12/12] upgrade bitcore-p2p --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e4c62dd5..b302e0b5 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "async": "0.9.0", "bitcoind-rpc": "^0.2.1", "bitcore": "^0.12.0", - "bitcore-p2p": "^0.13.0", + "bitcore-p2p": "^0.15.0", "bluebird": "^2.9.12", "body-parser": "^1.12.0", "bufferput": "bitpay/node-bufferput",