blockchain: add exports methods based on block header tip
What changed, and why it matters
This commit adds five new public read-only helper methods to btcd's blockchain package so other parts of the program can query the 'header chain' tip (the longest chain of block headers). The methods only expose information that was already tracked internally; they do not change any behavior, permissions, or validation rules. There is no indication this fixes a bug or closes a security hole.
No security action required. Review as a normal API addition; consider whether the new exported methods expose any internal state that callers should not trust without further validation, but the change itself is not a vulnerability.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch exports five accessor methods on *BlockChain: BestHeader, IsValidHeader, LatestBlockLocatorByHeader, HeaderHashByHeight, and HeaderHeightByHash. All of them read existing index/header-chain state under the existing chainLock or via the existing index.LookupNode/bestHeader helpers. No state is mutated, no new locks are introduced, no consensus or DoS limits are changed, and no existing callers are modified. It is a pure API-surface expansion for downstream consumers.
Changed components
blockchain/chain.goInspect captured patch +57 / −0
diff --git a/blockchain/chain.go b/blockchain/chain.go
index 58d7256..960e280 100644
--- a/blockchain/chain.go
+++ b/blockchain/chain.go
@@ -1344,6 +1344,15 @@ func (b *BlockChain) BestSnapshot() *BestState {
return snapshot
}
+// BestHeader returns the hash and the height of the best header.
+func (b *BlockChain) BestHeader() (chainhash.Hash, int32) {
+ b.chainLock.RLock()
+ defer b.chainLock.RUnlock()
+
+ best := b.bestHeader.Tip()
+ return best.hash, best.height
+}
+
// TipStatus is the status of a chain tip.
type TipStatus byte
@@ -1535,6 +1544,54 @@ func (b *BlockChain) BlockHashByHeight(blockHeight int32) (*chainhash.Hash, erro
return &node.hash, nil
}
+// IsValidHeader checks that we've already checked that this header connects to the
+// chain of best headers and did not receive an invalid state.
+func (b *BlockChain) IsValidHeader(blockHash *chainhash.Hash) bool {
+ node := b.index.LookupNode(blockHash)
+ if node == nil || !b.bestHeader.Contains(node) {
+ return false
+ }
+
+ return !b.index.NodeStatus(node).KnownInvalid()
+}
+
+// LatestBlockLocatorByHeader returns a block locator for the latest known tip of the
+// header chain.
+//
+// This function is safe for concurrent access.
+func (b *BlockChain) LatestBlockLocatorByHeader() (BlockLocator, error) {
+ b.chainLock.RLock()
+ locator := b.bestHeader.BlockLocator(nil)
+ b.chainLock.RUnlock()
+ return locator, nil
+}
+
+// HeaderHashByHeight returns the block header's hash given its height.
+//
+// NOTE: If the blockNode at the given blockHeight is not included in the
+// bestHeader chain, the function will return an error indicating that the
+// blockHeight wasn't found.
+func (b *BlockChain) HeaderHashByHeight(blockHeight int32) (
+ *chainhash.Hash, error) {
+
+ node := b.bestHeader.NodeByHeight(blockHeight)
+ if node == nil || !b.bestHeader.Contains(node) {
+ return nil, fmt.Errorf("blockheight %v not found", blockHeight)
+ }
+
+ return &node.hash, nil
+}
+
+// HeaderHeightByHash returns the height of the header given its hash.
+func (b *BlockChain) HeaderHeightByHash(blockHash chainhash.Hash) (int32, error) {
+ node := b.index.LookupNode(&blockHash)
+ if node == nil || !b.bestHeader.Contains(node) {
+ return -1, fmt.Errorf("blockhash %v not found", blockHash)
+ }
+
+ return node.height, nil
+}
+
// HeightRange returns a range of block hashes for the given start and end
// heights. It is inclusive of the start height and exclusive of the end
// height. The end height will be limited to the current main chain height.
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.