Skip to content

Commit

Permalink
evm: Clean up contract creation error handling
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 Apr 29, 2021
1 parent 871f50b commit 7e474e8
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 7e474e8

Please sign in to comment.