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 :)
This commit is contained in:
Conner Fromknecht 2018-08-01 16:50:56 -07:00
parent 9a2f952402
commit f470bf0fe8
No known key found for this signature in database
GPG key ID: E7D737B67FA592C7
2 changed files with 13 additions and 21 deletions

View file

@ -1242,25 +1242,17 @@ func (b *BlockChain) BestSnapshot() *BestState {
return snapshot return snapshot
} }
// FetchHeader returns the block header identified by the given hash or an error // HeaderByHash returns the block header identified by the given hash or an
// if it doesn't exist. // error if it doesn't exist. Note that this will return headers from both the
func (b *BlockChain) FetchHeader(hash *chainhash.Hash) (wire.BlockHeader, error) { // main and side chains.
// Reconstruct the header from the block index if possible. func (b *BlockChain) HeaderByHash(hash *chainhash.Hash) (wire.BlockHeader, error) {
if node := b.index.LookupNode(hash); node != nil { node := b.index.LookupNode(hash)
return node.Header(), nil if node == nil {
} err := fmt.Errorf("block %s is not known", hash)
// 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 {
return wire.BlockHeader{}, err return wire.BlockHeader{}, err
} }
return *header, nil
return node.Header(), nil
} }
// MainChainHasBlock returns whether or not the block with the given hash is in // MainChainHasBlock returns whether or not the block with the given hash is in

View file

@ -1320,7 +1320,7 @@ func handleGetBlockHeader(s *rpcServer, cmd interface{}, closeChan <-chan struct
if err != nil { if err != nil {
return nil, rpcDecodeHexError(c.Hash) return nil, rpcDecodeHexError(c.Hash)
} }
blockHeader, err := s.cfg.Chain.FetchHeader(hash) blockHeader, err := s.cfg.Chain.HeaderByHash(hash)
if err != nil { if err != nil {
return nil, &btcjson.RPCError{ return nil, &btcjson.RPCError{
Code: btcjson.ErrRPCBlockNotFound, Code: btcjson.ErrRPCBlockNotFound,
@ -2442,7 +2442,7 @@ func handleGetNetworkHashPS(s *rpcServer, cmd interface{}, closeChan <-chan stru
} }
// Fetch the header from chain. // Fetch the header from chain.
header, err := s.cfg.Chain.FetchHeader(hash) header, err := s.cfg.Chain.HeaderByHash(hash)
if err != nil { if err != nil {
context := "Failed to fetch block header" context := "Failed to fetch block header"
return nil, internalRPCError(err.Error(), context) return nil, internalRPCError(err.Error(), context)
@ -2634,7 +2634,7 @@ func handleGetRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan str
var chainHeight int32 var chainHeight int32
if blkHash != nil { if blkHash != nil {
// Fetch the header from chain. // Fetch the header from chain.
header, err := s.cfg.Chain.FetchHeader(blkHash) header, err := s.cfg.Chain.HeaderByHash(blkHash)
if err != nil { if err != nil {
context := "Failed to fetch block header" context := "Failed to fetch block header"
return nil, internalRPCError(err.Error(), context) return nil, internalRPCError(err.Error(), context)
@ -3262,7 +3262,7 @@ func handleSearchRawTransactions(s *rpcServer, cmd interface{}, closeChan <-chan
var blkHeight int32 var blkHeight int32
if blkHash := rtx.blkHash; blkHash != nil { if blkHash := rtx.blkHash; blkHash != nil {
// Fetch the header from chain. // Fetch the header from chain.
header, err := s.cfg.Chain.FetchHeader(blkHash) header, err := s.cfg.Chain.HeaderByHash(blkHash)
if err != nil { if err != nil {
return nil, &btcjson.RPCError{ return nil, &btcjson.RPCError{
Code: btcjson.ErrRPCBlockNotFound, Code: btcjson.ErrRPCBlockNotFound,