Skip to content

Commit 40ef9d5

Browse files
holimangzliudan
authored andcommitted
core/vm: make gas cost reporting to tracers correct (ethereum#22702)
Previously, the makeCallVariantGasCallEIP2929 charged the cold account access cost directly, leading to an incorrect gas cost passed to the tracer from the main execution loop. This change still temporarily charges the cost (to allow for an accurate calculation of the available gas for the call), but then afterwards refunds it and instead returns the correct total gas cost to be then properly charged in the main loop.
1 parent ed579d2 commit 40ef9d5

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

core/vm/operations_acl.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,15 @@ func makeCallVariantGasCallEIP2929(oldCalculator gasFunc) gasFunc {
177177
return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
178178
addr := common.Address(stack.Back(1).Bytes20())
179179
// Check slot presence in the access list
180-
if !evm.StateDB.AddressInAccessList(addr) {
180+
warmAccess := evm.StateDB.AddressInAccessList(addr)
181+
// The WarmStorageReadCostEIP2929 (100) is already deducted in the form of a constant cost, so
182+
// the cost to charge for cold access, if any, is Cold - Warm
183+
coldCost := ColdAccountAccessCostEIP2929 - WarmStorageReadCostEIP2929
184+
if !warmAccess {
181185
evm.StateDB.AddAddressToAccessList(addr)
182-
// The WarmStorageReadCostEIP2929 (100) is already deducted in the form of a constant cost
183-
if !contract.UseGas(ColdAccountAccessCostEIP2929 - WarmStorageReadCostEIP2929) {
186+
// Charge the remaining difference here already, to correctly calculate available
187+
// gas for call
188+
if !contract.UseGas(coldCost) {
184189
return 0, ErrOutOfGas
185190
}
186191
}
@@ -189,7 +194,16 @@ func makeCallVariantGasCallEIP2929(oldCalculator gasFunc) gasFunc {
189194
// - transfer value
190195
// - memory expansion
191196
// - 63/64ths rule
192-
return oldCalculator(evm, contract, stack, mem, memorySize)
197+
gas, err := oldCalculator(evm, contract, stack, mem, memorySize)
198+
if warmAccess || err != nil {
199+
return gas, err
200+
}
201+
// In case of a cold access, we temporarily add the cold charge back, and also
202+
// add it to the returned gas. By adding it to the return, it will be charged
203+
// outside of this function, as part of the dynamic gas, and that will make it
204+
// also become correctly reported to tracers.
205+
contract.Gas += coldCost
206+
return gas + coldCost, nil
193207
}
194208
}
195209

0 commit comments

Comments
 (0)