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 returns the header corresponding to the hash/number argument pair.
|
||||||
GetHeader(common.Hash, uint64) *types.Header
|
GetHeader(common.Hash, uint64) *types.Header
|
||||||
|
|
||||||
|
Config() *params.ChainConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewEVMBlockContext creates a new context for use in the EVM.
|
// 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{}
|
return common.Hash{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the cache if it is within 256 blocks from the head.
|
var eip2935Ancestor *types.Header
|
||||||
if n >= ref.Number.Uint64()-256 {
|
|
||||||
// If there's no hash cache yet, make one
|
// 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 {
|
if len(cache) == 0 {
|
||||||
cache = append(cache, ref.ParentHash)
|
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]
|
lastKnownHash := cache[len(cache)-1]
|
||||||
lastKnownNumber := ref.Number.Uint64() - uint64(len(cache))
|
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)
|
header := chain.GetHeader(lastKnownHash, lastKnownNumber)
|
||||||
if header == nil {
|
if header == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
if lastKnownNumber == n {
|
||||||
|
eip2935Ancestor = header
|
||||||
|
}
|
||||||
cache = append(cache, header.ParentHash)
|
cache = append(cache, header.ParentHash)
|
||||||
lastKnownHash = header.ParentHash
|
lastKnownHash = header.ParentHash
|
||||||
lastKnownNumber = header.Number.Uint64() - 1
|
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
|
var key common.Hash
|
||||||
binary.BigEndian.PutUint64(key[24:], n)
|
binary.BigEndian.PutUint64(key[24:], n)
|
||||||
return statedb.GetState(params.HistoryStorageAddress, key)
|
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{}
|
return common.Hash{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -247,6 +247,14 @@ func (d *dummyChain) GetHeader(h common.Hash, n uint64) *types.Header {
|
||||||
return fakeHeader(n, parentHash)
|
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
|
// TestBlockhash tests the blockhash operation. It's a bit special, since it internally
|
||||||
// requires access to a chain reader.
|
// requires access to a chain reader.
|
||||||
func TestBlockhash(t *testing.T) {
|
func TestBlockhash(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -1043,6 +1043,7 @@ func (diff *BlockOverrides) Apply(blockCtx *vm.BlockContext) {
|
||||||
type ChainContextBackend interface {
|
type ChainContextBackend interface {
|
||||||
Engine() consensus.Engine
|
Engine() consensus.Engine
|
||||||
HeaderByNumber(context.Context, rpc.BlockNumber) (*types.Header, error)
|
HeaderByNumber(context.Context, rpc.BlockNumber) (*types.Header, error)
|
||||||
|
ChainConfig() *params.ChainConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChainContext is an implementation of core.ChainContext. It's main use-case
|
// 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
|
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) {
|
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 {
|
if err := overrides.Apply(state); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue