Skip to content

Commit

Permalink
core/vm: clean up contract creation error handling (#6475)
Browse files Browse the repository at this point in the history
Cherry-pick ethereum/go-ethereum#22766.

Do not keep separate flag for "max code size exceeded" case, but instead
assign appropriate error for it sooner.

Co-authored-by: Paweł Bylica <chfast@gmail.com>
  • Loading branch information
yperbasis and chfast authored Dec 30, 2022
1 parent 3ebd597 commit a369fd0
Showing 1 changed file with 7 additions and 12 deletions.
19 changes: 7 additions & 12 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -384,19 +384,19 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
ret, err = run(evm, contract, nil, false)

// check whether the max code size has been exceeded
maxCodeSizeExceeded := evm.chainRules.IsSpuriousDragon && len(ret) > params.MaxCodeSize && !evm.chainRules.IsAura
if err == nil && evm.chainRules.IsSpuriousDragon && len(ret) > params.MaxCodeSize && !evm.chainRules.IsAura {
err = ErrMaxCodeSizeExceeded
}

// Reject code starting with 0xEF if EIP-3541 is enabled.
if err == nil && !maxCodeSizeExceeded {
if evm.chainRules.IsLondon && len(ret) >= 1 && ret[0] == 0xEF {
err = ErrInvalidCode
}
if err == nil && evm.chainRules.IsLondon && len(ret) >= 1 && ret[0] == 0xEF {
err = ErrInvalidCode
}
// if the contract creation ran successfully and no errors were returned
// calculate the gas required to store the code. If the code could not
// be stored due to not enough gas set an error and let it be handled
// by the error checking condition below.
if err == nil && !maxCodeSizeExceeded {
if err == nil {
createDataGas := uint64(len(ret)) * params.CreateDataGas
if contract.UseGas(createDataGas) {
evm.intraBlockState.SetCode(address, ret)
Expand All @@ -408,16 +408,12 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
// 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.
if maxCodeSizeExceeded || (err != nil && (evm.chainRules.IsHomestead || err != ErrCodeStoreOutOfGas)) {
if err != nil && (evm.chainRules.IsHomestead || err != ErrCodeStoreOutOfGas) {
evm.intraBlockState.RevertToSnapshot(snapshot)
if err != ErrExecutionReverted {
contract.UseGas(contract.Gas)
}
}
// Assign err if contract code size exceeds the max while the err is still empty.
if maxCodeSizeExceeded && err == nil {
err = ErrMaxCodeSizeExceeded
}

if evm.config.Debug {
if evm.depth == 0 {
Expand All @@ -428,7 +424,6 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
}

return ret, address, contract.Gas, err

}

// Create creates a new contract using code as deployment code.
Expand Down

0 comments on commit a369fd0

Please sign in to comment.