Avatar for the bluealloy user
bluealloy
revm
BlogDocsChangelog

Performance History

Latest Results

chore(amsterdam): drop superseded pre-devnet-7 create state-gas paths Each Amsterdam devnet supersedes the previous one, so the devnet-6 create accounting branches are removed rather than kept behind flag combinations: - The intrinsic `create_state_gas` fold for create transactions (and its `last_frame_result` refill on failed/alive-target creates) is gone; the charge is always decided at the runtime gas phase and recorded on the first frame's tracker. - `target_was_alive` is removed from `CreateFrame`/`CreateOutcome`; the CREATE refill is driven solely by `charged_create_state_gas`. - ee-tests and snapshots updated to the conditional-charge semantics. All glamsterdam devnet-7 v7.0.0 state and blockchain fixtures pass.
rakita/eip2780-runtime-gas-phase
15 hours ago
refactor(amsterdam): decide first-frame EIP-2780 charges at the handler Move the depth-0 EIP-2780 state-gas decisions out of frame creation into the runtime gas phase (apply_eip2780_runtime_gas), reusing the existing runtime out-of-gas halt: - The recipient new-account charge (value transfer to an empty recipient) and the create transaction's account-creation charge (deployment target does not exist) are decided and affordability- checked at the runtime phase. An unaffordable charge sets runtime_oog and the handler includes the transaction as an out-of-gas halt without entering the frame; a create transaction still bumps the sender nonce on that path. - The decided charge travels to the first frame via FrameInit::state_gas_charge and InitialAndFloorGas::first_frame_state_gas and is recorded on the frame's gas tracker, keeping it refillable on revert/halt. make_call_frame/make_create_frame lose all cfg/journal/ depth logic and only apply the passed charge (defensive backstop on failure). - The runtime halt now returns the EIP-8037 reservoir instead of consuming it, matching the spec's top-frame halt settlement. The CREATE opcode and SSTORE cold-load check drop their EIP-2780 gate: the devnet-7 conditional account-creation charge and the access-cost-before-read ordering are now the sole EIP-8037 behavior, and the pre-devnet-7 unconditional-charge/refill path is removed, so the CREATE refill in return_result is gated purely on the recorded charge. The now-unused Host::is_amsterdam_eip2780_enabled is removed.
rakita/eip2780-runtime-gas-phase
16 hours ago
chore: simplify SSTORE skip_cold_load, drop eip8037/eip2780 gating
rakita/eip2780-runtime-gas-phase
17 hours ago
feat(amsterdam): glamsterdam devnet-7 alignment (fixtures v7.0.0) Aligns Amsterdam to the tests-glamsterdam-devnet@v7.0.0 fixtures. All state_tests and blockchain_tests pass (revme statetest/btest). Spec changes: - EIPs#11836: calldata floor anchored on the decomposed intrinsic base (TX_BASE + recipient/value charges) instead of flat TX_BASE. - EIPs#11891: 7702 ACCOUNT_WRITE charged on the first write to each authority, skipped only when already paid (sender, value-bearing recipient, or a preceding valid authorization). - EIPs#11858: CREATE/CREATE2 account-creation state gas charged conditionally at access in the creating frame before the 63/64 split, after the endowment/nonce pre-checks, only when the destination does not exist; refilled LIFO when the create fails. Top-frame charge for create transactions keeps the existing depth-0 path. - EIPs#11854: SSTORE must cover the slot's access cost before the implicit storage read; an unaffordable cold access skips the read so the slot stays out of the block access list. - EIP-8282: builder deposit/exit system-contract addresses updated. Runtime gas phase is now charged incrementally on a gas tracker and stops at the first unaffordable charge: later authorities and a cold delegation target are never loaded, keeping them out of the EIP-7928 BAL; the recipient is read up front so its BAL read survives a runtime out-of-gas. JournalEntry::CodeChange now records the previous code hash/bytecode and restores them on revert. The old revert-to-empty assumption breaks once 7702 delegation set/clear on already-delegated accounts becomes revertible; the corrupted account stayed untouched (state root correct) but leaked a phantom code write into the BAL. statetest runner updates for the v7 fixture format: explicit tx chainId (including type-0), optional secretKey (bad_v_r_s expects rejection), and >u64 nonces no longer panic the keep-going runner.
rakita/eip2780-runtime-gas-phase
18 hours ago
feat(amsterdam): glam devnet-6 gas accounting & EIP alignment (#3782) * feat(eip8038): implement state-access gas cost update Adds EIP-8038 parameters (gated at AMSTERDAM alongside EIP-7904/EIP-8037). Per the user-supplied rule, every TBD value in the draft spec is set to `previous_value + 1`: WARM_ACCESS 100 -> 101 COLD_ACCOUNT_ACCESS 2,600 -> 2,601 ACCOUNT_WRITE 6,700 -> 6,701 COLD_STORAGE_ACCESS 2,100 -> 2,101 STORAGE_WRITE 2,800 -> 2,801 STORAGE_CLEAR_REFUND 4,800 -> 4,801 CREATE_ACCESS 7,000 -> 7,001 ACCESS_LIST_ADDRESS_COST 2,400 -> 2,401 ACCESS_LIST_STORAGE_KEY_COST 1,900 -> 1,901 Wires the new values through the GasParams table (account/storage access, SSTORE charges and refunds, CREATE/CREATE2, EIP-7702 per-auth regular cost, access-list per-item costs) and bumps the static gas table for warm-access opcodes. EXTCODESIZE and EXTCODECOPY get an extra WARM_ACCESS baked into their static cost per the EIP "EXT* family update" rule. Existing EIP-8037 snapshot tests refreshed; one Amsterdam access-list unit test updated. * feat(eip2780): reduce intrinsic transaction gas Adds EIP-2780 (Reduce intrinsic transaction gas) on top of EIP-8037 / EIP-8038, tracking the https://github.com/misilva73/EIPs/blob/update-eip-2780/EIPS/eip-2780.md draft. Replaces the legacy 21,000 stipend with a decomposed model: TX_BASE_COST 12,300 (sender base + ECDSA + sender access/write) + to-based (per recipient kind) - cold EOA/contract COLD_ACCOUNT_ACCESS (sourced from eip8038) - create CREATE_ACCESS (sourced from eip8038) + value-based - zero 0 - create with value TRANSFER_LOG_COST - other TRANSFER_LOG_COST + ACCOUNT_WRITE The current draft's self-transfer and precompile zero-charge carve-outs are intentionally not implemented — a future revision is expected to drop them, so self-transfers and precompile transfers pay the same to/value charges as any other recipient. Adds an `enable_amsterdam_eip2780` config flag (auto-enabled at AMSTERDAM, paired with `Cfg::is_amsterdam_eip2780_enabled`) and `Eip2780TxInfo` (just the transferred value) plumbed into `GasParams::initial_tx_gas`. Validation in the handler builds the info when EIP-2780 is enabled. `tx_transfer_log_cost`, `tx_account_write_cost`, and `tx_create_access_cost` GasIds are added and populated in the AMSTERDAM block. Implements the top-level execution charges from EIP-2780 in `EthFrame::make_call_frame` (depth == 0): - If recipient is EIP-7702-delegated, charge an additional `COLD_ACCOUNT_ACCESS` of regular gas. - If recipient is empty per EIP-161 and `tx.value > 0`, charge `new_account_state_gas(cpsb)` of state gas. The existing `last_frame_result` reservoir reconciliation refunds it on revert. Existing EIP-8037 helpers in `eip8037.rs` explicitly disable EIP-2780 so the state-gas-reservoir tests stay focused. Bumps one EIP-7708 test's gas limit to fit the new ~207k intrinsic for value transfer creating a new account. Adds an `eip2780.rs` ee-tests module covering self-transfer, EOA, empty-with-value, create with/without value, and the legacy-fallback path. * feat(eip7954): bump max code size to 64 KiB and initcode to 128 KiB (#3707) Raises EIP-7954 limits for the glam devnet: MAX_CODE_SIZE from 0x8000 → 0x10000 (65,536 bytes) and MAX_INITCODE_SIZE from 0x10000 → 0x20000 (131,072 bytes). Updates the affected validation test to push the new oversize threshold and refreshes related comments. * feat(context): implement EIP-8246 (remove SELFDESTRUCT burn) (#3717) Replace the EIP-7708 burn-log mechanism with EIP-8246 semantics: at transaction finalization, self-destructed accounts that still hold a balance keep it and have their code, storage and nonce cleared instead of the balance being burned. Self-destruct to self no longer burns the balance either. - Rename `eip7708_emit_burn_remaining_balance_logs` to `eip8246_clear_selfdestructed_accounts`; clear accounts (code, storage, nonce) and drop the self-destruct flag instead of emitting burn logs, preserving the balance. - Stop zeroing the balance / emitting a burn log for self-destruct to self under Amsterdam. - Remove the now-dead `eip7708_burn_log` helper. - Rename the `eip7708_delayed_burn_disabled` flag to `eip8246_delayed_clear_disabled` (CfgEnv field, Cfg accessor and JournalCfg field). * fix(eip-8037): exclude floor and refund from block_regular_gas_used (#3719) * fix(eip-8037): apply EIP-7778 branching to block_regular_gas_used Replace `max(total_gas_spent - state_gas_spent, floor_gas)` with the conditional formula from EIP-8037 + EIP-7778 (PR ethereum/EIPs#11706): - Floor-dominant (floor_gas >= total_gas_spent - refunded): block_regular = tx_gas_used - state_gas_spent - Refund-dominant: block_regular = total_gas_spent - state_gas_spent (pre-refund, since refunds are excluded from block accounting) Floor gas no longer participates as a `max(...)` against the regular component; it only contributes through `tx_gas_used` when it dominates the post-refund total. * fix(eip-8037): exclude floor and refund from block_regular_gas_used Per EIP-8037 + EIP-7778, block-level regular gas accounting is the pre-refund regular component of execution. Refund and floor are scalar adjustments on the combined `state + regular` total and only affect the receipt's `tx_gas_used`, not the block-level split. block_regular_gas_used = total_gas_spent - state_gas_spent * feat(amsterdam): align gas accounting & test runners to devnet-6 (v6.1.0) (#3778) * feat(eip8038): finalize gas parameters per ethereum/EIPs#11802 (#3771) * feat(eip8038): finalize gas parameters to ethereum/EIPs#11802 values Replaces the `previous_value + 1` placeholders introduced in #3697 with the parameters proposed in ethereum/EIPs#11802: COLD_ACCOUNT_ACCESS 2,600 -> 3,000 STORAGE_WRITE 2,800 -> 10,000 COLD_STORAGE_ACCESS 2,100 -> 3,000 STORAGE_CLEAR_REFUND 4,800 -> 12,480 ACCOUNT_WRITE 6,700 -> 8,000 CREATE_ACCESS 7,000 -> 11,000 ACCESS_LIST_ADDRESS 2,400 -> 3,000 ACCESS_LIST_KEY 1,900 -> 3,000 - WARM_ACCESS is restored to 100; the placeholder bumped it to 101 but the spec leaves it unchanged. - CREATE_ACCESS, the access-list costs and CALL_VALUE now use the spec's derivations (ACCOUNT_WRITE + COLD_STORAGE_ACCESS, COLD_*_ACCESS, and ACCOUNT_WRITE + CALL_STIPEND). - EIP7702_PER_EMPTY_ACCOUNT_REGULAR is recomputed from the EIP-8037 base plus the EIP-8038 deltas (ACCOUNT_WRITE, COLD_ACCOUNT_ACCESS); the ecRecover and calldata terms are unchanged by EIP-8038. - Adds constant and gas-table conformance tests. ethereum/EIPs#11802 is still an open draft, so these values are preliminary. * test(eip8038): regenerate eip8037 snapshots for finalized values The eip8037 ee-test snapshots run at SpecId::AMSTERDAM and therefore bake in the EIP-8038 parameters. Regenerated for the finalized values: state gas is unchanged; regular gas reflects the new access/write costs (e.g. CREATE +3,999, SELFDESTRUCT-to-empty +1,698, SSTORE clear now hitting the 20% refund cap). * feat(amsterdam): align EIP-2780/8037/8038/7702 gas with devnet-6 (v6.1.0) Fixes near-universal Amsterdam state-test failures by correcting gas parameters to the finalized glamsterdam-devnet-6 (EELS v6.1.0) values, matching the reference implementation: - EIP-8038: cherry-pick finalized parameters (#3771): COLD_*_ACCESS 3000, ACCOUNT_WRITE 8000, STORAGE_WRITE 10000, etc. - EIP-8038: cold SSTORE folds warm base into cold cost - cold_storage_cost uses the additional (2900) since sstore_static (warm 100) is charged separately, fixing a 100-gas overcharge on nearly every SSTORE. - EIP-8038: new_account_cost is 0 (value CALL already pays ACCOUNT_WRITE via CALL_VALUE); SELFDESTRUCT keeps the separate ACCOUNT_WRITE. - EIP-2780: TX_BASE 12300->12000, add TX_VALUE_COST (4244) for value calls, implement the self-transfer carve-out (base only), floor base ->12000. - EIP-7702: per-auth regular gas 15816 (incl. ACCOUNT_WRITE), refund ACCOUNT_WRITE (8000) per existing auth, and refund rejected auths under EIP-8037 (regular + state). - Update eip2780 ee-tests and regenerate eip8037 snapshots. Amsterdam state-test failures: 2289 -> 204. * fix(eip8037): track spilled state gas so halts consume it (reservoir model) revm's GasTracker did not distinguish state gas drawn from the reservoir from state gas that spilled into regular gas when the reservoir was empty. On an exceptional halt the spilled portion was wrongly credited back to the reservoir (and refunded via the gas_used = spent - reservoir formula) instead of consumed, so every revert/halt/OOG test that charged state gas computed too little gas. Mirror evm2's GasTracker: add a state_gas_spilled counter, credit it back to remaining (LIFO) on rollback via rollback_state_gas, and propagate it to the parent on success. handle_reservoir_remaining_gas and the top-level last_frame_result now settle a failing frame (rollback state gas, drop the refund counter) and, on halt, additionally spend_all the regular gas — so the spilled state gas is consumed while the reservoir is restored to its inherited value. refill_reservoir credits remaining-before-reservoir to match. Update the spend_all ee-test and regenerate snapshots. Amsterdam state-test failures: 204 -> 68. * fix(revme): map modern fork names, skip unknown specs in statetest State-test fixtures key the post section by fork name, and newer EEST fixtures use the descriptive names 'TangerineWhistle' / 'SpuriousDragon' instead of 'EIP150' / 'EIP158'. These deserialized to SpecName::Unknown, whose to_spec_id() panics, aborting the runner thread (observed running the glam-v601 fixtures with stest --keep-going). - Add serde aliases so TangerineWhistle->EIP150 and SpuriousDragon->EIP158 map to the correct spec and those tests actually run. - Skip SpecName::Unknown in the statetest runner (alongside the existing Constantinople skip) so any genuinely unmapped fork is skipped instead of panicking. * fix(eip2780): apply depth-0 delegate/state-gas charges to the executing frame The EIP-2780 top-level (depth-0) charges — the extra COLD_ACCOUNT_ACCESS for a 7702-delegated recipient and the new_account state gas for an empty value recipient — were applied to a local Gas only used on early-return paths (empty bytecode, precompile, halt). When the recipient executed code, EthFrame::clear rebuilt the interpreter's gas from the raw gas_limit, discarding the charges. - Load the recipient with code so the 7702 designator is read. - Carry the charged Gas into the interpreter after clear() so the charges affect remaining/reservoir/state gas during execution. Amsterdam state-test failures: 68 -> 32. * fix(eip8037): refund upfront new_account_state_gas when a CALL fails A CALL transferring value to an empty recipient charges new_account_state_gas upfront on the parent's tracker. When the call does not create the account (revert, halt, or early failure such as insufficient balance), that charge must be refunded to the parent's reservoir. The child-frame rollback in handle_reservoir_remaining_gas cannot do it because the charge lives on the parent. Mirror the CREATE path's create_state_gas refill using the propagated charged_new_account_state_gas flag. Amsterdam state-test failures: 32 -> 23. * fix(eip8037): refund create_state_gas when CREATE targets an already-alive account Per EIP-8037 (execution-specs created_target_alive), a CREATE/CREATE2 that succeeds at a pre-existing alive (non-empty, e.g. balance-only) address does not create a new account leaf, so the upfront create_state_gas must be refunded — the same refill the create-failed path already performs. Track target_was_alive (captured before the create checkpoint) through CreateFrame and CreateOutcome, and refund create_state_gas when the create failed OR the target was already alive. Amsterdam state-test failures: 23 -> 8 (clears CREATE-to-existing-account cases across eip7997 factory, stCreate2 collisions, selfdestruct, etc.). * fix(eip7702): mirror execution-specs auth-base refund (delegated_before_tx + double-refill) revm's apply_auth_list only refunded the per-auth AUTH_BASE state gas when the authority was currently delegated or being cleared. Execution-specs (and evm2) also refund it when the authority was delegated at the start of the transaction (delegated_before_tx, using the account's original code), and refund it twice when clearing a delegation that was freshly installed earlier in the same tx. Recompute existed/delegated_now/delegated_before_tx/clearing per authorization and apply the spec's refund rules. Amsterdam state-test failures: 8 -> 4. * fix(eip8037): refund create_state_gas for top-level CREATE at an alive target Extend the create_state_gas refund to the top-level CREATE transaction: when the create succeeds at a pre-existing alive (balance-only) address, no new account leaf is created, so the intrinsic create_state_gas charged at tx entry is refunded — matching the nested-create path. Threads target_was_alive from the CreateOutcome into last_frame_result. Amsterdam state-test failures: 4 -> 0. The full glam-v601 state-test suite now passes (all forks). * feat(revme): print an error for unknown post-state spec instead of skipping silently An unmapped post-state fork (SpecName::Unknown) is still skipped to avoid panicking in to_spec_id, but now reports the offending test path on stderr so unsupported specs are visible rather than silently ignored. * feat(revme): EIP-8282 builder system calls in btest + ForkSpec fork aliases - Add the EIP-8282 builder execution-request system calls (builder deposit 0x..884d type 0x03, builder exit 0x..14574a type 0x04) to the blockchain-test post-block transition, gated on Amsterdam, so they are warmed and appear in the Block Access List (EIP-7928) as the v6.1.0 fixtures expect. - Map the modern ForkSpec names TangerineWhistle->EIP150 and SpuriousDragon->EIP158 (serde aliases) so those blockchain-test fixtures decode. Blockchain-test failures: 2852 -> 7. * fix(eip7928): record SSTORE slot access in BAL even when the cold load OOGs SSTORE skipped the cold storage load when there was not enough gas to pay the cold cost (an optimization to avoid a DB read before a certain out-of-gas). That also skipped warming the slot, so EIP-7928 block access lists omitted the accessed slot. Always cold-load the slot for SSTORE: the out-of-gas outcome is unchanged (the cold charge still fails), but the access is now recorded. The skip is retained for CALL, where EIP-7928 defers EIP-7702 delegation warming. Blockchain-test failures: 7 -> 6. * fix(eip7928): preserve self-destructed slot accesses in BAL under EIP-8246 When EIP-8246 preserves a self-destructed account's balance, it cleared the account's storage map (storage.clear()) before the block access list was captured, dropping the slot accesses that occurred during execution. EIP-7928 records those accesses, so the BAL was missing read-only (and write-to-zero) slots on created-then-self-destructed accounts. Wipe the storage values in place (present_value = 0) instead of dropping the entries: the committed state is still an empty balance-only account, but the slot accesses survive into the BAL — read-only slots stay read-only and written slots become writes-to-zero. Blockchain-test failures: 6 -> 0. The full glam-v601 blockchain-test and state-test suites now pass. * fix(eip2780): charge new_account_state_gas for value transfers to precompiles The glamsterdam v6.1.0 fixtures (glam-v610) charge the EIP-8037 new_account_state_gas when a top-level transaction transfers value to an empty precompile/special address. revm skipped the EIP-2780 depth-0 charges entirely for precompile recipients, so the state gas was missing. - Remove the precompile carve-out from the depth-0 EIP-2780 charge so an empty precompile recipient with value is charged new_account_state_gas (matching evm2's eip2780_call_charges, which has no precompile exception). - The precompile path returns its own result gas (not the local depth-0 gas), so re-apply the state-gas charge to result.gas. Gate it on depth == 0: a precompile reached by a CALL opcode already had the charge applied on the parent's tracker (avoiding a double charge). glam-v610 blockchain-test failures: 7 -> 0. State tests and full workspace pass. --------- * ci: fix failing checks on glam-devnet-6 - run-tests.sh: download glamsterdam-devnet@v6.1.0 fixtures instead of tests-bal@v7.1.1, which predates the Amsterdam consensus changes in this branch and expected stale intrinsic-gas values. - gas_params.rs: drop private intra-doc link to fix `cargo doc` under -D rustdoc::private_intra_doc_links. - Cargo.lock: bump anyhow 1.0.102 -> 1.0.103 to clear RUSTSEC-2026-0190. * docs: fix unescaped backtick from multi-line code span in eip8038
main
4 days ago

Latest Branches

CodSpeed Performance Gauge
-4%
feat(amsterdam): EIP-2780 runtime gas phase (ethereum/EIPs#11844)#3789
15 hours ago
a0b11be
rakita/eip2780-runtime-gas-phase
CodSpeed Performance Gauge
0%
2 days ago
0b2679e
dependabot/github_actions/taiki-e/install-action-2.82.7
CodSpeed Performance Gauge
0%
2 days ago
f2cc335
dependabot/github_actions/crate-ci/typos-1.48.0
© 2026 CodSpeed Technology
Home Terms Privacy Docs