github bluealloy/revm v104
tag v104, revm v35.0.0

11 hours ago

REVM v104 — Release Notes

Date: March 3, 2026
Tag: v104

Amsterdam hardfork support (EIP-7708, EIP-7843, EIP-8024), ResultGas struct refactor, flatten Bytecode, logs added to Revert/Halt variants, BAL (Block Access List) support, O(1) block hash cache, various performance improvements and bug fixes.

Migration Guide: MIGRATION_GUIDE.md
Changelog: CHANGELOG.md

Breaking Changes

  • Flatten BytecodeBytecode is now a struct wrapping Arc<BytecodeInner> instead of an enum. Use accessor methods (kind(), is_legacy(), eip7702_address()) instead of pattern matching. (#3375)
  • ResultGas struct in ExecutionResult — Separate gas_used/gas_refunded fields replaced by a ResultGas struct with methods used(), remaining(), inner_refunded(), final_refunded(), spent_sub_refunded(). (#3413)
  • Logs in Revert/Halt variantsExecutionResult::Revert and Halt now carry logs: Vec<Log> for logs emitted before failure. (#3424)
  • EIP-161 state clear moved into journal finalize — Removed has_state_clear field and related methods from CacheState/State. (#3444)
  • Remove Default for EthPrecompiles and EthInstructions — Use new(spec) constructors instead. (#3434)
  • Fixed-bytes hashmaps from alloy-coreHashMap<Address, _>AddressMap<_>, HashMap<B256, _>B256Map<_>. (#3358)

Amsterdam Hardfork (New EIPs)

  • EIP-7708: ETH transfers emit a log — When Amsterdam is active and value is non-zero, ETH transfers emit logs. Includes configuration options in Cfg. (#3334, #3395)
  • EIP-7843: SLOTNUM opcode — New opcode 0x4B. BlockEnv gains slot_num: u64 field, Host trait gains slot_num() method. (#3340)
  • EIP-8024: DUPN, SWAPN, EXCHANGE opcodes — New opcodes at 0xE60xE8 with a new InvalidImmediateEncoding instruction result variant. (#3223)

Features

  • BAL (Block Access List) support — New example and StateBuilder::with_bal_builder_if helper. (#3339, #3351)
  • aws-lc-rs backend for secp256r1 — Alternative precompile backend via feature flag. (#3451)
  • Configurable EIP-7702 auth refund — New GasParams entry. (#3366)
  • tx_access_list_cost helper — Added to GasParams. (#3349)
  • clear() for CacheState and TransitionState — Convenience method. (#3390)
  • BlockHashCache helpersiter() and lowest() methods. (#3352)
  • Storage getter on BundleState — (#3321)
  • revme: --json output flag for evmrunner. (#3428)
  • revme: --omit-progress flag for statetest. (#3419)
  • revme: validate block gas in blockchain tests. (#3416)

Performance

  • O(1) ring buffer block hash cache — Replaces BTreeMap<u64, B256>. (#3299)
  • Zero-copy scalar conversion in BLS12-381 MSM precompile. (#3359)
  • Cache trusted setup G2 for KZG precompile. (#3322)
  • Elide jumps in JUMP opcode execution. (#3347)
  • Reserve capacity in merge_transitions, extend_state, and add_transitions. (#3430, #3373)
  • Avoid unnecessary clone/prealloc in state operations. (#3387)
  • Remove unnecessary enveloped_tx clone in op-revm. (#3455)

Bug Fixes

  • Forward storage_by_account_id in WrapDatabaseRef. (#3441)
  • Allow EIP-161 state clear for empty Loaded and Changed accounts. (#3421)
  • Big-endian resize for modexp output padding. (#3432)
  • Respect is_fee_charge_disabled in calculate_caller_fee. (#3401)
  • Fix storage_by_account_id cache bypass in CacheDB. (#3385)
  • Fix populated account if BAL pre-state was none. (#3357)
  • Set transition_id to account correctly. (#3353)
  • Use provided code hash when setting account code. (#3324)
  • LOG/CREATE opcodes memory modification tracking. (#3328)

Dependencies

  • Updated vulnerable dependencies: keccak, time, bytes (#3467)
  • Bumped c-kzg 2.1.4 → 2.1.6 (#3448)
  • Default hardfork updated to Osaka (Ethereum) / Jovian (Optimism) (#3326)

Full diff: v103...v104 (181 files changed, 4494 insertions, 1791 deletions)

All commits

  • chore: remove outdated stack pop TODO by @joeybright53 in #3315
  • perf: Use O(1) ring buffer cache for block hashes instead of BTreeMap by @malik672 in #3299
  • refactor(bytecode): remove redundant clones in legacy analysis tests by @letmehateu in #3317
  • Rename misleading calc_linear_cost_u32 function by @saylor-mik87786 in #3318
  • fix(database): BlockHashCache incorrectly returns zero for block 0 by @bshastry in #3319
  • chore: update default hardfork to Osaka (Ethereum) and Jovian (Optimism) by @zerosnacks in #3326
  • feat: Implement EIP-8024 for Amsterdam by @frangio in #3223
  • fix(bytecode): improve analyze_legacy padding for SWAPN/DUPN/EXCHANGE by @rakita in #3332
  • fix: the LOG[0-4] CREATE CREATE2 opcode can modify memory by @mark0-cn in #3328
  • feat(database): add storage getter to BundleState by @mattsse in #3321
  • perf: cache trusted setup G2 by @lisenokdonbassenok in #3322
  • fix: use provided code hash when setting account code by @Bashmunta in #3324
  • fix(bytecode): improve analyze_legacy and stack tests by @rakita in #3335
  • feat: Implement EIP-7708 ETH transfers emit a log by @rakita in #3334
  • revm-handler: add ItemOrResult::map_item (alias map_frame) by @maximevtush in #3320
  • fix(bytecode): add padding for final opcode missing immediates by @frangio in #3338
  • feat: Implement EIP-7843 SLOTNUM opcode for Amsterdam by @rakita in #3340
  • feat: add BAL (Block Access List) example by @mattsse in #3339
  • perf: elide some jumps in jump by @DaniPopes in #3347
  • feat(gas): add tx_access_list_cost helper to GasParams by @saylor-mik87786 in #3349
  • feat(database): add StateBuilder::with_bal_builder_if by @mattsse in #3351
  • feat(database): add iter and lowest helpers to BlockHashCache by @mattsse in #3352
  • fix: set transition_id to account by @rakita in #3353
  • refactor(handler): extract duplicate ContextError handling by @andrewshab3 in #3312
  • perf: use fixed bytes hashmaps from alloy-core by @gakonst in #3358
  • fix(bal): fix populated account if pre-state was none by @jsign in #3357
  • perf(precompile): zero-copy scalar conversion in BLS12-381 MSM by @dizer-ti in #3359
  • Deprecate nonce_bump_journal_entry and caller_accounting_journal_entry functions by @rakita in #3367
  • docs: clarify gmp uses dynamic linking (no GPL implications) by @gakonst in #3383
  • feat(database): add clear() to CacheState and TransitionState by @mattsse in #3390
  • perf(state): avoid unnecessary clone, prealloc, and fix typo by @nkysg in #3387
  • fix(db): use self.storage() in storage_by_account_id to avoid cache bypass by @RyanBGG in #3385
  • feat(statetest-types): add slot_number support (EIP-7843) by @rakita in #3391
  • fix(journal): emit EIP-7708 log for selfdestructed accounts with remaining balance by @rakita in #3394
  • chore(scripts): update devnet test fixtures to bal@v5.1.0 by @rakita in #3392
  • perf: reserve capacity in add_transitions by @DaniPopes in #3373
  • feat(gas_params): add configurable EIP-7702 auth refund by @Himess in #3366
  • refactor(interpreter): deduplicate slice range logic by @andrewshab3 in #3376
  • feat(statetest-types): add BPO2ToAmsterdamAtTime15k fork spec by @rakita in #3397
  • refactor!: flatten Bytecode by @DaniPopes in #3375
  • impl Display and Error for TxEnvBuildError and DeriveTxTypeError by @Himess in #3409
  • feat(cfg): add EIP-7708 configuration options by @rakita in #3395
  • chore: remove unused deps by @cuiweixie in #3414
  • refactor!: add ResultGas struct to ExecutionResult by @rakita in #3413
  • refactor!: add logs to Revert and Halt variants of ExecutionResult by @rakita in #3424
  • bench: add subcall benchmarks (1000-call variants) by @rakita in #3427
  • chore: remove unused alloy-provider dev-dependency by @zeroprooff in #3423
  • perf(database): add reserve calls in merge_transitions and extend_state by @gakonst in #3430
  • feat(revme): add --omit-progress flag to statetest command by @bluebluesaku in #3419
  • fix(handler): respect is_fee_charge_disabled in calculate_caller_fee by @bluebluesaku in #3401
  • fix: add a test utility function to generate memory input opcodes by @silathdiir in #3280
  • feat(revme): validate block gas used in blockchain tests by @rakita in #3416
  • fix(precompile): use big-endian resize for modexp output padding by @Wollac in #3432
  • refactor(handler): remove Default for EthPrecompiles and EthInstructions by @rakita in #3434
  • fix(database): allow EIP161 state clear for empty Loaded and Changed accounts by @msheth-circle in #3421
  • feat(revme): add --json output flag to evmrunner command by @bluebluesaku in #3428
  • refactor(gas): simplify log2floor implementation by @rakita in #3440
  • fix: forward storage_by_account_id in WrapDatabaseRef by @andrewshab3 in #3441
  • chore: bump c-kzg from 2.1.4 to 2.1.6 by @rakita in #3448
  • refactor: deduplicate CacheDB::basic by delegating to load_account by @andrewshab3 in #3447
  • refactor: move EIP-161 state clear into journal finalize by @decofe in #3444
  • docs(op-revm): fix operator fee field doc comments by @jackwener in #3457
  • perf(op-revm): remove unnecessary enveloped_tx clone in reward_beneficiary by @jackwener in #3455
  • feat(precompile): add aws-lc-rs as alternative backend for secp256r1 by @rakita in #3451
  • fix(context): correct ResultGas::final_refunded() when floor gas is active by @rakita in #3450
  • chore: update vulnerable dependencies by @rakita in #3467
  • chore: release by @github-actions[bot] in #3316
  • docs: add v104 migration guide by @rakita in #3468
  • chore: bump revm to v35.0.0 for v104 release by @rakita in #3470

New Contributors

Full Changelog: v103...v104

Don't miss a new revm release

NewReleases is sending notifications on new releases.