mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
rewrite instruction to check if 256th ancestor passed shanghai
This commit is contained in:
parent
12770a1fa1
commit
78cce0e69d
3 changed files with 48 additions and 20 deletions
41
core/evm.go
41
core/evm.go
|
|
@ -36,6 +36,8 @@ type ChainContext interface {
|
|||
|
||||
// GetHeader returns the header corresponding to the hash/number argument pair.
|
||||
GetHeader(common.Hash, uint64) *types.Header
|
||||
|
||||
Config() *params.ChainConfig
|
||||
}
|
||||
|
||||
// NewEVMBlockContext creates a new context for use in the EVM.
|
||||
|
|
@ -103,39 +105,52 @@ func GetHashFn(ref *types.Header, chain ChainContext) vm.GetHashFunc {
|
|||
return common.Hash{}
|
||||
}
|
||||
|
||||
// Use the cache if it is within 256 blocks from the head.
|
||||
if n >= ref.Number.Uint64()-256 {
|
||||
// If there's no hash cache yet, make one
|
||||
var eip2935Ancestor *types.Header
|
||||
|
||||
// If there's no hash cache yet, make one and fill
|
||||
// it with all 256 hashes. We have to get all blocks
|
||||
// since for eip2935 we need to query the 256th
|
||||
// ancestor to find out if it had eip2935 enabled.
|
||||
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))
|
||||
limit := uint64(257)
|
||||
if ref.Number.Uint64() < limit {
|
||||
limit = ref.Number.Uint64()
|
||||
}
|
||||
|
||||
for {
|
||||
for ref.Number.Uint64()-lastKnownNumber < limit {
|
||||
header := chain.GetHeader(lastKnownHash, lastKnownNumber)
|
||||
if header == nil {
|
||||
break
|
||||
}
|
||||
if lastKnownNumber == n {
|
||||
eip2935Ancestor = header
|
||||
}
|
||||
cache = append(cache, header.ParentHash)
|
||||
lastKnownHash = header.ParentHash
|
||||
lastKnownNumber = header.Number.Uint64() - 1
|
||||
if n == lastKnownNumber {
|
||||
return lastKnownHash
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if eip2935 {
|
||||
|
||||
// Check if the 256th ancestor had already activated eip 2935.
|
||||
// If the ancestor is nil, then this is the case of a testnet
|
||||
// that forked within 256 blocks of the genesis.
|
||||
if eip2935Ancestor != nil && chain.Config().IsPrague(eip2935Ancestor.Number, eip2935Ancestor.Time) {
|
||||
var key common.Hash
|
||||
binary.BigEndian.PutUint64(key[24:], n)
|
||||
return statedb.GetState(params.HistoryStorageAddress, key)
|
||||
}
|
||||
|
||||
// if the 256th ancestor did not have eip2935 enabled, try
|
||||
// to get the value from the cache.
|
||||
if idx := ref.Number.Uint64() - n - 1; idx < uint64(len(cache)) {
|
||||
return cache[idx]
|
||||
}
|
||||
|
||||
// something went wrong while building the cache
|
||||
return common.Hash{}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -247,6 +247,14 @@ func (d *dummyChain) GetHeader(h common.Hash, n uint64) *types.Header {
|
|||
return fakeHeader(n, parentHash)
|
||||
}
|
||||
|
||||
func (d *dummyChain) Config() *params.ChainConfig {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *dummyChain) GetHeaderByNumber(n uint64) *types.Header {
|
||||
return d.GetHeader(common.Hash{}, n)
|
||||
}
|
||||
|
||||
// TestBlockhash tests the blockhash operation. It's a bit special, since it internally
|
||||
// requires access to a chain reader.
|
||||
func TestBlockhash(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -1043,6 +1043,7 @@ func (diff *BlockOverrides) Apply(blockCtx *vm.BlockContext) {
|
|||
type ChainContextBackend interface {
|
||||
Engine() consensus.Engine
|
||||
HeaderByNumber(context.Context, rpc.BlockNumber) (*types.Header, error)
|
||||
ChainConfig() *params.ChainConfig
|
||||
}
|
||||
|
||||
// ChainContext is an implementation of core.ChainContext. It's main use-case
|
||||
|
|
@ -1071,6 +1072,10 @@ func (context *ChainContext) GetHeader(hash common.Hash, number uint64) *types.H
|
|||
return header
|
||||
}
|
||||
|
||||
func (context *ChainContext) Config() *params.ChainConfig {
|
||||
return context.b.ChainConfig()
|
||||
}
|
||||
|
||||
func doCall(ctx context.Context, b Backend, args TransactionArgs, state *state.StateDB, header *types.Header, overrides *StateOverride, blockOverrides *BlockOverrides, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) {
|
||||
if err := overrides.Apply(state); err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
Loading…
Reference in a new issue