core, eth, les: more efficient hash-based header chain retrieval (#16946)
This commit is contained in:
committed by
Péter Szilágyi
parent
0255951587
commit
049f5b3572
@ -307,6 +307,43 @@ func (hc *HeaderChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []co
|
||||
return chain
|
||||
}
|
||||
|
||||
// GetAncestor retrieves the Nth ancestor of a given block. It assumes that either the given block or
|
||||
// a close ancestor of it is canonical. maxNonCanonical points to a downwards counter limiting the
|
||||
// number of blocks to be individually checked before we reach the canonical chain.
|
||||
//
|
||||
// Note: ancestor == 0 returns the same block, 1 returns its parent and so on.
|
||||
func (hc *HeaderChain) GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64) {
|
||||
if ancestor > number {
|
||||
return common.Hash{}, 0
|
||||
}
|
||||
if ancestor == 1 {
|
||||
// in this case it is cheaper to just read the header
|
||||
if header := hc.GetHeader(hash, number); header != nil {
|
||||
return header.ParentHash, number - 1
|
||||
} else {
|
||||
return common.Hash{}, 0
|
||||
}
|
||||
}
|
||||
for ancestor != 0 {
|
||||
if rawdb.ReadCanonicalHash(hc.chainDb, number) == hash {
|
||||
number -= ancestor
|
||||
return rawdb.ReadCanonicalHash(hc.chainDb, number), number
|
||||
}
|
||||
if *maxNonCanonical == 0 {
|
||||
return common.Hash{}, 0
|
||||
}
|
||||
*maxNonCanonical--
|
||||
ancestor--
|
||||
header := hc.GetHeader(hash, number)
|
||||
if header == nil {
|
||||
return common.Hash{}, 0
|
||||
}
|
||||
hash = header.ParentHash
|
||||
number--
|
||||
}
|
||||
return hash, number
|
||||
}
|
||||
|
||||
// GetTd retrieves a block's total difficulty in the canonical chain from the
|
||||
// database by hash and number, caching it if found.
|
||||
func (hc *HeaderChain) GetTd(hash common.Hash, number uint64) *big.Int {
|
||||
|
Reference in New Issue
Block a user