From c1c1ba0f309726010d783df60bff6f9321fa4cc1 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 24 Jan 2025 16:35:43 +0100 Subject: [PATCH] core: change system call determination in EVM --- core/state_processor.go | 6 +++--- core/state_transition.go | 2 +- core/vm/evm.go | 22 +++++++++++++--------- core/vm/gas_table_test.go | 4 ++-- core/vm/instructions.go | 2 +- core/vm/interpreter.go | 4 ++-- core/vm/interpreter_test.go | 2 +- core/vm/runtime/runtime.go | 2 -- 8 files changed, 23 insertions(+), 21 deletions(-) diff --git a/core/state_processor.go b/core/state_processor.go index cc147569f8..902ff582e8 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -229,7 +229,7 @@ func ProcessBeaconBlockRoot(beaconRoot common.Hash, evm *vm.EVM) { } evm.SetTxContext(NewEVMTxContext(msg)) evm.StateDB.AddAddressToAccessList(params.BeaconRootsAddress) - _, _, _ = evm.Call(vm.AccountRef(msg.From), *msg.To, msg.Data, 30_000_000, common.U2560, true) + _, _, _ = evm.Call(vm.AccountRef(msg.From), *msg.To, msg.Data, 30_000_000, common.U2560) evm.StateDB.Finalise(true) } @@ -253,7 +253,7 @@ func ProcessParentBlockHash(prevHash common.Hash, evm *vm.EVM) { } evm.SetTxContext(NewEVMTxContext(msg)) evm.StateDB.AddAddressToAccessList(params.HistoryStorageAddress) - _, _, err := evm.Call(vm.AccountRef(msg.From), *msg.To, msg.Data, 30_000_000, common.U2560, true) + _, _, err := evm.Call(vm.AccountRef(msg.From), *msg.To, msg.Data, 30_000_000, common.U2560) if err != nil { panic(err) } @@ -292,7 +292,7 @@ func processRequestsSystemCall(requests *[][]byte, evm *vm.EVM, requestType byte } evm.SetTxContext(NewEVMTxContext(msg)) evm.StateDB.AddAddressToAccessList(addr) - ret, _, _ := evm.Call(vm.AccountRef(msg.From), *msg.To, msg.Data, 30_000_000, common.U2560, true) + ret, _, _ := evm.Call(vm.AccountRef(msg.From), *msg.To, msg.Data, 30_000_000, common.U2560) evm.StateDB.Finalise(true) if len(ret) == 0 { return // skip empty output diff --git a/core/state_transition.go b/core/state_transition.go index feb29ad2f2..b6203e6aae 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -484,7 +484,7 @@ func (st *stateTransition) execute() (*ExecutionResult, error) { } // Execute the transaction's call. - ret, st.gasRemaining, vmerr = st.evm.Call(sender, st.to(), msg.Data, st.gasRemaining, value, false) + ret, st.gasRemaining, vmerr = st.evm.Call(sender, st.to(), msg.Data, st.gasRemaining, value) } var gasRefund uint64 diff --git a/core/vm/evm.go b/core/vm/evm.go index 63aa7e34ce..431f2965ef 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -170,11 +170,15 @@ func (evm *EVM) Interpreter() *EVMInterpreter { return evm.interpreter } +func (evm *EVM) isSystemCall() bool { + return evm.TxContext.Origin == params.SystemAddress +} + // Call executes the contract associated with the addr with the given input as -// parameters. It also handles any necessary value transfer required and takes +// parameters. It also handles any necessary value transfer required and takse // the necessary steps to create accounts and reverses the state in case of an // execution error or failed value transfer. -func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *uint256.Int, isSyscall bool) (ret []byte, leftOverGas uint64, err error) { +func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *uint256.Int) (ret []byte, leftOverGas uint64, err error) { // Capture the tracer start/end events in debug mode if evm.Config.Tracer != nil { evm.captureBegin(evm.depth, CALL, caller.Address(), addr, input, gas, value.ToBig()) @@ -194,7 +198,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas p, isPrecompile := evm.precompile(addr) if !evm.StateDB.Exist(addr) { - if !isPrecompile && evm.chainRules.IsEIP4762 && !isSyscall { + if !isPrecompile && evm.chainRules.IsEIP4762 && !evm.isSystemCall() { // add proof of absence to witness wgas := evm.AccessEvents.AddAccount(addr, false) if gas < wgas { @@ -225,9 +229,9 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas // If the account has no code, we can abort here // The depth-check is already done, and precompiles handled above contract := NewContract(caller, AccountRef(addrCopy), value, gas) - contract.IsSystemCall = isSyscall + contract.IsSystemCall = evm.isSystemCall() contract.SetCallCode(&addrCopy, evm.resolveCodeHash(addrCopy), code) - ret, err = evm.interpreter.Run(contract, input, false, isSyscall) + ret, err = evm.interpreter.Run(contract, input, false) gas = contract.Gas } } @@ -287,7 +291,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, // The contract is a scoped environment for this execution context only. contract := NewContract(caller, AccountRef(caller.Address()), value, gas) contract.SetCallCode(&addrCopy, evm.resolveCodeHash(addrCopy), evm.resolveCode(addrCopy)) - ret, err = evm.interpreter.Run(contract, input, false, false) + ret, err = evm.interpreter.Run(contract, input, false) gas = contract.Gas } if err != nil { @@ -334,7 +338,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by // Initialise a new contract and make initialise the delegate values contract := NewContract(caller, AccountRef(caller.Address()), nil, gas).AsDelegate() contract.SetCallCode(&addrCopy, evm.resolveCodeHash(addrCopy), evm.resolveCode(addrCopy)) - ret, err = evm.interpreter.Run(contract, input, false, false) + ret, err = evm.interpreter.Run(contract, input, false) gas = contract.Gas } if err != nil { @@ -392,7 +396,7 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte // When an error was returned by the EVM or when setting the creation code // above we revert to the snapshot and consume any gas remaining. Additionally // when we're in Homestead this also counts for code storage gas errors. - ret, err = evm.interpreter.Run(contract, input, true, false) + ret, err = evm.interpreter.Run(contract, input, true) gas = contract.Gas } if err != nil { @@ -522,7 +526,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, // initNewContract runs a new contract's creation code, performs checks on the // resulting code that is to be deployed, and consumes necessary gas. func (evm *EVM) initNewContract(contract *Contract, address common.Address, value *uint256.Int) ([]byte, error) { - ret, err := evm.interpreter.Run(contract, nil, false, false) + ret, err := evm.interpreter.Run(contract, nil, false) if err != nil { return ret, err } diff --git a/core/vm/gas_table_test.go b/core/vm/gas_table_test.go index ab24dfac68..be86885261 100644 --- a/core/vm/gas_table_test.go +++ b/core/vm/gas_table_test.go @@ -97,7 +97,7 @@ func TestEIP2200(t *testing.T) { } evm := NewEVM(vmctx, statedb, params.AllEthashProtocolChanges, Config{ExtraEips: []int{2200}}) - _, gas, err := evm.Call(AccountRef(common.Address{}), address, nil, tt.gaspool, new(uint256.Int), false) + _, gas, err := evm.Call(AccountRef(common.Address{}), address, nil, tt.gaspool, new(uint256.Int)) if !errors.Is(err, tt.failure) { t.Errorf("test %d: failure mismatch: have %v, want %v", i, err, tt.failure) } @@ -153,7 +153,7 @@ func TestCreateGas(t *testing.T) { evm := NewEVM(vmctx, statedb, params.AllEthashProtocolChanges, config) var startGas = uint64(testGas) - ret, gas, err := evm.Call(AccountRef(common.Address{}), address, nil, startGas, new(uint256.Int), false) + ret, gas, err := evm.Call(AccountRef(common.Address{}), address, nil, startGas, new(uint256.Int)) if err != nil { return false } diff --git a/core/vm/instructions.go b/core/vm/instructions.go index de30def386..9b9a31a855 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -752,7 +752,7 @@ func opCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byt if !value.IsZero() { gas += params.CallStipend } - ret, returnGas, err := interpreter.evm.Call(scope.Contract, toAddr, args, gas, &value, false) + ret, returnGas, err := interpreter.evm.Call(scope.Contract, toAddr, args, gas, &value) if err != nil { temp.Clear() diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index 6eb20649c1..e3237936a0 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -159,7 +159,7 @@ func NewEVMInterpreter(evm *EVM) *EVMInterpreter { // It's important to note that any errors returned by the interpreter should be // considered a revert-and-consume-all-gas operation except for // ErrExecutionReverted which means revert-and-keep-gas-left. -func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly, isSyscall bool) (ret []byte, err error) { +func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (ret []byte, err error) { // Increment the call depth which is restricted to 1024 in.evm.depth++ defer func() { in.evm.depth-- }() @@ -233,7 +233,7 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly, isSysc logged, pcCopy, gasCopy = false, pc, contract.Gas } - if in.evm.chainRules.IsEIP4762 && !contract.IsDeployment && !isSyscall { + if in.evm.chainRules.IsEIP4762 && !contract.IsDeployment && !contract.IsSystemCall { // if the PC ends up in a new "chunk" of verkleized code, charge the // associated costs. contractAddr := contract.Address() diff --git a/core/vm/interpreter_test.go b/core/vm/interpreter_test.go index 9c928a4c72..cacad8f813 100644 --- a/core/vm/interpreter_test.go +++ b/core/vm/interpreter_test.go @@ -53,7 +53,7 @@ func TestLoopInterrupt(t *testing.T) { timeout := make(chan bool) go func(evm *EVM) { - _, _, err := evm.Call(AccountRef(common.Address{}), address, nil, math.MaxUint64, new(uint256.Int), false) + _, _, err := evm.Call(AccountRef(common.Address{}), address, nil, math.MaxUint64, new(uint256.Int)) errChannel <- err }(evm) diff --git a/core/vm/runtime/runtime.go b/core/vm/runtime/runtime.go index f11c4a6d85..2243e14b65 100644 --- a/core/vm/runtime/runtime.go +++ b/core/vm/runtime/runtime.go @@ -148,7 +148,6 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) { input, cfg.GasLimit, uint256.MustFromBig(cfg.Value), - false, ) if cfg.EVMConfig.Tracer != nil && cfg.EVMConfig.Tracer.OnTxEnd != nil { cfg.EVMConfig.Tracer.OnTxEnd(&types.Receipt{GasUsed: cfg.GasLimit - leftOverGas}, err) @@ -220,7 +219,6 @@ func Call(address common.Address, input []byte, cfg *Config) ([]byte, uint64, er input, cfg.GasLimit, uint256.MustFromBig(cfg.Value), - false, ) if cfg.EVMConfig.Tracer != nil && cfg.EVMConfig.Tracer.OnTxEnd != nil { cfg.EVMConfig.Tracer.OnTxEnd(&types.Receipt{GasUsed: cfg.GasLimit - leftOverGas}, err)