Skip to content

Commit

Permalink
vm: fix Frontier consensus bug along CREATE with not enough gas
Browse files Browse the repository at this point in the history
  • Loading branch information
jochem-brouwer authored and holgerd77 committed Feb 11, 2021
1 parent 7c4c5b9 commit ab89b59
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 3 deletions.
5 changes: 4 additions & 1 deletion packages/vm/lib/evm/eei.ts
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,10 @@ export default class EEI {
this._lastReturned = results.execResult.returnValue
}

if (!results.execResult.exceptionError) {
if (
!results.execResult.exceptionError ||
results.execResult.exceptionError.error === ERROR.CODESTORE_OUT_OF_GAS
) {
Object.assign(this._result.selfdestruct, selfdestruct)
// update stateRoot on current contract
const account = await this._state.getAccount(this._env.address)
Expand Down
16 changes: 14 additions & 2 deletions packages/vm/lib/evm/evm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ export default class EVM {
allowedCodeSize = false
}
// If enough gas and allowed code size
let CodestoreOOG = false
if (
totalGas.lte(message.gasLimit) &&
(this._vm._allowUnlimitedContractSize || allowedCodeSize)
Expand All @@ -355,8 +356,8 @@ export default class EVM {
debug(`Not enough gas or code size not allowed (Frontier)`)
if (totalGas.sub(returnFee).lte(message.gasLimit)) {
// we cannot pay the code deposit fee (but the deposit code actually did run)
//result = { ...result, ...COOGResult(totalGas.sub(returnFee)) }
result.gasUsed = totalGas.sub(returnFee)
result = { ...result, ...COOGResult(totalGas.sub(returnFee)) }
CodestoreOOG = true
} else {
result = { ...result, ...OOGResult(message.gasLimit) }
}
Expand All @@ -367,6 +368,17 @@ export default class EVM {
if (!result.exceptionError && result.returnValue && result.returnValue.toString() !== '') {
await this._state.putContractCode(message.to, result.returnValue)
debug(`Code saved on new contract creation`)
} else if (CodestoreOOG) {
// This only happens at Frontier. But, let's do a sanity check;
if (!this._vm._common.gteHardfork('homestead')) {
// Pre-Homestead behavior; put an empty contract.
// This contract would be considered "DEAD" in later hard forks.
// It is thus an unecessary default item, which we have to save to dik
// It does change the state root, but it only wastes storage.
//await this._state.putContractCode(message.to, result.returnValue)
const account = await this._state.getAccount(message.to)
await this._state.putAccount(message.to, account)
}
}

return {
Expand Down

0 comments on commit ab89b59

Please sign in to comment.