Skip to content

Commit a3f8e92

Browse files
fix: isAddressCold warmth check and CALL pre-check Amsterdam gate
- isAddressCold: use warm_addresses.isCold() for stale-tx accounts instead of coinbase-only check, covering precompiles and EIP-2930 access-list entries (fixes false cold report for cached accounts) - CALL worst-case pre-check: gate on .amsterdam instead of .berlin; pre-Amsterdam has no phantom BAL entries and the G_NEWACCOUNT worst-case caused false OOG for existing accounts Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 72ed824 commit a3f8e92

File tree

2 files changed

+6
-9
lines changed

2 files changed

+6
-9
lines changed

src/context/journal.zig

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,14 +1165,9 @@ pub const JournalInner = struct {
11651165
pub fn isAddressCold(self: *const JournalInner, address: primitives.Address) bool {
11661166
if (self.evm_state.get(address)) |acct| {
11671167
if (acct.isColdTransactionId(self.transaction_id)) {
1168-
// EIP-3651: coinbase is pre-warmed each tx. If the coinbase was loaded in
1169-
// a previous tx (old transaction_id), still treat it as warm for gas purposes.
1170-
// Only check the coinbase slot — not precompiles or access-list entries, to
1171-
// avoid unintended cross-tx warm promotion for those.
1172-
if (self.warm_addresses.coinbase) |cb| {
1173-
if (std.mem.eql(u8, &address, &cb)) return false;
1174-
}
1175-
return true;
1168+
// Account was loaded in a prior tx — defer to warm_addresses which covers
1169+
// EIP-3651 coinbase, precompiles, and EIP-2930 access-list entries.
1170+
return self.warm_addresses.isCold(address);
11761171
}
11771172
return false;
11781173
}

src/interpreter/opcodes/call.zig

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,9 @@ fn callImpl(
138138
// Worst-case pre-check (assume account non-existent) before any DB load.
139139
// getCallGasCost(..., false) >= exact cost, so if this passes the account can never
140140
// become a phantom BAL entry (the exact-cost check below can never OOG).
141-
if (primitives.isEnabledIn(spec, .berlin)) {
141+
// Gated on Amsterdam: pre-Amsterdam has no BAL and G_NEWACCOUNT makes the worst-case
142+
// overly conservative for existing accounts, causing false OOG.
143+
if (primitives.isEnabledIn(spec, .amsterdam)) {
142144
const worst_case = gas_costs.getCallGasCost(spec, pre_is_cold, transfers_value, false);
143145
if (ctx.interpreter.gas.remaining < worst_case) {
144146
ctx.interpreter.halt(.out_of_gas);

0 commit comments

Comments
 (0)