github paradigmxyz/reth v2.6.0
Reth v2.6.0

3 hours ago

image

Reth v2.6.0 expands Amsterdam and Hegotá protocol support, installs the REST-SSZ Engine API by default, advances EIP-8189 snap-sync infrastructure, and moves partial persistence further into production paths.

The release also improves performance across block processing, historical-state RPC, pruning, transaction-pool updates, and peer discovery. On a 300M-gas BAL workload, storage-trie job parallelism reduced mean newPayload latency by 8.6% and state-root wait time by 39%.

Action Required

Operators with explicit engine persistence thresholds should review their configuration. The defaults are now 50 persisted blocks, 30 state-masking blocks, and 100 blocks of backpressure. A nonzero masking window must satisfy num-state-masking-blocks + memory-block-buffer-target < persistence-threshold (#27220).

  • Set --engine.num-state-masking-blocks 0 to disable state masking (partial persistence).
  • Set --engine.persistence-threshold 0 to preserve immediate persistence and disable state masking (partial persistence).

Operators which read the Reth database out-of-process should disable partial persistence by setting --engine.num-state-masking-blocks 0.

Update Priority

User Class Priority
Payload Builders Low
Non-Payload Builders Low

Breaking Changes

Runtime and Configuration

  • Raised the default persistence threshold from 7 to 50 blocks, enabled 30 blocks of state masking by default, and raised the backpressure threshold from 16 to 100 blocks. Partial persistence is now compiled unconditionally (#26800, #27220).
  • Installed REST-SSZ routes on the authenticated Engine API server by default. Custom Engine API implementations must implement EngineSszApi (#26254).

SDK and RPC APIs

  • Changed EthApiInner::new to accept a single EthApiSettings value instead of individual settings arguments. Custom RPC builders must update construction; existing builder setters and defaults remain available (#27251, #27268).
  • Added the required in_memory_size cache field to the public EthPooledTransaction struct. Downstream users constructing it with struct literals must initialize the field; constructor users are unaffected (#27061).
  • Replaced the layered transaction-announcement wrapper types with ordered TransactionAnnouncement, AnnouncedTransaction, and TransactionMetadata types. Downstream networking users of the previous public internals must migrate (#27021).
  • Made eth_getMultiProof always return V2 proofs, including child branch nodes after extensions. The RPC method keeps its existing two-argument signature (#26851).

Features

Performance

  • Ran storage-trie updates inside checked-out jobs, reducing mean newPayload latency and state-root wait time (#27156).
  • Added opt-in caching and prewarming of RPC-computed BALs with --rpc-cache.cache-computed-bals and --rpc-cache.prewarm-bals[=BLOCKS]. (#24097).
  • Reused RocksDB snapshots and iterators for historical-state lookups, reducing mean trace RPC latency, and CPU per request while increasing throughput (#27210).
  • Skipped history shards that pruning cannot affect, improving mean pruning time (#26900).
  • Limited transaction-pool fee updates to changed senders when possible, reducing a 0.25% sender update from 93 µs to 0.9 µs in a saturated-pool benchmark (#26956).
  • Removed the one-second startup wait for discv5 boot-node ENR requests by moving them into the background (#26929).
  • Reduced RPC memory and CPU overhead by windowing eth_getLogs scans, bloom-filtering log paths, lazily converting trace_get results, and sharing fee-history entries (#26946, #27000, #27031, #26942).

Partial Persistence

Reth now enables partial persistence by default. In this mode state/trie database keys are not updated in the database if later blocks contain updates to those same keys. Those later blocks are referred to as "state masking" blocks.

The new behavior, given default persistence parameters, is:

  • --engine.persistence-threshold 50: Persistence is triggered once there are 50 blocks in-memory.
  • --engine.memory-block-buffer-target 5: Of those 50, 5 will not be persisted at all but will be retained in-memory.
  • --engine.num-state-masking-blocks 30: Of the remaining 45 blocks, 30 will not have their state/trie updates persisted yet. All other block data (headers, transactions, changesets, indexes, etc..) will still be persisted.
  • The remaining 15 blocks will have their state/trie updates persisted, but only those keys not overwritten by the 30 masking blocks.

Consistency is guaranteed on startup after a crash by using the changesets of the masking blocks to revert all state which was not written due to masking by those blocks.

Engine, Payload Building and Protocol Support

  • Added Bogota chainspec and Engine API support for engine_newPayloadV6 and engine_forkchoiceUpdatedV5, including fork-time validation (#26686, #26691, #26706, #26711).
  • Added foundational FOCIL support with engine_getInclusionListV1 and bounded inclusion-list construction from non-blob pool transactions (#26682, #26737).
  • Validated Amsterdam payload fields and imported EIP-7928 block access lists against their header commitments, and advertised the Amsterdam system contracts through eth_config (#27173, #26696, #26705).
  • Installed the REST-SSZ Engine API transport by default, including payload-body retrieval by hash and range and the experimental Amsterdam payload-witness endpoint (#26254, #26394, #26406, #27028).
  • Fetched authenticated BALs for downloaded Amsterdam blocks and used them on the parallel BAL execution path (#26823, #26885).

Networking

  • Advertised eth/70 and eth/71 by default, added an outbound GetCells client, and bounded inbound RLPx subprotocol queues by message count and memory (#26824, #26673, #26660).

RPC and CLI

  • Added the Geth-compatible debug_traceChain subscription with sequential, bounded tracing (#26582).
  • Added HTTP request decompression and a --http.compression allowlist for response compression algorithms (#20277, #26668).
  • Exposed raw block transaction lookup methods on the authenticated Engine API server (#26760).
  • Added EIP-8037 state-gas tracing while preserving pre-Amsterdam trace output (#26804).
  • Added --authrpc.jwtsecret-hex as an inline alternative to a JWT-secret file (#27034).
  • Added downstream hooks for custom transaction replacement pricing and nonce-bound validation while preserving Ethereum defaults (#27201, #27185).

Execution Overlays and Storage

  • Ground-up rewrite of execution/trie state overlay management. Execution state overlays are now flattened for better performance with high in-memory block counts (#26834, #26838, #26862, #26616, #27056, #27219).

Bug Fixes

Security and Networking

  • Kept the engine tree alive when downloaded or buffered blocks contain unrecoverable transactions, preventing malformed peer-served blocks from stopping the task (#26901).
  • Updated h2 to 0.4.16 for the fix to RUSTSEC-2026-0258 (#26753).
  • Made eth/72 transaction announcements interoperable with Geth's cell-mask encoding instead of disconnecting compliant peers (#26670).

Engine, Trie and Payload

  • Flushed retained state and trie data before pipeline backfill so staged execution cannot read masked state without its in-memory overlay (#26911).
  • Fixed proof V2 dirty-range processing and branch collapse around cached trie branches (#26842, #26843).
  • Preserved storage wipes in execution overlays so pre-Dencun SELFDESTRUCT reads do not fall back to durable state (#26872).
  • Prevented an engine panic when the payload stream terminates and adjudicated speculative BAL worker failures in transaction order (#27218, #26721).
  • Applied persistence backpressure to the retained state-trie frontier and fixed cache handoff races during persistence (#27269, #27230, #27234).

RPC and Txpool

  • Rejected a caller-supplied chainId that does not match the node instead of silently re-signing and submitting the transaction on another chain (#26782).
  • Returned an error for eth_getLogs queries whose matching receipts were pruned instead of returning incomplete results (#27002).
  • Returned actual used gas from the basic-transfer eth_estimateGas shortcut, fixing post-Amsterdam overestimation of up to 75% (#26875).
  • Derived the next-block base fee for eth_callBundle, simulated mev_simBundle in the block after parentBlock, and returned null for sender-nonce gaps consumed by EIP-7702 authorization (#27265, #27266, #27275).
  • Parked pending blob transactions when the blob fee rises while the base fee falls, enforced the configured minimum priority fee for local transactions, and rejected transactions below the tracked sender nonce when enabled (#26962, #26861, #26981).

Don't miss a new reth release

NewReleases is sending notifications on new releases.