mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-24 13:46:43 +00:00
core/vm: port to config2
This commit is contained in:
parent
ee78ae4172
commit
0101ffeee9
9 changed files with 85 additions and 74 deletions
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue