Skip to content

Commit 453b60e

Browse files
evm: better error handling for contract creation errors (ethereumjs#2723)
Co-authored-by: acolytec3 <[email protected]>
1 parent 13276b1 commit 453b60e

File tree

2 files changed

+68
-6
lines changed

2 files changed

+68
-6
lines changed

packages/evm/src/evm.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -612,20 +612,30 @@ export class EVM implements EVMInterface {
612612
}
613613
} else {
614614
if (this._common.gteHardfork(Hardfork.Homestead)) {
615-
if (this.DEBUG) {
616-
debug(`Not enough gas or code size not allowed (>= Homestead)`)
615+
if (!allowedCodeSize) {
616+
if (this.DEBUG) {
617+
debug(`Code size exceeds maximum code size (>= SpuriousDragon)`)
618+
}
619+
result = { ...result, ...CodesizeExceedsMaximumError(message.gasLimit) }
620+
} else {
621+
if (this.DEBUG) {
622+
debug(`Contract creation: out of gas`)
623+
}
624+
result = { ...result, ...OOGResult(message.gasLimit) }
617625
}
618-
result = { ...result, ...CodesizeExceedsMaximumError(message.gasLimit) }
619626
} else {
620627
// we are in Frontier
621-
if (this.DEBUG) {
622-
debug(`Not enough gas or code size not allowed (Frontier)`)
623-
}
624628
if (totalGas - returnFee <= message.gasLimit) {
625629
// we cannot pay the code deposit fee (but the deposit code actually did run)
630+
if (this.DEBUG) {
631+
debug(`Not enough gas to pay the code deposit fee (Frontier)`)
632+
}
626633
result = { ...result, ...COOGResult(totalGas - returnFee) }
627634
CodestoreOOG = true
628635
} else {
636+
if (this.DEBUG) {
637+
debug(`Contract creation: out of gas`)
638+
}
629639
result = { ...result, ...OOGResult(message.gasLimit) }
630640
}
631641
}

packages/evm/test/runCall.spec.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,3 +673,55 @@ tape('step event: ensure EVM memory and not internal memory gets reported', asyn
673673
await evm.runCall(runCallArgs)
674674
t.ok(verifyMemoryExpanded, 'memory did expand')
675675
})
676+
677+
tape('ensure code deposit errors are logged correctly (>= Homestead)', async (t) => {
678+
const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Berlin })
679+
const evm = await EVM.create({
680+
common,
681+
stateManager: new DefaultStateManager(),
682+
})
683+
684+
// Create a contract which is too large
685+
const runCallArgs = {
686+
gasLimit: BigInt(10000000),
687+
data: hexToBytes('61FFFF6000F3'),
688+
}
689+
690+
const res = await evm.runCall(runCallArgs)
691+
t.ok(res.execResult.exceptionError?.error === ERROR.CODESIZE_EXCEEDS_MAXIMUM)
692+
693+
// Create a contract which goes OOG when creating
694+
const runCallArgs2 = {
695+
gasLimit: BigInt(100000),
696+
data: hexToBytes('62FFFFFF6000F3'),
697+
}
698+
699+
const res2 = await evm.runCall(runCallArgs2)
700+
t.ok(res2.execResult.exceptionError?.error === ERROR.OUT_OF_GAS)
701+
})
702+
703+
tape('ensure code deposit errors are logged correctly (Frontier)', async (t) => {
704+
const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Chainstart })
705+
const evm = await EVM.create({
706+
common,
707+
stateManager: new DefaultStateManager(),
708+
})
709+
710+
// Create a contract which cannot pay the code deposit fee
711+
const runCallArgs = {
712+
gasLimit: BigInt(10000000),
713+
data: hexToBytes('61FFFF6000F3'),
714+
}
715+
716+
const res = await evm.runCall(runCallArgs)
717+
t.ok(res.execResult.exceptionError?.error === ERROR.CODESTORE_OUT_OF_GAS)
718+
719+
// Create a contract which goes OOG when creating
720+
const runCallArgs2 = {
721+
gasLimit: BigInt(100000),
722+
data: hexToBytes('62FFFFFF6000F3'),
723+
}
724+
725+
const res2 = await evm.runCall(runCallArgs2)
726+
t.ok(res2.execResult.exceptionError?.error === ERROR.OUT_OF_GAS)
727+
})

0 commit comments

Comments
 (0)