mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-03-02 17:43:48 +00:00
core: special case on creation for eof code
This commit is contained in:
parent
d744516b74
commit
d23c5e5e62
5 changed files with 13 additions and 5 deletions
|
|
@ -17,6 +17,7 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/big"
|
||||
|
|
@ -444,10 +445,15 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
|
|||
vmerr error // vm errors do not effect consensus and are therefore not assigned to err
|
||||
)
|
||||
if contractCreation {
|
||||
ret, _, st.gasRemaining, vmerr = st.evm.Create(sender, msg.Data, st.gasRemaining, value)
|
||||
ret, _, st.gasRemaining, vmerr = st.evm.Create(sender, msg.Data, st.gasRemaining, value, rules.IsPrague)
|
||||
// Special case for EOF, if the initcode or deployed code is
|
||||
// invalid, the tx is considered valid (so update nonce), but
|
||||
// gas for initcode execution is not consumed.
|
||||
// Only intrinsic creation transaction costs are charged.
|
||||
if errors.Is(vmerr, vm.ErrInvalidEOFInitcode) {
|
||||
st.state.SetNonce(msg.From, st.state.GetNonce(sender.Address())+1)
|
||||
}
|
||||
} else {
|
||||
// Increment the nonce for the next transaction
|
||||
st.state.SetNonce(msg.From, st.state.GetNonce(sender.Address())+1)
|
||||
ret, st.gasRemaining, vmerr = st.evm.Call(sender, st.to(), msg.Data, st.gasRemaining, value)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ var (
|
|||
ErrReturnDataOutOfBounds = errors.New("return data out of bounds")
|
||||
ErrGasUintOverflow = errors.New("gas uint64 overflow")
|
||||
ErrInvalidCode = errors.New("invalid code: must not begin with 0xef")
|
||||
ErrInvalidEOFInitcode = errors.New("invalid eof initcode")
|
||||
ErrNonceUintOverflow = errors.New("nonce uint64 overflow")
|
||||
|
||||
// errStopToken is an internal token indicating interpreter loop termination,
|
||||
|
|
|
|||
|
|
@ -564,7 +564,7 @@ func (evm *EVM) initNewContract(contract *Contract, address common.Address, valu
|
|||
}
|
||||
|
||||
// Create creates a new contract using code as deployment code.
|
||||
func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
|
||||
func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *uint256.Int, allowEOF bool) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
|
||||
contractAddr = crypto.CreateAddress(caller.Address(), evm.StateDB.GetNonce(caller.Address()))
|
||||
return evm.create(caller, &codeAndHash{code: code}, gas, value, contractAddr, CREATE)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -682,7 +682,7 @@ func opCreate(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]b
|
|||
|
||||
scope.Contract.UseGas(gas, interpreter.evm.Config.Tracer, 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
|
||||
// rule) and treat as an error, if the ruleset is frontier we must
|
||||
|
|
|
|||
|
|
@ -184,6 +184,7 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
|
|||
input,
|
||||
cfg.GasLimit,
|
||||
uint256.MustFromBig(cfg.Value),
|
||||
rules.IsPrague,
|
||||
)
|
||||
return code, address, leftOverGas, err
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue