Erigon v3.5.0 — Tidal Tails
Erigon 3.5.0 is a major release headlined by parallel block execution becoming the default and initial support for Ethereum's upcoming Glamsterdam hardfork. It is a drop-in upgrade for 3.4.x users — no re-sync required; existing datadirs upgrade their prune configuration automatically (see Breaking Changes).
Key Features
- Parallel block execution, on by default. Erigon now executes EVM transactions across multiple cores by default, using the Block-STM (software transactional memory) design pioneered by Aptos: transactions run optimistically in parallel and are re-validated against a multi-version state, re-executing only on conflict (#21591 by @mh0lt, closes #17630). Revert to serial with
EXEC3_PARALLEL=falseor--exec.serial. - Glamsterdam devnet support. Initial implementation of Ethereum's next hardfork: Block-Level Access Lists (EIP-7928), enshrined Proposer-Builder Separation / "Gloas" (EIP-7732) in Caplin, gas repricings (EIP-8037, EIP-7976, EIP-7981), larger contracts (EIP-7954), transfer logs (EIP-7708), and the
eth/71Block Access List wire protocol (EIP-8159). Devnet/testing only — not scheduled on mainnet or any public testnet. debug_executionWitness. Stateless execution-witness generation (EIP-7928/8025) with reth-compatible output, for zkEVM and stateless clients (#20205 by @antonis19, #21629 by @awskii).- More aggressive history pruning by default.
--prune.mode=fullnow follows the EIP-8252 reorg-retention window (~36 days / 262,144 blocks) — see Breaking Changes. - GraphQL API revival. Broad resolver coverage restored — queries, logs,
call,sendRawTransaction,estimateGas,gasPrice, storage, and EIP-4844 fields.
Breaking Changes
--prune.mode=full: EIP-8252 retention window replaces pre-merge history-expiry
Full mode now retains state and block data for the last 262,144 blocks (~36.4 days), matching EIP-8252's REORG_RETENTION_WINDOW (#21342). Previously full mode pruned only pre-merge block data (EIP-4444 history-expiry) and kept the last 100,000 blocks of state history.
What changed:
| Before | After | |
|---|---|---|
| State history retention | last 100,000 blocks | last 262,144 blocks |
| Block data retention | pre-merge pruned, all post-merge kept (EIP-4444) | last 262,144 blocks |
Migration: existing datadirs upgrade automatically and silently. To keep the old "retain all post-merge block data" behavior, set --prune.distance.blocks=18446744073709551615.
Note: physical deletion of frozen snapshot files is not implemented yet (see #21306), so existing on-disk historical blocks persist for now, though the new cutoff is already recorded at the config level.
In practice, this means only freshly synced full nodes will have a reduced disk footprint.
--prune.mode=blocks: state history retention bumped to 262,144 blocks
--prune.mode=blocks keeps the same shape as before (all block data retained), but its state history retention also bumps from 100,000 to 262,144 blocks. --prune.mode=minimal is unchanged — both block and state history retain the 100,000-block window, deliberately sub-EIP-8252 for disk-constrained operators. See #21342 for details.
Single p2p listener: --p2p.allowed-ports removed, all eth versions multiplex on --port
Erigon now opens a single TCP listener on --port (default 30303) carrying every configured eth protocol version, instead of one listener per protocol on 30303/30304/30305. This fixes a discovery-DHT race that left inbound peers stuck at a fraction of --maxpeers for multi-protocol deployments: per-protocol ENRs collided under one Node ID, so only one survived in the DHT and peers dialed the wrong listener (#21335).
What changed:
| Aspect | Before | After |
|---|---|---|
| Inbound peer ports | 30303, 30304, 30305, … (one per eth version) |
30303 only |
--p2p.allowed-ports flag |
Picked one port per protocol from this list | Removed — passing it now errors |
--maxpeers semantics |
Per-protocol cap; actual ceiling ≈ N × maxpeers | Honest total cap |
Default --maxpeers |
32 |
64 (compensates for the now-honest cap) |
| Enode database directory | <datadir>/nodes/eth68, <datadir>/nodes/eth69, … |
<datadir>/nodes/eth |
Migration:
- Remove
--p2p.allowed-ports=...from CLI args / config files; it is no longer recognised. - Firewall, Kubernetes Service, and monitoring rules that explicitly opened 30304/30305 can drop those entries — only
--portis bound now. - If you previously lowered
--maxpeersbecause you knew the per-protocol multiplication inflated the real ceiling, raise it back to the target total (the cap is now what the flag says). - First run after upgrade loses the warm peer cache in
nodes/eth{68,69,…}— nothing on disk is deleted, the directories are simply no longer read; discovery rebuilds the peer set from bootnodes within a few minutes.
Standalone sentry binary (cmd/sentry) and --sentry.api.addr (remote sentry over gRPC) are unaffected — neither had the bug.
debug_trace* RPC: enableMemory / enableReturnData replace disableMemory / disableReturnData
Aligns Erigon with the execution-apis specification (ethereum/execution-apis#762) and Geth behavior.
What changed:
| Field | Before (Erigon) | After (Erigon / Geth / Spec) |
|---|---|---|
| Memory in trace | disableMemory (default: included) |
enableMemory (default: excluded) |
| Return data in trace | disableReturnData (default: included) |
enableReturnData (default: excluded) |
Both the key and its default changed: disable* → enable*, and memory and return data are now excluded unless explicitly enabled — matching the spec and Geth.
Migration: memory and return data are now excluded by default. To include them, add the new opt-in key (omit it to keep the default):
- Memory:
{ "enableMemory": true } - Return data:
{ "enableReturnData": true }
Affected RPC methods: debug_traceTransaction, debug_traceBlockByHash, debug_traceBlockByNumber, debug_traceCall.
Clique PoA consensus engine removed
The legacy Clique proof-of-authority engine has been removed (#20532 by @yperbasis). --chain=dev now runs on an embedded proof-of-stake consensus instead of Clique (#20451 by @mh0lt), matching how all live networks operate post-Merge. Networks or tooling that still depended on Clique are no longer supported.
Silkworm integration removed
The optional Silkworm C++ execution-backend integration and its --silkworm.* flags have been removed (#19662 by @canepat). Erigon uses its native Go execution engine exclusively.
Glamsterdam (Devnet Support)
3.5.0 adds an initial implementation of Ethereum's next hardfork — Glamsterdam (consensus-layer "Gloas" + execution-layer "Amsterdam") — for devnet testing and validation. It is not scheduled on mainnet or any public testnet, and these code paths are inert on production networks until an activation time is configured.
- EIP-7928 — Block-Level Access Lists (BAL): records every account and storage slot a block touches, enabling deterministic parallel validation. Full builder, validator, and strict-validation support (#19627, #19656, #20602, #20776), plus the
eth_getBlockAccessListRPC method (#19929) — by @mh0lt, @yperbasis, @Sahil-4555 - EIP-7732 — Enshrined Proposer-Builder Separation (ePBS / "Gloas"): implemented in Caplin — execution-payload envelope, PTC, and builder payments (#18956) — with follow-up audit and fork-choice fixes (#21248, #21228) — by @domiwei
- Gas repricings: EIP-8037 State Creation Gas Cost Increase (#19596), EIP-7976 calldata floor cost (#20613), EIP-7981 access-list cost (#20671) — by @taratorio
- EIP-7954 — Increase Maximum Contract Size (#19624) — by @yperbasis
- EIP-7843 — slot-number opcode (
SLOTNUM), wired into Caplin block production andengine_forkchoiceUpdatedV4(#20175) — by @yperbasis - Networking:
eth/71Block Access List exchange (EIP-8159, #20793, #20794, #20795) — by @mh0lt
Added
RPC
debug_executionWitness: generate stateless execution witnesses (EIP-7928/8025), withlegacyandcanonicaloutput modes — thelegacyformat is reth-compatible — for zkEVM and stateless clients (#20205, #21371, #21518, #21629) — by @antonis19, @lupin012, @awskiieth_capabilities: report the set of supported RPC methods (#20951) — by @lupin012debug_setHead: rewind the chain head (#19577) — by @canepat- GraphQL substantially revived — transaction, logs,
call,sendRawTransaction,estimateGas,gasPrice, and storage resolvers, plus EIP-4844 fields (#20389, #20916, #21219, #21379, #21060) — by @lupin012 testing_namespace exposed via--http.apifor engine/spec test harnesses (#20482) — by @lupin012eth_simulateV1: per-call gas and result limits (#20232) — by @Sahil-4555
CLI & Operations
--exec.no-prune(disable all DB pruning),--exec.serial(force single-threaded execution), and--exec.*executor-tuning flags (#20915, #20853, #20797) — by @mh0ltseg du(snapshot disk-usage analysis, #20104) andseg rm-blocks(remove latest block snapshots, #20554) — by @awskii, @sudeepdino008
Changed
RPC
- WebSocket transport rewritten on
coder/websocket, with overload protection, clean close frames, and bounded write timeouts (#20097, #20446, #20788, #20923) — by @lystopad, @lupin012, @Sahil-4555 - Admission control: uniform
503responses under load (#20303); optional response compression via libdeflate (#20665) — by @lupin012 - Geth compatibility:
debug_traceTransactionindex format (#20210),trace_rawTransaction(#20448),debug_accountRange(#20057), nullv,r,sfor unsigned transactions (#21321) — by @lupin012 - Performance: faster
eth_getLogs(#20561),trace_block(#20182),eth_gasPrice(#19678), canonical-hash cache (#19173);engine_getPayload~2.4× andgetBlobs~10× faster (#21615, #21606) — by @lupin012, @taratorio trace_*returns an explicit error when an unsupported custom tracer is supplied (#21544) — by @lupin012
Networking & P2P
- New
eth/70wire protocol: partial block receipt lists (EIP-7975, #19755) — by @yperbasis - All eth protocol versions now multiplex on a single TCP listener (see Breaking Changes, #21335) — by @lystopad
- Peer hygiene / DoS hardening: cap and rate-limit inbound
NewBlockHashes(#21557), enforce the 4096-hash limit onNewPooledTransactionHashes(#20577), drop peers failing blob KZG verification (#21421), and bound fan-out stream buffers (#20783) — by @yperbasis - Skip chain-specific bootnodes on genesis-hash mismatch (#19807); honour an explicitly empty
--bootnodes(#20630) — by @yperbasis
TxPool
- Proactive dormancy-based eviction of stale queued transactions (#19862) — by @lystopad
- Transaction parsing migrated onto the shared
execution/typestransaction types (#19757); malformed EIP-7702 authorization tuples are now tolerated rather than rejected wholesale (#20809) — by @yperbasis
Caplin (Consensus Layer)
- Unified Engine API client for standalone mode (#20035) — by @mh0lt
- Fork-choice and ENR-stability fixes — recovery from a post-Gloas fork-choice stall and a persistent node key for stable ENR across restarts (#21228, #21276) — by @domiwei
- Block production: give the EL builder a build window before stopping it, fixing near-empty proposed blocks (~0–2% gas) on otherwise-healthy validators (#21990) — by @lystopad
Storage & Performance
- Off-heap Elias-Fano index building (#20640) and parallel commitment computation (#20805) — by @AskAlexSharov, @mh0lt
- Transient-storage zero-write fast path (#20568) and opcode-scoped intern cache to eliminate duplicate
unique.Make()(#20552) — by @Sahil-4555, @AskAlexSharov
Removed
- Clique PoA engine (#20532 by @yperbasis) and Silkworm integration (#19662 by @canepat) — see Breaking Changes.
- Unused
hack(#20412),state(#20420), anddiag(#21351) helper binaries — by @awskii, @AskAlexSharov
Security
--ethstatscredentials are redacted from the startup command log (#20890) — by @MysticRyuujin- DoS-resistance limits on inbound P2P message volume (#20577, #21557) and bounded RPC/stream buffers (#20446, #20783) — by @yperbasis, @lupin012
Full Changelog: v3.4.4...v3.5.0