core/vm: port to config2

This commit is contained in:
Felix Lange 2025-08-06 23:41:04 +02:00
parent ee78ae4172
commit 0101ffeee9
9 changed files with 85 additions and 74 deletions

View file

@ -37,6 +37,7 @@ import (
"github.com/ethereum/go-ethereum/crypto/kzg4844" "github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/ethereum/go-ethereum/crypto/secp256r1" "github.com/ethereum/go-ethereum/crypto/secp256r1"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/params/forks"
"golang.org/x/crypto/ripemd160" "golang.org/x/crypto/ripemd160"
) )
@ -206,21 +207,21 @@ func init() {
} }
} }
func activePrecompiledContracts(rules params.Rules) PrecompiledContracts { func activePrecompiledContracts(rules params.Rules2) PrecompiledContracts {
switch { switch {
case rules.IsVerkle: case rules.Active(forks.Verkle):
return PrecompiledContractsVerkle return PrecompiledContractsVerkle
case rules.IsOsaka: case rules.Active(forks.Osaka):
return PrecompiledContractsOsaka return PrecompiledContractsOsaka
case rules.IsPrague: case rules.Active(forks.Prague):
return PrecompiledContractsPrague return PrecompiledContractsPrague
case rules.IsCancun: case rules.Active(forks.Cancun):
return PrecompiledContractsCancun return PrecompiledContractsCancun
case rules.IsBerlin: case rules.Active(forks.Berlin):
return PrecompiledContractsBerlin return PrecompiledContractsBerlin
case rules.IsIstanbul: case rules.Active(forks.Istanbul):
return PrecompiledContractsIstanbul return PrecompiledContractsIstanbul
case rules.IsByzantium: case rules.Active(forks.Byzantium):
return PrecompiledContractsByzantium return PrecompiledContractsByzantium
default: default:
return PrecompiledContractsHomestead return PrecompiledContractsHomestead
@ -228,7 +229,7 @@ func activePrecompiledContracts(rules params.Rules) PrecompiledContracts {
} }
// ActivePrecompiledContracts returns a copy of precompiled contracts enabled with the current configuration. // ActivePrecompiledContracts returns a copy of precompiled contracts enabled with the current configuration.
func ActivePrecompiledContracts(rules params.Rules) PrecompiledContracts { func ActivePrecompiledContracts(rules params.Rules2) PrecompiledContracts {
return maps.Clone(activePrecompiledContracts(rules)) return maps.Clone(activePrecompiledContracts(rules))
} }

View file

@ -109,7 +109,7 @@ func enable1344(jt *JumpTable) {
// opChainID implements CHAINID opcode // opChainID implements CHAINID opcode
func opChainID(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { func opChainID(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
chainId, _ := uint256.FromBig(interpreter.evm.chainConfig.ChainID) chainId, _ := uint256.FromBig(params.ChainID.Get(interpreter.evm.chainConfig))
scope.Stack.push(chainId) scope.Stack.push(chainId)
return nil, nil return nil, nil
} }

View file

@ -27,6 +27,7 @@ import (
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/params/forks"
"github.com/holiman/uint256" "github.com/holiman/uint256"
) )
@ -99,10 +100,10 @@ type EVM struct {
depth int depth int
// chainConfig contains information about the current chain // chainConfig contains information about the current chain
chainConfig *params.ChainConfig chainConfig *params.Config2
// chain rules contains the chain rules for the current epoch // chain rules contains the chain rules for the current epoch
chainRules params.Rules chainRules params.Rules2
// virtual machine configuration options used to initialise the evm // virtual machine configuration options used to initialise the evm
Config Config Config Config
@ -130,13 +131,18 @@ type EVM struct {
// database and several configs. It meant to be used throughout the entire // database and several configs. It meant to be used throughout the entire
// state transition of a block, with the transaction context switched as // state transition of a block, with the transaction context switched as
// needed by calling evm.SetTxContext. // needed by calling evm.SetTxContext.
func NewEVM(blockCtx BlockContext, statedb StateDB, chainConfig *params.ChainConfig, config Config) *EVM { func NewEVM(blockCtx BlockContext, statedb StateDB, chainConfig *params.Config2, config Config) *EVM {
blocknum := uint64(0)
if blockCtx.BlockNumber != nil {
blocknum = blockCtx.BlockNumber.Uint64()
}
evm := &EVM{ evm := &EVM{
Context: blockCtx, Context: blockCtx,
StateDB: statedb, StateDB: statedb,
Config: config, Config: config,
chainConfig: chainConfig, chainConfig: chainConfig,
chainRules: chainConfig.Rules(blockCtx.BlockNumber, blockCtx.Random != nil, blockCtx.Time), chainRules: chainConfig.Rules(blocknum, blockCtx.Time),
jumpDests: newMapJumpDests(), jumpDests: newMapJumpDests(),
} }
evm.precompiles = activePrecompiledContracts(evm.chainRules) evm.precompiles = activePrecompiledContracts(evm.chainRules)
@ -159,7 +165,7 @@ func (evm *EVM) SetJumpDestCache(jumpDests JumpDestCache) {
// SetTxContext resets the EVM with a new transaction context. // SetTxContext resets the EVM with a new transaction context.
// This is not threadsafe and should only be done very cautiously. // This is not threadsafe and should only be done very cautiously.
func (evm *EVM) SetTxContext(txCtx TxContext) { func (evm *EVM) SetTxContext(txCtx TxContext) {
if evm.chainRules.IsEIP4762 { if evm.chainRules.Active(forks.Verkle) {
txCtx.AccessEvents = state.NewAccessEvents(evm.StateDB.PointCache()) txCtx.AccessEvents = state.NewAccessEvents(evm.StateDB.PointCache())
} }
evm.TxContext = txCtx evm.TxContext = txCtx
@ -209,7 +215,7 @@ func (evm *EVM) Call(caller common.Address, addr common.Address, input []byte, g
p, isPrecompile := evm.precompile(addr) p, isPrecompile := evm.precompile(addr)
if !evm.StateDB.Exist(addr) { if !evm.StateDB.Exist(addr) {
if !isPrecompile && evm.chainRules.IsEIP4762 && !isSystemCall(caller) { if !isPrecompile && evm.chainRules.Active(forks.Verkle) && !isSystemCall(caller) {
// Add proof of absence to witness // Add proof of absence to witness
// At this point, the read costs have already been charged, either because this // At this point, the read costs have already been charged, either because this
// is a direct tx call, in which case it's covered by the intrinsic gas, or because // is a direct tx call, in which case it's covered by the intrinsic gas, or because
@ -225,7 +231,7 @@ func (evm *EVM) Call(caller common.Address, addr common.Address, input []byte, g
gas -= wgas gas -= wgas
} }
if !isPrecompile && evm.chainRules.IsEIP158 && value.IsZero() { if !isPrecompile && evm.chainRules.Active(forks.SpuriousDragon) && value.IsZero() {
// Calling a non-existing account, don't do anything. // Calling a non-existing account, don't do anything.
return nil, gas, nil return nil, gas, nil
} }
@ -442,7 +448,7 @@ func (evm *EVM) create(caller common.Address, code []byte, gas uint64, value *ui
evm.StateDB.SetNonce(caller, nonce+1, tracing.NonceChangeContractCreator) evm.StateDB.SetNonce(caller, nonce+1, tracing.NonceChangeContractCreator)
// Charge the contract creation init gas in verkle mode // Charge the contract creation init gas in verkle mode
if evm.chainRules.IsEIP4762 { if evm.chainRules.Active(forks.Verkle) {
statelessGas := evm.AccessEvents.ContractCreatePreCheckGas(address, gas) statelessGas := evm.AccessEvents.ContractCreatePreCheckGas(address, gas)
if statelessGas > gas { if statelessGas > gas {
return nil, common.Address{}, 0, ErrOutOfGas return nil, common.Address{}, 0, ErrOutOfGas
@ -455,7 +461,7 @@ func (evm *EVM) create(caller common.Address, code []byte, gas uint64, value *ui
// We add this to the access list _before_ taking a snapshot. Even if the // We add this to the access list _before_ taking a snapshot. Even if the
// creation fails, the access-list change should not be rolled back. // creation fails, the access-list change should not be rolled back.
if evm.chainRules.IsEIP2929 { if evm.chainRules.Active(forks.Berlin) && !evm.chainRules.Active(forks.Verkle) {
evm.StateDB.AddAddressToAccessList(address) evm.StateDB.AddAddressToAccessList(address)
} }
// Ensure there's no existing contract already at the designated address. // Ensure there's no existing contract already at the designated address.
@ -486,11 +492,11 @@ func (evm *EVM) create(caller common.Address, code []byte, gas uint64, value *ui
// acts inside that account. // acts inside that account.
evm.StateDB.CreateContract(address) evm.StateDB.CreateContract(address)
if evm.chainRules.IsEIP158 { if evm.chainRules.Active(forks.SpuriousDragon) {
evm.StateDB.SetNonce(address, 1, tracing.NonceChangeNewContract) evm.StateDB.SetNonce(address, 1, tracing.NonceChangeNewContract)
} }
// Charge the contract creation init gas in verkle mode // Charge the contract creation init gas in verkle mode
if evm.chainRules.IsEIP4762 { if evm.chainRules.Active(forks.Verkle) {
consumed, wanted := evm.AccessEvents.ContractCreateInitGas(address, gas) consumed, wanted := evm.AccessEvents.ContractCreateInitGas(address, gas)
if consumed < wanted { if consumed < wanted {
return nil, common.Address{}, 0, ErrOutOfGas return nil, common.Address{}, 0, ErrOutOfGas
@ -512,7 +518,7 @@ func (evm *EVM) create(caller common.Address, code []byte, gas uint64, value *ui
contract.IsDeployment = true contract.IsDeployment = true
ret, err = evm.initNewContract(contract, address) ret, err = evm.initNewContract(contract, address)
if err != nil && (evm.chainRules.IsHomestead || err != ErrCodeStoreOutOfGas) { if err != nil && (evm.chainRules.Active(forks.Homestead) || err != ErrCodeStoreOutOfGas) {
evm.StateDB.RevertToSnapshot(snapshot) evm.StateDB.RevertToSnapshot(snapshot)
if err != ErrExecutionReverted { if err != ErrExecutionReverted {
contract.UseGas(contract.Gas, evm.Config.Tracer, tracing.GasChangeCallFailedExecution) contract.UseGas(contract.Gas, evm.Config.Tracer, tracing.GasChangeCallFailedExecution)
@ -530,16 +536,16 @@ func (evm *EVM) initNewContract(contract *Contract, address common.Address) ([]b
} }
// Check whether the max code size has been exceeded, assign err if the case. // Check whether the max code size has been exceeded, assign err if the case.
if evm.chainRules.IsEIP158 && len(ret) > params.MaxCodeSize { if evm.chainRules.Active(forks.SpuriousDragon) && len(ret) > params.MaxCodeSize {
return ret, ErrMaxCodeSizeExceeded return ret, ErrMaxCodeSizeExceeded
} }
// Reject code starting with 0xEF if EIP-3541 is enabled. // Reject code starting with 0xEF if EIP-3541 is enabled.
if len(ret) >= 1 && ret[0] == 0xEF && evm.chainRules.IsLondon { if len(ret) >= 1 && ret[0] == 0xEF && evm.chainRules.Active(forks.London) {
return ret, ErrInvalidCode return ret, ErrInvalidCode
} }
if !evm.chainRules.IsEIP4762 { if !evm.chainRules.Active(forks.Verkle) {
createDataGas := uint64(len(ret)) * params.CreateDataGas createDataGas := uint64(len(ret)) * params.CreateDataGas
if !contract.UseGas(createDataGas, evm.Config.Tracer, tracing.GasChangeCallCodeStorage) { if !contract.UseGas(createDataGas, evm.Config.Tracer, tracing.GasChangeCallCodeStorage) {
return ret, ErrCodeStoreOutOfGas return ret, ErrCodeStoreOutOfGas
@ -576,7 +582,7 @@ func (evm *EVM) Create2(caller common.Address, code []byte, gas uint64, endowmen
// Prague, it can also resolve code pointed to by a delegation designator. // Prague, it can also resolve code pointed to by a delegation designator.
func (evm *EVM) resolveCode(addr common.Address) []byte { func (evm *EVM) resolveCode(addr common.Address) []byte {
code := evm.StateDB.GetCode(addr) code := evm.StateDB.GetCode(addr)
if !evm.chainRules.IsPrague { if !evm.chainRules.Active(forks.Prague) {
return code return code
} }
if target, ok := types.ParseDelegation(code); ok { if target, ok := types.ParseDelegation(code); ok {
@ -591,7 +597,7 @@ func (evm *EVM) resolveCode(addr common.Address) []byte {
// delegation designator. Although this is not accessible in the EVM it is used // delegation designator. Although this is not accessible in the EVM it is used
// internally to associate jumpdest analysis to code. // internally to associate jumpdest analysis to code.
func (evm *EVM) resolveCodeHash(addr common.Address) common.Hash { func (evm *EVM) resolveCodeHash(addr common.Address) common.Hash {
if evm.chainRules.IsPrague { if evm.chainRules.Active(forks.Prague) {
code := evm.StateDB.GetCode(addr) code := evm.StateDB.GetCode(addr)
if target, ok := types.ParseDelegation(code); ok { if target, ok := types.ParseDelegation(code); ok {
// Note we only follow one level of delegation. // Note we only follow one level of delegation.
@ -602,7 +608,7 @@ func (evm *EVM) resolveCodeHash(addr common.Address) common.Hash {
} }
// ChainConfig returns the environment's chain configuration // ChainConfig returns the environment's chain configuration
func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig } func (evm *EVM) ChainConfig() *params.Config2 { return evm.chainConfig }
func (evm *EVM) captureBegin(depth int, typ OpCode, from common.Address, to common.Address, input []byte, startGas uint64, value *big.Int) { func (evm *EVM) captureBegin(depth int, typ OpCode, from common.Address, to common.Address, input []byte, startGas uint64, value *big.Int) {
tracer := evm.Config.Tracer tracer := evm.Config.Tracer
@ -623,7 +629,7 @@ func (evm *EVM) captureEnd(depth int, startGas uint64, leftOverGas uint64, ret [
if err != nil { if err != nil {
reverted = true reverted = true
} }
if !evm.chainRules.IsHomestead && errors.Is(err, ErrCodeStoreOutOfGas) { if !evm.chainRules.Active(forks.Homestead) && errors.Is(err, ErrCodeStoreOutOfGas) {
reverted = false reverted = false
} }
if tracer.OnExit != nil { if tracer.OnExit != nil {

View file

@ -23,6 +23,7 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/params/forks"
) )
// memoryGasCost calculates the quadratic gas for memory expansion. It does so // memoryGasCost calculates the quadratic gas for memory expansion. It does so
@ -104,7 +105,7 @@ func gasSStore(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySi
// The legacy gas metering only takes into consideration the current state // The legacy gas metering only takes into consideration the current state
// Legacy rules should be applied if we are in Petersburg (removal of EIP-1283) // Legacy rules should be applied if we are in Petersburg (removal of EIP-1283)
// OR Constantinople is not active // OR Constantinople is not active
if evm.chainRules.IsPetersburg || !evm.chainRules.IsConstantinople { if evm.chainRules.Active(forks.Petersburg) || !evm.chainRules.Active(forks.Constantinople) {
// This checks for 3 scenarios and calculates gas accordingly: // This checks for 3 scenarios and calculates gas accordingly:
// //
// 1. From a zero-value address to a non-zero value (NEW VALUE) // 1. From a zero-value address to a non-zero value (NEW VALUE)
@ -374,14 +375,14 @@ func gasCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize
transfersValue = !stack.Back(2).IsZero() transfersValue = !stack.Back(2).IsZero()
address = common.Address(stack.Back(1).Bytes20()) address = common.Address(stack.Back(1).Bytes20())
) )
if evm.chainRules.IsEIP158 { if evm.chainRules.Active(forks.SpuriousDragon) {
if transfersValue && evm.StateDB.Empty(address) { if transfersValue && evm.StateDB.Empty(address) {
gas += params.CallNewAccountGas gas += params.CallNewAccountGas
} }
} else if !evm.StateDB.Exist(address) { } else if !evm.StateDB.Exist(address) {
gas += params.CallNewAccountGas gas += params.CallNewAccountGas
} }
if transfersValue && !evm.chainRules.IsEIP4762 { if transfersValue && !evm.chainRules.Active(forks.Verkle) {
gas += params.CallValueTransferGas gas += params.CallValueTransferGas
} }
memoryGas, err := memoryGasCost(mem, memorySize) memoryGas, err := memoryGasCost(mem, memorySize)
@ -393,7 +394,7 @@ func gasCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize
return 0, ErrGasUintOverflow return 0, ErrGasUintOverflow
} }
evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, gas, stack.Back(0)) evm.callGasTemp, err = callGas(evm.chainRules.Active(forks.TangerineWhistle), contract.Gas, gas, stack.Back(0))
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -413,13 +414,13 @@ func gasCallCode(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memory
gas uint64 gas uint64
overflow bool overflow bool
) )
if stack.Back(2).Sign() != 0 && !evm.chainRules.IsEIP4762 { if stack.Back(2).Sign() != 0 && !evm.chainRules.Active(forks.Verkle) {
gas += params.CallValueTransferGas gas += params.CallValueTransferGas
} }
if gas, overflow = math.SafeAdd(gas, memoryGas); overflow { if gas, overflow = math.SafeAdd(gas, memoryGas); overflow {
return 0, ErrGasUintOverflow return 0, ErrGasUintOverflow
} }
evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, gas, stack.Back(0)) evm.callGasTemp, err = callGas(evm.chainRules.Active(forks.TangerineWhistle), contract.Gas, gas, stack.Back(0))
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -434,7 +435,7 @@ func gasDelegateCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, me
if err != nil { if err != nil {
return 0, err return 0, err
} }
evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, gas, stack.Back(0)) evm.callGasTemp, err = callGas(evm.chainRules.Active(forks.TangerineWhistle), contract.Gas, gas, stack.Back(0))
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -450,7 +451,7 @@ func gasStaticCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memo
if err != nil { if err != nil {
return 0, err return 0, err
} }
evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, gas, stack.Back(0)) evm.callGasTemp, err = callGas(evm.chainRules.Active(forks.TangerineWhistle), contract.Gas, gas, stack.Back(0))
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -464,11 +465,11 @@ func gasStaticCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memo
func gasSelfdestruct(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { func gasSelfdestruct(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
var gas uint64 var gas uint64
// EIP150 homestead gas reprice fork: // EIP150 homestead gas reprice fork:
if evm.chainRules.IsEIP150 { if evm.chainRules.Active(forks.TangerineWhistle) {
gas = params.SelfdestructGasEIP150 gas = params.SelfdestructGasEIP150
var address = common.Address(stack.Back(0).Bytes20()) var address = common.Address(stack.Back(0).Bytes20())
if evm.chainRules.IsEIP158 { if evm.chainRules.Active(forks.SpuriousDragon) {
// if empty and transfers value // if empty and transfers value
if evm.StateDB.Empty(address) && evm.StateDB.GetBalance(contract.Address()).Sign() != 0 { if evm.StateDB.Empty(address) && evm.StateDB.GetBalance(contract.Address()).Sign() != 0 {
gas += params.CreateBySelfdestructGas gas += params.CreateBySelfdestructGas

View file

@ -28,7 +28,7 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params/presets"
"github.com/holiman/uint256" "github.com/holiman/uint256"
) )
@ -95,7 +95,7 @@ func TestEIP2200(t *testing.T) {
CanTransfer: func(StateDB, common.Address, *uint256.Int) bool { return true }, CanTransfer: func(StateDB, common.Address, *uint256.Int) bool { return true },
Transfer: func(StateDB, common.Address, common.Address, *uint256.Int) {}, Transfer: func(StateDB, common.Address, common.Address, *uint256.Int) {},
} }
evm := NewEVM(vmctx, statedb, params.AllEthashProtocolChanges, Config{ExtraEips: []int{2200}}) evm := NewEVM(vmctx, statedb, presets.AllEthashProtocolChanges, Config{ExtraEips: []int{2200}})
_, gas, err := evm.Call(common.Address{}, address, nil, tt.gaspool, new(uint256.Int)) _, gas, err := evm.Call(common.Address{}, address, nil, tt.gaspool, new(uint256.Int))
if !errors.Is(err, tt.failure) { if !errors.Is(err, tt.failure) {
@ -151,7 +151,7 @@ func TestCreateGas(t *testing.T) {
config.ExtraEips = []int{3860} config.ExtraEips = []int{3860}
} }
evm := NewEVM(vmctx, statedb, params.AllEthashProtocolChanges, config) evm := NewEVM(vmctx, statedb, presets.AllEthashProtocolChanges, config)
var startGas = uint64(testGas) var startGas = uint64(testGas)
ret, gas, err := evm.Call(common.Address{}, address, nil, startGas, new(uint256.Int)) ret, gas, err := evm.Call(common.Address{}, address, nil, startGas, new(uint256.Int))
if err != nil { if err != nil {

View file

@ -23,6 +23,7 @@ import (
"github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/tracing"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/params/forks"
"github.com/holiman/uint256" "github.com/holiman/uint256"
) )
@ -663,7 +664,7 @@ func opCreate(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]b
input = scope.Memory.GetCopy(offset.Uint64(), size.Uint64()) input = scope.Memory.GetCopy(offset.Uint64(), size.Uint64())
gas = scope.Contract.Gas gas = scope.Contract.Gas
) )
if interpreter.evm.chainRules.IsEIP150 { if interpreter.evm.chainRules.Active(forks.TangerineWhistle) {
gas -= gas / 64 gas -= gas / 64
} }
@ -677,7 +678,7 @@ func opCreate(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]b
// homestead we must check for CodeStoreOutOfGasError (homestead only // homestead we must check for CodeStoreOutOfGasError (homestead only
// rule) and treat as an error, if the ruleset is frontier we must // rule) and treat as an error, if the ruleset is frontier we must
// ignore this error and pretend the operation was successful. // ignore this error and pretend the operation was successful.
if interpreter.evm.chainRules.IsHomestead && suberr == ErrCodeStoreOutOfGas { if interpreter.evm.chainRules.Active(forks.Homestead) && suberr == ErrCodeStoreOutOfGas {
stackvalue.Clear() stackvalue.Clear()
} else if suberr != nil && suberr != ErrCodeStoreOutOfGas { } else if suberr != nil && suberr != ErrCodeStoreOutOfGas {
stackvalue.Clear() stackvalue.Clear()

View file

@ -30,7 +30,7 @@ import (
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params/presets"
"github.com/holiman/uint256" "github.com/holiman/uint256"
) )
@ -96,7 +96,7 @@ func init() {
func testTwoOperandOp(t *testing.T, tests []TwoOperandTestcase, opFn executionFunc, name string) { func testTwoOperandOp(t *testing.T, tests []TwoOperandTestcase, opFn executionFunc, name string) {
var ( var (
evm = NewEVM(BlockContext{}, nil, params.TestChainConfig, Config{}) evm = NewEVM(BlockContext{}, nil, presets.TestChainConfig, Config{})
stack = newstack() stack = newstack()
pc = uint64(0) pc = uint64(0)
) )
@ -194,7 +194,7 @@ func TestSAR(t *testing.T) {
func TestAddMod(t *testing.T) { func TestAddMod(t *testing.T) {
var ( var (
evm = NewEVM(BlockContext{}, nil, params.TestChainConfig, Config{}) evm = NewEVM(BlockContext{}, nil, presets.TestChainConfig, Config{})
stack = newstack() stack = newstack()
pc = uint64(0) pc = uint64(0)
) )
@ -237,7 +237,7 @@ func TestWriteExpectedValues(t *testing.T) {
// getResult is a convenience function to generate the expected values // getResult is a convenience function to generate the expected values
getResult := func(args []*twoOperandParams, opFn executionFunc) []TwoOperandTestcase { getResult := func(args []*twoOperandParams, opFn executionFunc) []TwoOperandTestcase {
var ( var (
evm = NewEVM(BlockContext{}, nil, params.TestChainConfig, Config{}) evm = NewEVM(BlockContext{}, nil, presets.TestChainConfig, Config{})
stack = newstack() stack = newstack()
pc = uint64(0) pc = uint64(0)
) )
@ -281,7 +281,7 @@ func TestJsonTestcases(t *testing.T) {
func opBenchmark(bench *testing.B, op executionFunc, args ...string) { func opBenchmark(bench *testing.B, op executionFunc, args ...string) {
var ( var (
evm = NewEVM(BlockContext{}, nil, params.TestChainConfig, Config{}) evm = NewEVM(BlockContext{}, nil, presets.TestChainConfig, Config{})
stack = newstack() stack = newstack()
scope = &ScopeContext{nil, stack, nil} scope = &ScopeContext{nil, stack, nil}
) )
@ -519,7 +519,7 @@ func BenchmarkOpIsZero(b *testing.B) {
func TestOpMstore(t *testing.T) { func TestOpMstore(t *testing.T) {
var ( var (
evm = NewEVM(BlockContext{}, nil, params.TestChainConfig, Config{}) evm = NewEVM(BlockContext{}, nil, presets.TestChainConfig, Config{})
stack = newstack() stack = newstack()
mem = NewMemory() mem = NewMemory()
) )
@ -542,7 +542,7 @@ func TestOpMstore(t *testing.T) {
func BenchmarkOpMstore(bench *testing.B) { func BenchmarkOpMstore(bench *testing.B) {
var ( var (
evm = NewEVM(BlockContext{}, nil, params.TestChainConfig, Config{}) evm = NewEVM(BlockContext{}, nil, presets.TestChainConfig, Config{})
stack = newstack() stack = newstack()
mem = NewMemory() mem = NewMemory()
) )
@ -562,7 +562,7 @@ func BenchmarkOpMstore(bench *testing.B) {
func TestOpTstore(t *testing.T) { func TestOpTstore(t *testing.T) {
var ( var (
statedb, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) statedb, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
evm = NewEVM(BlockContext{}, statedb, params.TestChainConfig, Config{}) evm = NewEVM(BlockContext{}, statedb, presets.TestChainConfig, Config{})
stack = newstack() stack = newstack()
mem = NewMemory() mem = NewMemory()
caller = common.Address{} caller = common.Address{}
@ -601,7 +601,7 @@ func TestOpTstore(t *testing.T) {
func BenchmarkOpKeccak256(bench *testing.B) { func BenchmarkOpKeccak256(bench *testing.B) {
var ( var (
evm = NewEVM(BlockContext{}, nil, params.TestChainConfig, Config{}) evm = NewEVM(BlockContext{}, nil, presets.TestChainConfig, Config{})
stack = newstack() stack = newstack()
mem = NewMemory() mem = NewMemory()
) )
@ -703,7 +703,7 @@ func TestRandom(t *testing.T) {
{name: "hash(0x010203)", random: crypto.Keccak256Hash([]byte{0x01, 0x02, 0x03})}, {name: "hash(0x010203)", random: crypto.Keccak256Hash([]byte{0x01, 0x02, 0x03})},
} { } {
var ( var (
evm = NewEVM(BlockContext{Random: &tt.random}, nil, params.TestChainConfig, Config{}) evm = NewEVM(BlockContext{Random: &tt.random}, nil, presets.TestChainConfig, Config{})
stack = newstack() stack = newstack()
pc = uint64(0) pc = uint64(0)
) )
@ -743,7 +743,7 @@ func TestBlobHash(t *testing.T) {
{name: "out-of-bounds (nil)", idx: 25, expect: zero, hashes: nil}, {name: "out-of-bounds (nil)", idx: 25, expect: zero, hashes: nil},
} { } {
var ( var (
evm = NewEVM(BlockContext{}, nil, params.TestChainConfig, Config{}) evm = NewEVM(BlockContext{}, nil, presets.TestChainConfig, Config{})
stack = newstack() stack = newstack()
pc = uint64(0) pc = uint64(0)
) )
@ -846,7 +846,7 @@ func TestOpMCopy(t *testing.T) {
}, },
} { } {
var ( var (
evm = NewEVM(BlockContext{}, nil, params.TestChainConfig, Config{}) evm = NewEVM(BlockContext{}, nil, presets.TestChainConfig, Config{})
stack = newstack() stack = newstack()
pc = uint64(0) pc = uint64(0)
) )
@ -974,7 +974,7 @@ func TestPush(t *testing.T) {
} }
func TestOpCLZ(t *testing.T) { func TestOpCLZ(t *testing.T) {
evm := NewEVM(BlockContext{}, nil, params.TestChainConfig, Config{}) evm := NewEVM(BlockContext{}, nil, presets.TestChainConfig, Config{})
tests := []struct { tests := []struct {
inputHex string inputHex string

View file

@ -24,6 +24,7 @@ import (
"github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/tracing"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params/forks"
"github.com/holiman/uint256" "github.com/holiman/uint256"
) )
@ -106,34 +107,34 @@ func NewEVMInterpreter(evm *EVM) *EVMInterpreter {
// If jump table was not initialised we set the default one. // If jump table was not initialised we set the default one.
var table *JumpTable var table *JumpTable
switch { switch {
case evm.chainRules.IsOsaka: case evm.chainRules.Active(forks.Osaka):
table = &osakaInstructionSet table = &osakaInstructionSet
case evm.chainRules.IsVerkle: case evm.chainRules.Active(forks.Verkle):
// TODO replace with proper instruction set when fork is specified // TODO replace with proper instruction set when fork is specified
table = &verkleInstructionSet table = &verkleInstructionSet
case evm.chainRules.IsPrague: case evm.chainRules.Active(forks.Prague):
table = &pragueInstructionSet table = &pragueInstructionSet
case evm.chainRules.IsCancun: case evm.chainRules.Active(forks.Cancun):
table = &cancunInstructionSet table = &cancunInstructionSet
case evm.chainRules.IsShanghai: case evm.chainRules.Active(forks.Shanghai):
table = &shanghaiInstructionSet table = &shanghaiInstructionSet
case evm.chainRules.IsMerge: case evm.chainRules.Active(forks.Paris):
table = &mergeInstructionSet table = &mergeInstructionSet
case evm.chainRules.IsLondon: case evm.chainRules.Active(forks.London):
table = &londonInstructionSet table = &londonInstructionSet
case evm.chainRules.IsBerlin: case evm.chainRules.Active(forks.Berlin):
table = &berlinInstructionSet table = &berlinInstructionSet
case evm.chainRules.IsIstanbul: case evm.chainRules.Active(forks.Istanbul):
table = &istanbulInstructionSet table = &istanbulInstructionSet
case evm.chainRules.IsConstantinople: case evm.chainRules.Active(forks.Constantinople):
table = &constantinopleInstructionSet table = &constantinopleInstructionSet
case evm.chainRules.IsByzantium: case evm.chainRules.Active(forks.Byzantium):
table = &byzantiumInstructionSet table = &byzantiumInstructionSet
case evm.chainRules.IsEIP158: case evm.chainRules.Active(forks.SpuriousDragon):
table = &spuriousDragonInstructionSet table = &spuriousDragonInstructionSet
case evm.chainRules.IsEIP150: case evm.chainRules.Active(forks.TangerineWhistle):
table = &tangerineWhistleInstructionSet table = &tangerineWhistleInstructionSet
case evm.chainRules.IsHomestead: case evm.chainRules.Active(forks.Homestead):
table = &homesteadInstructionSet table = &homesteadInstructionSet
default: default:
table = &frontierInstructionSet table = &frontierInstructionSet
@ -237,7 +238,7 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
logged, pcCopy, gasCopy = false, pc, contract.Gas logged, pcCopy, gasCopy = false, pc, contract.Gas
} }
if in.evm.chainRules.IsEIP4762 && !contract.IsDeployment && !contract.IsSystemCall { if in.evm.chainRules.Active(forks.Verkle) && !contract.IsDeployment && !contract.IsSystemCall {
// if the PC ends up in a new "chunk" of verkleized code, charge the // if the PC ends up in a new "chunk" of verkleized code, charge the
// associated costs. // associated costs.
contractAddr := contract.Address() contractAddr := contract.Address()

View file

@ -26,6 +26,7 @@ import (
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/params/presets"
"github.com/holiman/uint256" "github.com/holiman/uint256"
) )
@ -48,7 +49,7 @@ func TestLoopInterrupt(t *testing.T) {
statedb.SetCode(address, common.Hex2Bytes(tt)) statedb.SetCode(address, common.Hex2Bytes(tt))
statedb.Finalise(true) statedb.Finalise(true)
evm := NewEVM(vmctx, statedb, params.AllEthashProtocolChanges, Config{}) evm := NewEVM(vmctx, statedb, presets.AllEthashProtocolChanges, Config{})
errChannel := make(chan error) errChannel := make(chan error)
timeout := make(chan bool) timeout := make(chan bool)
@ -79,7 +80,7 @@ func TestLoopInterrupt(t *testing.T) {
func BenchmarkInterpreter(b *testing.B) { func BenchmarkInterpreter(b *testing.B) {
var ( var (
statedb, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) statedb, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
evm = NewEVM(BlockContext{BlockNumber: big.NewInt(1), Time: 1, Random: &common.Hash{}}, statedb, params.MergedTestChainConfig, Config{}) evm = NewEVM(BlockContext{BlockNumber: big.NewInt(1), Time: 1, Random: &common.Hash{}}, statedb, presets.MergedTestChainConfig, Config{})
startGas uint64 = 100_000_000 startGas uint64 = 100_000_000
value = uint256.NewInt(0) value = uint256.NewInt(0)
stack = newstack() stack = newstack()