From c554225b61575573ef3f6ae5953a9b2c0cd4d5e2 Mon Sep 17 00:00:00 2001 From: lupin012 <58134934+lupin012@users.noreply.github.com> Date: Fri, 19 Jul 2024 12:08:08 +0200 Subject: [PATCH 1/2] add support bailout on create --- core/state_transition.go | 2 +- core/vm/evm.go | 22 ++++++++++++---------- core/vm/instructions.go | 4 ++-- core/vm/runtime/runtime.go | 1 + 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/core/state_transition.go b/core/state_transition.go index a08fae912e6..511c3b91a7b 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -442,7 +442,7 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*evmtype // nonce to calculate the address of the contract that is being created // It does get incremented inside the `Create` call, after the computation // of the contract's address, but before the execution of the code. - ret, _, st.gasRemaining, vmerr = st.evm.Create(sender, st.data, st.gasRemaining, st.value) + ret, _, st.gasRemaining, vmerr = st.evm.Create(sender, st.data, st.gasRemaining, st.value, bailout) } else { // Increment the nonce for the next transaction st.state.SetNonce(msg.From(), st.state.GetNonce(sender.Address())+1) diff --git a/core/vm/evm.go b/core/vm/evm.go index 7a368e2c374..6b69193cc4c 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -350,11 +350,11 @@ func (c *codeAndHash) Hash() libcommon.Hash { } func (evm *EVM) OverlayCreate(caller ContractRef, codeAndHash *codeAndHash, gas uint64, value *uint256.Int, address libcommon.Address, typ OpCode, incrementNonce bool) ([]byte, libcommon.Address, uint64, error) { - return evm.create(caller, codeAndHash, gas, value, address, typ, incrementNonce) + return evm.create(caller, codeAndHash, gas, value, address, typ, incrementNonce, false) } // create creates a new contract using code as deployment code. -func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gasRemaining uint64, value *uint256.Int, address libcommon.Address, typ OpCode, incrementNonce bool) ([]byte, libcommon.Address, uint64, error) { +func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gasRemaining uint64, value *uint256.Int, address libcommon.Address, typ OpCode, incrementNonce bool, bailout bool) ([]byte, libcommon.Address, uint64, error) { var ret []byte var err error var gasConsumption uint64 @@ -381,8 +381,10 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gasRemainin return nil, libcommon.Address{}, gasRemaining, err } if !evm.Context.CanTransfer(evm.intraBlockState, caller.Address(), value) { - err = ErrInsufficientBalance - return nil, libcommon.Address{}, gasRemaining, err + if !bailout { + err = ErrInsufficientBalance + return nil, libcommon.Address{}, gasRemaining, err + } } if incrementNonce { nonce := evm.intraBlockState.GetNonce(caller.Address()) @@ -409,7 +411,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gasRemainin if evm.chainRules.IsSpuriousDragon { evm.intraBlockState.SetNonce(address, 1) } - evm.Context.Transfer(evm.intraBlockState, caller.Address(), address, value, false /* bailout */) + evm.Context.Transfer(evm.intraBlockState, caller.Address(), address, value, bailout) // Initialise a new contract and set the code that is to be used by the EVM. // The contract is a scoped environment for this execution context only. @@ -466,9 +468,9 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gasRemainin // Create creates a new contract using code as deployment code. // DESCRIBED: docs/programmers_guide/guide.md#nonce -func (evm *EVM) Create(caller ContractRef, code []byte, gasRemaining uint64, endowment *uint256.Int) (ret []byte, contractAddr libcommon.Address, leftOverGas uint64, err error) { +func (evm *EVM) Create(caller ContractRef, code []byte, gasRemaining uint64, endowment *uint256.Int, bailout bool) (ret []byte, contractAddr libcommon.Address, leftOverGas uint64, err error) { contractAddr = crypto.CreateAddress(caller.Address(), evm.intraBlockState.GetNonce(caller.Address())) - return evm.create(caller, &codeAndHash{code: code}, gasRemaining, endowment, contractAddr, CREATE, true /* incrementNonce */) + return evm.create(caller, &codeAndHash{code: code}, gasRemaining, endowment, contractAddr, CREATE, true /* incrementNonce */, bailout) } // Create2 creates a new contract using code as deployment code. @@ -476,16 +478,16 @@ func (evm *EVM) Create(caller ContractRef, code []byte, gasRemaining uint64, end // The different between Create2 with Create is Create2 uses keccak256(0xff ++ msg.sender ++ salt ++ keccak256(init_code))[12:] // instead of the usual sender-and-nonce-hash as the address where the contract is initialized at. // DESCRIBED: docs/programmers_guide/guide.md#nonce -func (evm *EVM) Create2(caller ContractRef, code []byte, gasRemaining uint64, endowment *uint256.Int, salt *uint256.Int) (ret []byte, contractAddr libcommon.Address, leftOverGas uint64, err error) { +func (evm *EVM) Create2(caller ContractRef, code []byte, gasRemaining uint64, endowment *uint256.Int, salt *uint256.Int, bailout bool) (ret []byte, contractAddr libcommon.Address, leftOverGas uint64, err error) { codeAndHash := &codeAndHash{code: code} contractAddr = crypto.CreateAddress2(caller.Address(), salt.Bytes32(), codeAndHash.Hash().Bytes()) - return evm.create(caller, codeAndHash, gasRemaining, endowment, contractAddr, CREATE2, true /* incrementNonce */) + return evm.create(caller, codeAndHash, gasRemaining, endowment, contractAddr, CREATE2, true /* incrementNonce */, bailout) } // SysCreate is a special (system) contract creation methods for genesis constructors. // Unlike the normal Create & Create2, it doesn't increment caller's nonce. func (evm *EVM) SysCreate(caller ContractRef, code []byte, gas uint64, endowment *uint256.Int, contractAddr libcommon.Address) (ret []byte, leftOverGas uint64, err error) { - ret, _, leftOverGas, err = evm.create(caller, &codeAndHash{code: code}, gas, endowment, contractAddr, CREATE, false /* incrementNonce */) + ret, _, leftOverGas, err = evm.create(caller, &codeAndHash{code: code}, gas, endowment, contractAddr, CREATE, false /* incrementNonce */, false) return } diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 4ccdd164aaf..247788fb0e2 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -660,7 +660,7 @@ func opCreate(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]b scope.Contract.UseGas(gas, tracing.GasChangeCallContractCreation) - res, addr, returnGas, suberr := interpreter.evm.Create(scope.Contract, input, gas, &value) + res, addr, returnGas, suberr := interpreter.evm.Create(scope.Contract, input, gas, &value, false) // Push item on the stack based on the returned error. If the ruleset is // homestead we must check for CodeStoreOutOfGasError (homestead only @@ -701,7 +701,7 @@ func opCreate2(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([] scope.Contract.UseGas(gas, tracing.GasChangeCallContractCreation2) // reuse size int for stackvalue stackValue := size - res, addr, returnGas, suberr := interpreter.evm.Create2(scope.Contract, input, gas, &endowment, &salt) + res, addr, returnGas, suberr := interpreter.evm.Create2(scope.Contract, input, gas, &endowment, &salt, false) // Push item on the stack based on the returned error. if suberr != nil { diff --git a/core/vm/runtime/runtime.go b/core/vm/runtime/runtime.go index 6bcc709fee0..91dce5944b2 100644 --- a/core/vm/runtime/runtime.go +++ b/core/vm/runtime/runtime.go @@ -233,6 +233,7 @@ func Create(input []byte, cfg *Config, blockNr uint64) ([]byte, libcommon.Addres input, cfg.GasLimit, cfg.Value, + false, ) return code, address, leftOverGas, err } From 9886968152c118b1af8f405158ddd0ed539cdbdc Mon Sep 17 00:00:00 2001 From: lupin012 <58134934+lupin012@users.noreply.github.com> Date: Fri, 19 Jul 2024 16:41:42 +0200 Subject: [PATCH 2/2] fix lint --- core/vm/runtime/runtime.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/vm/runtime/runtime.go b/core/vm/runtime/runtime.go index 91dce5944b2..8d89c474497 100644 --- a/core/vm/runtime/runtime.go +++ b/core/vm/runtime/runtime.go @@ -233,7 +233,7 @@ func Create(input []byte, cfg *Config, blockNr uint64) ([]byte, libcommon.Addres input, cfg.GasLimit, cfg.Value, - false, + false, ) return code, address, leftOverGas, err }