From d2ebc62d12912b2bcc44f733e6f29f9993016f25 Mon Sep 17 00:00:00 2001 From: Jan Pochyla Date: Wed, 6 Sep 2017 10:59:40 +0200 Subject: [PATCH] use getblockheader --- bitcoinrpc.go | 34 ++++++++++++++++++++-------------- blockbook.go | 12 +++++++++--- types.go | 7 +++++++ 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/bitcoinrpc.go b/bitcoinrpc.go index 02604488..3b38bc47 100644 --- a/bitcoinrpc.go +++ b/bitcoinrpc.go @@ -46,9 +46,9 @@ func (b *BitcoinRPC) ClearCache() { } // GetBlock returns information about the block with the given hash. -func (b *BitcoinRPC) GetBlock(hash string, height uint32) (block *Block, err error) { +func (b *BitcoinRPC) GetBlock(hash string) (block *Block, err error) { if b.Parser != nil { - return b.GetBlockAndParse(hash, height) + return b.GetBlockAndParse(hash) } else { return b.GetParsedBlock(hash) } @@ -57,8 +57,13 @@ func (b *BitcoinRPC) GetBlock(hash string, height uint32) (block *Block, err err // GetBlockAndParse returns information about the block with the given hash. // // It downloads raw block and parses it in-process. -func (b *BitcoinRPC) GetBlockAndParse(hash string, height uint32) (block *Block, err error) { +func (b *BitcoinRPC) GetBlockAndParse(hash string) (block *Block, err error) { log.Printf("rpc: getblock (verbose=false) %v", hash) + var header BlockHeader + err = b.client.Call("getblockheader", &header, hash) + if err != nil { + return + } var raw string err = b.client.Call("getblock", &raw, hash, false) // verbose=false if err != nil { @@ -70,8 +75,9 @@ func (b *BitcoinRPC) GetBlockAndParse(hash string, height uint32) (block *Block, } block, err = b.Parser.ParseBlock(data) if err == nil { - block.Hash = hash - block.Height = height + block.Hash = header.Hash + block.Height = header.Height + block.Next = header.Next } return } @@ -97,6 +103,13 @@ func (b *BitcoinRPC) GetParsedBlock(hash string) (block *Block, err error) { return } +// GetBestBlockHash returns hash of the tip of the best-block-chain. +func (b *BitcoinRPC) GetBestBlockHash() (hash string, err error) { + log.Printf("rpc: getbestblockhash") + err = b.client.Call("getbestblockhash", &hash) + return +} + // GetBlockHash returns hash of block in best-block-chain at given height. func (b *BitcoinRPC) GetBlockHash(height uint32) (hash string, err error) { log.Printf("rpc: getblockhash %v", height) @@ -104,15 +117,8 @@ func (b *BitcoinRPC) GetBlockHash(height uint32) (hash string, err error) { return } -// GetBlockCount returns the number of blocks in the longest chain. -func (b *BitcoinRPC) GetBlockCount() (count uint32, err error) { - log.Printf("rpc: getblockcount") - err = b.client.Call("getblockcount", &count) - return -} - -// GetRawTransaction returns the number of blocks in the longest chain. If the -// transaction cache is turned on, returned RawTx.Confirmations is stale. +// GetTransaction returns the number of blocks in the longest chain. If the +// transaction cache is turned on, returned Tx.Confirmations is stale. func (b *BitcoinRPC) GetTransaction(txid string) (tx *Tx, err error) { if b.txCache != nil { if cachedTx, ok := b.txCache.Get(txid); ok { diff --git a/blockbook.go b/blockbook.go index 84d7694e..73dda23e 100644 --- a/blockbook.go +++ b/blockbook.go @@ -11,8 +11,9 @@ type BlockParser interface { } type BlockOracle interface { + GetBestBlockHash() (string, error) GetBlockHash(height uint32) (string, error) - GetBlock(hash string, height uint32) (*Block, error) + GetBlock(hash string) (*Block, error) } type OutpointAddressOracle interface { @@ -177,17 +178,22 @@ type blockResult struct { func getBlocks(lower uint32, higher uint32, blocks BlockOracle, results chan<- blockResult) { defer close(results) - for height := lower; height <= higher; height++ { + + height := lower hash, err := blocks.GetBlockHash(height) if err != nil { results <- blockResult{err: err} return } - block, err := blocks.GetBlock(hash, height) + + for height <= higher { + block, err := blocks.GetBlock(hash) if err != nil { results <- blockResult{err: err} return } + hash = block.Next + height = block.Height + 1 results <- blockResult{block: block} } } diff --git a/types.go b/types.go index 8b1be566..6857480e 100644 --- a/types.go +++ b/types.go @@ -40,7 +40,14 @@ type Tx struct { type Block struct { Hash string `json:"hash"` + Next string `json:"nextblockhash"` Height uint32 `json:"height"` Txids []string `json:"tx"` Txs []*Tx `json:"_"` } + +type BlockHeader struct { + Hash string `json:"hash"` + Next string `json:"nextblockhash"` + Height uint32 `json:"height"` +}