From f470bf0fe82b7bb7c175b0d80a8bc71c61d1d2a4 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Wed, 1 Aug 2018 16:50:56 -0700 Subject: [PATCH] blockchain: Backport optimize exported header access. backport of https://github.com/decred/dcrd/pull/1273 Notable difference being that btcd mainline currenlty doesn't have a blockchain/blockindex_test.go file, so those changes are omitted. Great work @davecgh :) --- blockchain/chain.go | 26 +++++++++----------------- rpcserver.go | 8 ++++---- 2 files changed, 13 insertions(+), 21 deletions(-) diff --git a/blockchain/chain.go b/blockchain/chain.go index c13fabd9..c49d728b 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -1242,25 +1242,17 @@ func (b *BlockChain) BestSnapshot() *BestState { return snapshot } -// FetchHeader returns the block header identified by the given hash or an error -// if it doesn't exist. -func (b *BlockChain) FetchHeader(hash *chainhash.Hash) (wire.BlockHeader, error) { - // Reconstruct the header from the block index if possible. - if node := b.index.LookupNode(hash); node != nil { - return node.Header(), nil - } - - // Fall back to loading it from the database. - var header *wire.BlockHeader - err := b.db.View(func(dbTx database.Tx) error { - var err error - header, err = dbFetchHeaderByHash(dbTx, hash) - return err - }) - if err != nil { +// HeaderByHash returns the block header identified by the given hash or an +// error if it doesn't exist. Note that this will return headers from both the +// main and side chains. +func (b *BlockChain) HeaderByHash(hash *chainhash.Hash) (wire.BlockHeader, error) { + node := b.index.LookupNode(hash) + if node == nil { + err := fmt.Errorf("block %s is not known", hash) return wire.BlockHeader{}, err } - return *header, nil + + return node.Header(), nil } // MainChainHasBlock returns whether or not the block with the given hash is in diff --git a/rpcserver.go b/rpcserver.go index e3f6430f..8475ef57 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -1320,7 +1320,7 @@ func handleGetBlockHeader(s *rpcServer, cmd interface{}, closeChan <-chan struct if err != nil { return nil, rpcDecodeHexError(c.Hash) } - blockHeader, err := s.cfg.Chain.FetchHeader(hash) + blockHeader, err := s.cfg.Chain.HeaderByHash(hash) if err != nil { return nil, &btcjson.RPCError{ Code: btcjson.ErrRPCBlockNotFound, @@ -2442,7 +2442,7 @@ func handleGetNetworkHashPS(s *rpcServer, cmd interface{}, closeChan <-chan stru } // Fetch the header from chain. - header, err := s.cfg.Chain.FetchHeader(hash) + header, err := s.cfg.Chain.HeaderByHash(hash) if err != nil { context := "Failed to fetch block header" return nil, internalRPCError(err.Error(), context) @@ -2634,7 +2634,7 @@ func handleGetRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan str var chainHeight int32 if blkHash != nil { // Fetch the header from chain. - header, err := s.cfg.Chain.FetchHeader(blkHash) + header, err := s.cfg.Chain.HeaderByHash(blkHash) if err != nil { context := "Failed to fetch block header" return nil, internalRPCError(err.Error(), context) @@ -3262,7 +3262,7 @@ func handleSearchRawTransactions(s *rpcServer, cmd interface{}, closeChan <-chan var blkHeight int32 if blkHash := rtx.blkHash; blkHash != nil { // Fetch the header from chain. - header, err := s.cfg.Chain.FetchHeader(blkHash) + header, err := s.cfg.Chain.HeaderByHash(blkHash) if err != nil { return nil, &btcjson.RPCError{ Code: btcjson.ErrRPCBlockNotFound,