Skip to content

Commit 87e34fb

Browse files
refactor: make Context and Evm generic over DB type (#20)
* feat(eip7928): BAL-aware access tracking infrastructure Add the journal/database plumbing required for correct EIP-7928 Block Access List construction: - primitives: fix TX_GAS_LIMIT_CAP to 16777216 (EIP-7825 value) - database: FallbackFns vtable gains commit_tx/discard_tx/snapshot_frame/ commit_frame/revert_frame/untrack_address hooks so a stateless witness DB can track accesses with frame-accurate reverts - context/journal: lazy access-list pre-warming (warmAccessList / setAccessList) replaces eager loadAccountWithCode+sload; adds isAddressCold/isStorageCold predicates; StorageChanged journal entry now records old_was_written for correct revert; snapshotFrame/commitFrame/revertFrame forwarded to db - handler/mainnet_builder: use warmAccessList for EIP-2929 pre-warming; call snapshotFrame/revertFrame around top-level CALL value transfer - interpreter/host: propagate snapshotFrame/commitFrame/revertFrame through CALL/CREATE frame lifecycle - interpreter/opcodes/call + host_ops: use isAddressCold/isStorageCold for pre-call gas checks without triggering DB loads; untrack_address on OOG - state: storage slot gains was_written flag for revert correctness Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Remove debug prints; fix EIP-3651 coinbase cross-tx warm check - Remove DBG prints from InMemoryDB.basic and JournalInner.setCodeWithHash - Fix isAddressCold: only treat coinbase as cross-tx warm (EIP-3651), not all previously-loaded addresses, to avoid unintended gas discounts for precompiles and access-list entries Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(bal): fix EIP-7928 BAL tracking for 7702 delegation OOG boundaries Split the CALL instruction OOG check into two stages to match EELS: 1. If remaining < call_cost_no_delegation: untrack target (oog_before_target_access) 2. If remaining < base_cost (includes delegation): halt OOG without untracking target (oog_after_target_access and oog_success_minus_1 — target IS in BAL, delegation NOT) Also add unconditional untrackAddress for OOG in EXTCODECOPY and CALL-type opcodes when gas is exhausted before the target is accessed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * style: apply zig fmt Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor: make Context generic over DB, remove FallbackFns vtable - Remove FallbackFns C-style vtable and InMemoryDB.fallback field - Make Context generic: Context(comptime DB: type); DefaultContext = Context(InMemoryDB) - Add Journal(DB) tracking wrappers guarded by @hasDecl (snapshotFrame, commitFrame, revertFrame, commitTracking, discardTracking, notifyStorageSlotCommit, hasNonZeroStorageForAddress, untrackAddress, forceTrackAddress) - Replace Host.ctx with type-erased JournalVTable (18 entries); Host.init(DB, ctx, prec) and Host.fromCtx(ctx, prec) constructors; opcode handlers unchanged - Make Evm generic: EvmFor(comptime DB: type); Evm = EvmFor(InMemoryDB) alias - Make MainnetHandler.* functions accept anytype evm for zero-cost duck typing - Fix getDb() dangling pointer: change self: @this() → self: *const @this() - Update test files to use Host.fromCtx() instead of Host{ .ctx = ... } literal Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * perf/refactor: O(1) CREATE storage collision check; simplify Frame.execute - Add nonzero_storage_count index to InMemoryDB maintained by new private putStorage helper; hasNonZeroStorageForAddress is now O(1) instead of O(n) storage scan on every CREATE - Drop explicit `comptime DB: type` parameter from Frame.execute; infer DB via anytype ctx to remove parameter sprawl Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: propagate spec in withCfg/modifyCfgChained; add revertFrame on transfer failure - withCfg and modifyCfgChained now call setSpecId on the returned context's journaled_state so the journal spec stays in sync - setupCallCore now calls revertFrame() before checkpointRevert() on the two early-return paths when value transfer fails, matching the pattern in mainnet_builder.zig Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 81f7f0e commit 87e34fb

23 files changed

+1500
-1105
lines changed

examples/simple_contract.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub fn main() !void {
1818
defer db.deinit();
1919

2020
// Create a context with Prague specification
21-
var ctx = context.Context.new(db, primitives.SpecId.prague);
21+
var ctx = context.DefaultContext.new(db, primitives.SpecId.prague);
2222

2323
// Create a simple contract that adds two numbers
2424
// PUSH1 0x05 (push 5 onto stack)

0 commit comments

Comments
 (0)