What changed, and why it matters
This commit adds a new internal bookkeeping structure called bestHeader to btcd's blockchain tracking. It mirrors the existing bestChain view but is intended to track headers separately from full blocks. There is no visible security fix or vulnerability being patched; it appears to be preparatory refactoring for a later change in how new blocks are announced.
No security action required. Treat as normal refactoring/infrastructure change. Review subsequent commits that actually consume bestHeader to ensure header-chain logic does not introduce validation or DoS issues.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch introduces a second chainView, bestHeader, alongside bestChain in the BlockChain struct. It initializes the new view in New() and keeps its tip synchronized with bestChain in createChainState() and initChainState(). The commit message states this is needed because the node will receive headers for new block announcements instead of inventory (inv) messages. No logic changes affecting validation, consensus rules, or resource limits are present in the diff.
Changed components
blockchain/chain.goblockchain/chainio.goInspect captured patch +10 / −3
diff --git a/blockchain/chain.go b/blockchain/chain.go
index 952d0bc..48af310 100644
--- a/blockchain/chain.go
+++ b/blockchain/chain.go
@@ -128,8 +128,12 @@ type BlockChain struct {
//
// bestChain tracks the current active chain by making use of an
// efficient chain view into the block index.
- index *blockIndex
- bestChain *chainView
+ //
+ // bestHeader tracks the current active header chain. The tip is the last
+ // header we have on the block index.
+ index *blockIndex
+ bestChain *chainView
+ bestHeader *chainView
// The UTXO state holds a cached view of the UTXO state of the chain.
// It is protected by the chain lock.
@@ -2188,6 +2192,7 @@ func New(config *Config) (*BlockChain, error) {
utxoCache: newUtxoCache(config.DB, config.UtxoCacheMaxSize),
hashCache: config.HashCache,
bestChain: newChainView(nil),
+ bestHeader: newChainView(nil),
orphans: make(map[chainhash.Hash]*orphanBlock),
prevOrphans: make(map[chainhash.Hash][]*orphanBlock),
warningCaches: newThresholdCaches(vbNumBits),
diff --git a/blockchain/chainio.go b/blockchain/chainio.go
index 27028ea..e85f581 100644
--- a/blockchain/chainio.go
+++ b/blockchain/chainio.go
@@ -1079,6 +1079,7 @@ func (b *BlockChain) createChainState() error {
node := newBlockNode(header, nil)
node.status = statusDataStored | statusValid
b.bestChain.SetTip(node)
+ b.bestHeader.SetTip(node)
// Add the new node to the index which is used for faster lookups.
b.index.addNode(node)
@@ -1262,13 +1263,14 @@ func (b *BlockChain) initChainState() error {
i++
}
- // Set the best chain view to the stored best state.
+ // Set the best chain view and the best header to the stored best state.
tip := b.index.LookupNode(&state.hash)
if tip == nil {
return AssertError(fmt.Sprintf("initChainState: cannot find "+
"chain tip %s in block index", state.hash))
}
b.bestChain.SetTip(tip)
+ b.bestHeader.SetTip(tip)
// Load the raw block bytes for the best block.
blockBytes, err := dbTx.FetchBlock(&state.hash)
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.