Skip to content

Commit

Permalink
Merge pull request #6136 from m-Peter/evm-dry-run-create2-bug
Browse files Browse the repository at this point in the history
Add a buffer gas of "all but one 64th" for gas used on `EVM.dryRun`
  • Loading branch information
janezpodhostnik authored Jun 21, 2024
2 parents 1788144 + 9e6188e commit 2a589d8
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 3 deletions.
17 changes: 17 additions & 0 deletions fvm/evm/emulator/emulator.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,9 +256,21 @@ func (bl *BlockView) DryRunTransaction(
// return without commiting the state
txResult, err := proc.run(msg, tx.Hash(), 0, tx.Type())
if txResult.Successful() {
// As mentioned in https://github.com/ethereum/EIPs/blob/master/EIPS/eip-150.md#specification
// Define "all but one 64th" of N as N - floor(N / 64).
// If a call asks for more gas than the maximum allowed amount
// (i.e. the total amount of gas remaining in the parent after subtracting
// the gas cost of the call and memory expansion), do not return an OOG error;
// instead, if a call asks for more gas than all but one 64th of the maximum
// allowed amount, call with all but one 64th of the maximum allowed amount of
// gas (this is equivalent to a version of EIP-901 plus EIP-1142).
// CREATE only provides all but one 64th of the parent gas to the child call.
txResult.GasConsumed = AddOne64th(txResult.GasConsumed)

// Adding `gethParams.SstoreSentryGasEIP2200` is needed for this condition:
// https://github.com/onflow/go-ethereum/blob/master/core/vm/operations_acl.go#L29-L32
txResult.GasConsumed += gethParams.SstoreSentryGasEIP2200

// Take into account any gas refunds, which are calculated only after
// transaction execution.
txResult.GasConsumed += txResult.GasRefund
Expand Down Expand Up @@ -587,3 +599,8 @@ func (proc *procedure) run(
}
return &res, nil
}

func AddOne64th(n uint64) uint64 {
// NOTE: Go's integer division floors, but that is desirable here
return n + (n / 64)
}
10 changes: 7 additions & 3 deletions fvm/evm/evm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/onflow/flow-go/fvm/crypto"
envMock "github.com/onflow/flow-go/fvm/environment/mock"
"github.com/onflow/flow-go/fvm/evm"
"github.com/onflow/flow-go/fvm/evm/emulator"
"github.com/onflow/flow-go/fvm/evm/stdlib"
"github.com/onflow/flow-go/fvm/evm/testutils"
. "github.com/onflow/flow-go/fvm/evm/testutils"
Expand Down Expand Up @@ -1534,9 +1535,10 @@ func TestDryRun(t *testing.T) {
// Make sure that gas consumed from `EVM.dryRun` is bigger
// than the actual gas consumption of the equivalent
// `EVM.run`.
totalGas := emulator.AddOne64th(res.GasConsumed) + gethParams.SstoreSentryGasEIP2200
require.Equal(
t,
res.GasConsumed+gethParams.SstoreSentryGasEIP2200,
totalGas,
dryRunResult.GasConsumed,
)
})
Expand Down Expand Up @@ -1667,9 +1669,10 @@ func TestDryRun(t *testing.T) {
// Make sure that gas consumed from `EVM.dryRun` is bigger
// than the actual gas consumption of the equivalent
// `EVM.run`.
totalGas := emulator.AddOne64th(res.GasConsumed) + gethParams.SstoreSentryGasEIP2200
require.Equal(
t,
res.GasConsumed+gethParams.SstoreSentryGasEIP2200,
totalGas,
dryRunResult.GasConsumed,
)
})
Expand Down Expand Up @@ -1798,9 +1801,10 @@ func TestDryRun(t *testing.T) {
// Make sure that gas consumed from `EVM.dryRun` is bigger
// than the actual gas consumption of the equivalent
// `EVM.run`.
totalGas := emulator.AddOne64th(res.GasConsumed) + gethParams.SstoreSentryGasEIP2200 + gethParams.SstoreClearsScheduleRefundEIP3529
require.Equal(
t,
res.GasConsumed+gethParams.SstoreSentryGasEIP2200+gethParams.SstoreClearsScheduleRefundEIP3529,
totalGas,
dryRunResult.GasConsumed,
)
})
Expand Down

0 comments on commit 2a589d8

Please sign in to comment.