Skip to content

Commit

Permalink
core/vm: clean up contract creation error handling (ethereum#22766)
Browse files Browse the repository at this point in the history
Do not keep separate flag for "max code size exceeded" case, but instead
assign appropriate error for it sooner.
  • Loading branch information
chfast committed May 1, 2021
1 parent 8ff9810 commit 0e00ee4
Showing 1 changed file with 8 additions and 9 deletions.
17 changes: 8 additions & 9 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -463,13 +463,16 @@ 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.IsEIP158 && len(ret) > params.MaxCodeSize
// Check whether the max code size has been exceeded, assign err if the case.
if err == nil && evm.chainRules.IsEIP158 && len(ret) > params.MaxCodeSize {
err = ErrMaxCodeSizeExceeded
}

// 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.StateDB.SetCode(address, ret)
Expand All @@ -481,21 +484,17 @@ 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.StateDB.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.vmConfig.Debug && evm.depth == 0 {
evm.vmConfig.Tracer.CaptureEnd(ret, gas-contract.Gas, time.Since(start), err)
}
return ret, address, contract.Gas, err

}

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

0 comments on commit 0e00ee4

Please sign in to comment.