From a54df2c87f3e45191c72105a0bfe1d37c4c268c0 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Sat, 29 Jun 2019 22:12:29 -0700 Subject: [PATCH 1/5] node/http: get block header by hash/height --- lib/node/http.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/lib/node/http.js b/lib/node/http.js index 01de675fb..e1a5b6005 100644 --- a/lib/node/http.js +++ b/lib/node/http.js @@ -255,6 +255,27 @@ class HTTP extends Server { res.json(200, block.getJSON(this.network, view, height, depth)); }); + // Block Header by hash/height + this.get('/header/:block', async (req, res) => { + const valid = Validator.fromRequest(req); + const hash = valid.uintbrhash('block'); + + enforce(hash != null, 'Hash or height required.'); + enforce(!this.chain.options.spv, 'Cannot get block header in SPV mode.'); + + const block = await this.chain.getBlock(hash); + + if (!block) { + res.json(404); + return; + } + + const header = block.toHeaders(); + const height = await this.chain.getHeight(hash); + + res.json(200, header.getJSON(this.network, null, height)); + }); + // Mempool snapshot this.get('/mempool', async (req, res) => { enforce(this.mempool, 'No mempool available.'); From f0b46f965332ee607768dd9b6cc1f85aca07185b Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Mon, 1 Jul 2019 19:58:22 -0700 Subject: [PATCH 2/5] node/http: use entry instead of block --- lib/node/http.js | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/lib/node/http.js b/lib/node/http.js index e1a5b6005..281c08776 100644 --- a/lib/node/http.js +++ b/lib/node/http.js @@ -261,19 +261,15 @@ class HTTP extends Server { const hash = valid.uintbrhash('block'); enforce(hash != null, 'Hash or height required.'); - enforce(!this.chain.options.spv, 'Cannot get block header in SPV mode.'); - const block = await this.chain.getBlock(hash); + const entry = await this.chain.getEntry(hash); - if (!block) { + if (!entry) { res.json(404); return; } - const header = block.toHeaders(); - const height = await this.chain.getHeight(hash); - - res.json(200, header.getJSON(this.network, null, height)); + res.json(200, entry.toJSON()); }); // Mempool snapshot From 0c69c6d7c9bde18b9dc778c8a40804be33ba345e Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Fri, 5 Jul 2019 14:39:57 -0700 Subject: [PATCH 3/5] test: get block header --- test/http-test.js | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/test/http-test.js b/test/http-test.js index c553e77cb..d10eee50a 100644 --- a/test/http-test.js +++ b/test/http-test.js @@ -454,6 +454,50 @@ describe('HTTP', function() { assert.strictEqual(blocks.length, 10); }); + // depends on the previous test to generate blocks + it('should fetch block header', async () => { + // fetch corresponding header and block + const header = await nclient.get(`/header/${7}`); + assert.equal(header.height, 7); + + const properties = [ + 'hash', 'version', 'prevBlock', + 'merkleRoot', 'time', 'bits', + 'nonce', 'height', 'chainwork' + ]; + + for (const property of properties) + assert(property in header); + + const block = await nclient.getBlock(7); + + assert.equal(block.hash, header.hash); + assert.equal(block.height, header.height); + assert.equal(block.version, header.version); + assert.equal(block.prevBlock, header.prevBlock); + assert.equal(block.merkleRoot, header.merkleRoot); + assert.equal(block.time, header.time); + assert.equal(block.bits, header.bits); + assert.equal(block.nonce, header.nonce); + }); + + it('should fetch null for block header that does not exist', async () => { + // many blocks in the future + const header = await nclient.get(`/header/${40000}`); + assert.equal(header, null); + }); + + it('should have valid header chain', async () => { + // starting at the genesis block + let prevBlock = '0000000000000000000000000000000000000000000000000000000000000000'; + for (let i = 0; i < 10; i++) { + const header = await nclient.get(`/header/${i}`); + + assert.equal(prevBlock, header.prevBlock); + prevBlock = header.hash; + } + }); + it('should initiate rescan from socket without a bloom filter', async () => { // Rescan from height 5. Without a filter loaded = no response, but no error const response = await nclient.call('rescan', 5); From 346292f2078ea7ab4f7bb336a94e8d8f8c78d39b Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Mon, 8 Jul 2019 12:48:43 -0700 Subject: [PATCH 4/5] test: get block header by hash --- test/http-test.js | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/test/http-test.js b/test/http-test.js index d10eee50a..bcf2d610c 100644 --- a/test/http-test.js +++ b/test/http-test.js @@ -455,10 +455,11 @@ describe('HTTP', function() { }); // depends on the previous test to generate blocks - it('should fetch block header', async () => { + it('should fetch block header by height', async () => { // fetch corresponding header and block - const header = await nclient.get(`/header/${7}`); - assert.equal(header.height, 7); + const height = 7; + const header = await nclient.get(`/header/${height}`); + assert.equal(header.height, height); const properties = [ 'hash', 'version', 'prevBlock', @@ -469,7 +470,7 @@ describe('HTTP', function() { for (const property of properties) assert(property in header); - const block = await nclient.getBlock(7); + const block = await nclient.getBlock(height); assert.equal(block.hash, header.hash); assert.equal(block.height, header.height); @@ -481,6 +482,15 @@ describe('HTTP', function() { assert.equal(block.nonce, header.nonce); }); + it('should fetch block header by hash', async () => { + const info = await nclient.getInfo(); + + const headerByHash = await nclient.get(`/header/${info.chain.tip}`); + const headerByHeight = await nclient.get(`/header/${info.chain.height}`); + + assert.deepEqual(headerByHash, headerByHeight); + }); + it('should fetch null for block header that does not exist', async () => { // many blocks in the future const header = await nclient.get(`/header/${40000}`); From f62370800c95c92da1684edb04256b4af3b16804 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Thu, 18 Jul 2019 13:41:57 -0700 Subject: [PATCH 5/5] nit: fix comment style --- test/http-test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/http-test.js b/test/http-test.js index bcf2d610c..bfb7ca868 100644 --- a/test/http-test.js +++ b/test/http-test.js @@ -454,7 +454,7 @@ describe('HTTP', function() { assert.strictEqual(blocks.length, 10); }); - // depends on the previous test to generate blocks + // Depends on the previous test to generate blocks. it('should fetch block header by height', async () => { // fetch corresponding header and block const height = 7; @@ -492,13 +492,13 @@ describe('HTTP', function() { }); it('should fetch null for block header that does not exist', async () => { - // many blocks in the future + // Many blocks in the future. const header = await nclient.get(`/header/${40000}`); assert.equal(header, null); }); it('should have valid header chain', async () => { - // starting at the genesis block + // Starting at the genesis block. let prevBlock = '0000000000000000000000000000000000000000000000000000000000000000'; for (let i = 0; i < 10; i++) { const header = await nclient.get(`/header/${i}`);