diff --git a/blockchain/chain.go b/blockchain/chain.go index 58d7256d..960e2807 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.