mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
core/evm: less iteration in blockhash
This commit is contained in:
parent
c616dcf111
commit
3b7d48e881
1 changed files with 23 additions and 14 deletions
37
core/evm.go
37
core/evm.go
|
|
@ -60,24 +60,33 @@ func NewEVMContext(msg Message, header *types.Header, chain ChainContext, author
|
|||
|
||||
// GetHashFn returns a GetHashFunc which retrieves header hashes by number
|
||||
func GetHashFn(ref *types.Header, chain ChainContext) func(n uint64) common.Hash {
|
||||
var cache map[uint64]common.Hash
|
||||
|
||||
// Cache will initially contain [refHash.parent],
|
||||
// Then fill up with [refHash.p, refHash.pp, refHash.ppp, ...]
|
||||
var cache []common.Hash
|
||||
|
||||
return func(n uint64) common.Hash {
|
||||
// If there's no hash cache yet, make one
|
||||
if cache == nil {
|
||||
cache = map[uint64]common.Hash{
|
||||
ref.Number.Uint64() - 1: ref.ParentHash,
|
||||
if len(cache) == 0 {
|
||||
cache = append(cache, ref.ParentHash)
|
||||
}
|
||||
if idx := ref.Number.Uint64() - n - 1; idx < uint64(len(cache)) {
|
||||
return cache[idx]
|
||||
}
|
||||
// No luck in the cache, but we can start iterating from the last element we already know
|
||||
lastKnownHash := cache[len(cache)-1]
|
||||
lastKnownNumber := ref.Number.Uint64() - uint64(len(cache))
|
||||
|
||||
for {
|
||||
header := chain.GetHeader(lastKnownHash, lastKnownNumber)
|
||||
if header == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
// Try to fulfill the request from the cache
|
||||
if hash, ok := cache[n]; ok {
|
||||
return hash
|
||||
}
|
||||
// Not cached, iterate the blocks and cache the hashes
|
||||
for header := chain.GetHeader(ref.ParentHash, ref.Number.Uint64()-1); header != nil; header = chain.GetHeader(header.ParentHash, header.Number.Uint64()-1) {
|
||||
cache[header.Number.Uint64()-1] = header.ParentHash
|
||||
if n == header.Number.Uint64()-1 {
|
||||
return header.ParentHash
|
||||
cache = append(cache, header.ParentHash)
|
||||
lastKnownHash = header.ParentHash
|
||||
lastKnownNumber = header.Number.Uint64() - 1
|
||||
if n == lastKnownNumber {
|
||||
return lastKnownHash
|
||||
}
|
||||
}
|
||||
return common.Hash{}
|
||||
|
|
|
|||
Loading…
Reference in a new issue