From 3e4370964f6fa308aca97dc8e4906bb51c0d1cf7 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 23 Dec 2020 15:44:36 -0600 Subject: [PATCH] rpcserver: Update getblockchaininfo best header. This modifies the getblockchaininfo RPC handler to use the newly-exposed best header that is not known to be invalid from chain versus the height of the current best chain tip. --- internal/rpcserver/interface.go | 4 ++++ internal/rpcserver/rpcserver.go | 3 ++- internal/rpcserver/rpcserverhandlers_test.go | 9 +++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/internal/rpcserver/interface.go b/internal/rpcserver/interface.go index fbfe06269e..a1b0a7253e 100644 --- a/internal/rpcserver/interface.go +++ b/internal/rpcserver/interface.go @@ -236,6 +236,10 @@ type Chain interface { // treated as immutable since it is shared by all callers. BestSnapshot() *blockchain.BestState + // BestHeader returns the header with the most cumulative work that is NOT + // known to be invalid. + BestHeader() (chainhash.Hash, int64) + // BlockByHash returns the block for the given hash, regardless of whether the // block is part of the main chain or not. BlockByHash(hash *chainhash.Hash) (*dcrutil.Block, error) diff --git a/internal/rpcserver/rpcserver.go b/internal/rpcserver/rpcserver.go index c42b9020ab..cc9fe9992e 100644 --- a/internal/rpcserver/rpcserver.go +++ b/internal/rpcserver/rpcserver.go @@ -2018,6 +2018,7 @@ func handleGetBlock(_ context.Context, s *Server, cmd interface{}) (interface{}, func handleGetBlockchainInfo(_ context.Context, s *Server, cmd interface{}) (interface{}, error) { chain := s.cfg.Chain best := chain.BestSnapshot() + _, bestHeaderHeight := chain.BestHeader() // Fetch the current chain work using the the best block hash. chainWork, err := chain.ChainWork(&best.Hash) @@ -2087,7 +2088,7 @@ func handleGetBlockchainInfo(_ context.Context, s *Server, cmd interface{}) (int response := types.GetBlockChainInfoResult{ Chain: params.Name, Blocks: best.Height, - Headers: best.Height, + Headers: bestHeaderHeight, SyncHeight: syncHeight, ChainWork: fmt.Sprintf("%064x", chainWork), InitialBlockDownload: !chain.IsCurrent(), diff --git a/internal/rpcserver/rpcserverhandlers_test.go b/internal/rpcserver/rpcserverhandlers_test.go index e4151d5b5a..6eeeeba281 100644 --- a/internal/rpcserver/rpcserverhandlers_test.go +++ b/internal/rpcserver/rpcserverhandlers_test.go @@ -127,6 +127,8 @@ type tspendVotes struct { // testRPCChain provides a mock block chain by implementing the Chain interface. type testRPCChain struct { bestSnapshot *blockchain.BestState + bestHeaderHash chainhash.Hash + bestHeaderHeight int64 blockByHash *dcrutil.Block blockByHashErr error blockByHeight *dcrutil.Block @@ -193,6 +195,11 @@ func (c *testRPCChain) BestSnapshot() *blockchain.BestState { return c.bestSnapshot } +// BestHeader returns a mocked best header hash and height. +func (c *testRPCChain) BestHeader() (chainhash.Hash, int64) { + return c.bestHeaderHash, c.bestHeaderHeight +} + // BlockByHash returns a mocked block for the given hash. func (c *testRPCChain) BlockByHash(hash *chainhash.Hash) (*dcrutil.Block, error) { return c.blockByHash, c.blockByHashErr @@ -3495,6 +3502,8 @@ func TestHandleGetBlockchainInfo(t *testing.T) { Hash: *hash, PrevHash: *prevHash, } + chain.bestHeaderHash = *hash + chain.bestHeaderHeight = 463073 chain.chainWork = big.NewInt(0).SetBytes([]byte{0x11, 0x5d, 0x28, 0x33, 0x84, 0x90, 0x90, 0xb0, 0x02, 0x65, 0x06}) chain.isCurrent = false