From 8489cb1f4d198bb8dce3e218dbd9d99162c5e472 Mon Sep 17 00:00:00 2001 From: jingyi2811 Date: Tue, 27 Apr 2021 19:33:09 +0800 Subject: [PATCH] Add new getBlockHeader rpc (#163) * Add getBlockHeader rpc * Some minor fixes --- .../__tests__/category/blockchain.test.ts | 70 ++++++++++++++----- .../src/category/blockchain.ts | 41 +++++++++++ website/docs/jellyfish/api/blockchain.md | 28 ++++++++ 3 files changed, 120 insertions(+), 19 deletions(-) diff --git a/packages/jellyfish-api-core/__tests__/category/blockchain.test.ts b/packages/jellyfish-api-core/__tests__/category/blockchain.test.ts index f20d090215..b09fa5c7d4 100644 --- a/packages/jellyfish-api-core/__tests__/category/blockchain.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/blockchain.test.ts @@ -1,7 +1,7 @@ import { RegTestContainer, MasterNodeRegTestContainer } from '@defichain/testcontainers' import { ContainerAdapterClient } from '../container_adapter_client' import waitForExpect from 'wait-for-expect' -import { BigNumber, Block, MempoolTx, Transaction, WalletFlag } from '../../src' +import { BigNumber, Block, BlockHeader, MempoolTx, Transaction, WalletFlag } from '../../src' describe('non masternode', () => { const container = new RegTestContainer() @@ -57,11 +57,23 @@ describe('masternode', () => { await container.stop() }) + /** + * Wait for block hash to reach a certain height + */ + async function waitForBlockHash (height: number): Promise { + await waitForExpect(async () => { + const info = await client.blockchain.getBlockchainInfo() + expect(info.blocks).toBeGreaterThan(height) + }) + + return await client.blockchain.getBlockHash(height) + } + describe('getBlockchainInfo', () => { it('should getBlockchainInfo', async () => { await waitForExpect(async () => { const info = await client.blockchain.getBlockchainInfo() - await expect(info.blocks).toBeGreaterThan(1) + expect(info.blocks).toBeGreaterThan(1) }) const info = await client.blockchain.getBlockchainInfo() @@ -83,23 +95,10 @@ describe('masternode', () => { }) describe('getBlock', () => { - /** - * Wait for block hash to reach a certain height - */ - async function waitForBlockHash (height: number): Promise { - await waitForExpect(async () => { - const info = await client.blockchain.getBlockchainInfo() - await expect(info.blocks).toBeGreaterThan(height) - }) - - return await client.blockchain.getBlockHash(height) - } - it('should getBlock with verbosity 0 and return just a string that is serialized, hex-encoded data for block', async () => { const blockHash = await waitForBlockHash(1) const hash: string = await client.blockchain.getBlock(blockHash, 0) - - expect(hash).not.toBeNull() + expect(typeof hash).toBe('string') }) it('should getBlock with verbosity 1 and return block with tx as hex', async () => { @@ -157,15 +156,48 @@ describe('masternode', () => { }) }) + describe('getBlockHeader', () => { + it('should getBlockHeader with verbosity true and return block with tx as hex', async () => { + const blockHash = await waitForBlockHash(1) + const blockHeader: BlockHeader = await client.blockchain.getBlockHeader(blockHash, true) + + expect(blockHeader.hash.length).toBe(64) + + expect(blockHeader.confirmations).toBeGreaterThanOrEqual(2) + expect(blockHeader.height).toBeGreaterThanOrEqual(1) + + expect(blockHeader.version).toBeGreaterThanOrEqual(536870912) + expect(blockHeader.versionHex).toStrictEqual('20000000') + expect(blockHeader.merkleroot.length).toBe(64) + + expect(blockHeader.time).toBeGreaterThan(1) + expect(blockHeader.mediantime).toBeGreaterThan(1) + + expect(blockHeader.bits).toStrictEqual('207fffff') + expect(blockHeader.difficulty).toBeGreaterThan(0) + + expect(blockHeader.chainwork.length).toBe(64) + expect(blockHeader.nTx).toBeGreaterThanOrEqual(1) + expect(blockHeader.previousblockhash.length).toBe(64) + expect(blockHeader.nextblockhash.length).toBe(64) + }) + + it('should getBlockHeader with verbosity false and return a string that is serialized, hex-encoded data for block header', async () => { + const blockHash = await waitForBlockHash(1) + const hash: string = await client.blockchain.getBlockHeader(blockHash, false) + expect(typeof hash).toBe('string') + }) + }) + describe('getBlockHash', () => { it('should getBlockHash', async () => { await waitForExpect(async () => { const info = await client.blockchain.getBlockchainInfo() - await expect(info.blocks).toBeGreaterThan(1) + expect(info.blocks).toBeGreaterThan(1) }) const blockHash: string = await client.blockchain.getBlockHash(1) - expect(blockHash).not.toBeNull() + expect(typeof blockHash).toBe('string') expect(blockHash.length).toBe(64) }) }) @@ -174,7 +206,7 @@ describe('masternode', () => { it('should getBlockCount', async () => { await waitForExpect(async () => { const info = await client.blockchain.getBlockchainInfo() - await expect(info.blocks).toBeGreaterThan(1) + expect(info.blocks).toBeGreaterThan(1) }) const blockCount: number = await client.blockchain.getBlockCount() diff --git a/packages/jellyfish-api-core/src/category/blockchain.ts b/packages/jellyfish-api-core/src/category/blockchain.ts index 321ca0105b..097798b6d0 100644 --- a/packages/jellyfish-api-core/src/category/blockchain.ts +++ b/packages/jellyfish-api-core/src/category/blockchain.ts @@ -73,6 +73,30 @@ export class Blockchain { return await this.client.call('getblock', [hash, verbosity], 'number') } + /** + * Get block header data with particular header hash. + * Returns an Object with information for block header. + * + * @param {string} hash of the block + * @param {boolean} verbosity true + * @return {Promise} + */ + getBlockHeader (hash: string, verbosity: true): Promise + + /** + * Get block header data with particular header hash. + * Returns a string that is serialized, hex-encoded data for block header. + * + * @param {string} hash of the block + * @param {boolean} verbosity false + * @return {Promise} + */ + getBlockHeader (hash: string, verbosity: false): Promise + + async getBlockHeader (hash: string, verbosity: boolean): Promise { + return await this.client.call('getblockheader', [hash, verbosity], 'number') + } + /** * Get details of unspent transaction output (UTXO). * @@ -167,6 +191,23 @@ export interface Block { nextblockhash: string } +export interface BlockHeader { + hash: string + confirmations: number + height: number + version: number + versionHex: string + merkleroot: string + time: number + mediantime: number + bits: string + difficulty: number + chainwork: string + nTx: number + previousblockhash: string + nextblockhash: string +} + export interface Transaction { txid: string hash: string diff --git a/website/docs/jellyfish/api/blockchain.md b/website/docs/jellyfish/api/blockchain.md index ad97b5a0bd..2eb52a66fd 100644 --- a/website/docs/jellyfish/api/blockchain.md +++ b/website/docs/jellyfish/api/blockchain.md @@ -121,6 +121,34 @@ interface Vout { } ``` +## getBlockHeader + +Get block header data with particular header hash. + +```ts title="client.blockchain.getBlockHeader()" +interface blockchain { + getBlockHeader (hash: string, verbosity: true): Promise + getBlockHeader (hash: string, verbosity: false): Promise +} + +interface BlockHeader { + hash: string + confirmations: number + height: number + version: number + versionHex: string + merkleroot: string + time: number + mediantime: number + bits: string + difficulty: number + chainwork: string + nTx: number + previousblockhash: string + nextblockhash: string +} +``` + ## getBlockHash Get a hash of block in best-block-chain at height provided.