Erigon v3.7.0 — Velvet Vibrissae
Erigon 3.7.0 is headlined by parallel commitment enabled by default, broad RPC performance improvements, persisted receipts by default, and Glamsterdam on Sepolia. It also improves Caplin validator reliability, recovery during non-finality, and RPC correctness at the chain tip and on pruned nodes.
Highlights
- Parallel commitment, on by default. State-root computation now uses multiple cores, with work shared across both account and storage tries. Use
--experimental.parallel-commitment=falseto select sequential commitment (#23831, #23972; closes #21137) — by @awskii - Broad RPC performance improvements. Faster
eth_getLogs,eth_feeHistory, andeth_getProof, plus lower CPU and memory costs for block and receipt responses. Faster JSON encoding and less copying reduce memory pressure for large HTTP and IPC batches (#23975, #24013, #24034, #23943, #23969, #23960) — by @AskAlexSharov - Persisted receipts enabled by default. New datadirs retain receipts so receipt and log queries can avoid block re-execution within the retention window. This trades more disk space for lower RPC latency; existing datadirs keep their stored setting (#23774) — by @AskAlexSharov
- Glamsterdam on Sepolia. Upgrade Sepolia nodes before 6 October 2026, 13:53:36 UTC. The release schedules Amsterdam in the execution layer and Gloas in Caplin at epoch
353024(#24246) — by @yperbasis. BAL-driven parallel execution also avoids unnecessary transaction retries on Glamsterdam networks (#22190) — by @taratorio
Breaking Changes
- Receipt storage defaults change for fresh datadirs. To retain the previous disk-saving default, set
--prune.include-receipts=falsewhen creating the datadir. Receipt retention follows state-history retention unless--prune.receipts.distanceis set; archive operators should budget for the additional receipt history. Changing the receipt enable/disable setting of an existing datadir requires a fresh datadir (#23774) — by @AskAlexSharov - amd64 releases require x86-64-v2. Docker images and tarballs now require CPU features including SSE4.2 and POPCNT. The separate
linux/amd64/v2Docker platform andamd64v2tarball are removed; use the standard amd64 artifacts. Source builds require Go 1.26 or newer (#23877, #23735) — by @AskAlexSharov - Polygon removal. Polygon chain names, datadirs, and
--bor.*/--polygon.*flags are no longer accepted; use 0xPolygon/erigon. Support ended in 3.1 (#23492, #23497, #23537) — by @awskii, @taratorio - Removed startup flags. Remove
--fcu.background.commitand--experimental.streaming-commitmentfrom startup arguments; these flags now prevent startup (#23051, #23191) — by @AskAlexSharov, @awskii - Required JSON-RPC arguments cannot be
null. Anullrequired positional argument now returns-32602instead
of silently becoming a zero value, matching geth (#23668) — by @lupin012 - Caplin restart migration. On upgrade, nodes with
--caplin.checkpoint-sync.disablemust re-sync Caplin from genesis unless a locally saved finalized state exists; the old head-state snapshot is no longer used. Allow checkpoint sync during the upgrade to avoid this replay (#22746) — by @awskii - Polling log filters follow historical-query semantics.
eth_getFilterLogsqueries the filter's stored criteria without drainingeth_getFilterChangesor renewing the filter lifetime. It enforces--rpc.blockrange.limit,--rpc.logs.maxresults, and--rpc.logs.querylimit. Log filters and subscriptions reject more than four topic positions, or criteria exceeding configured--rpc.subscription.filters.maxaddresses/--rpc.subscription.filters.maxtopics, with-32602; those two limits still default to unlimited (#23296) — by @taratorio - Log JSON compatibility.
erigon_getLogsanderigon_getLatestLogsrenametimestamptoblockTimestamp.callTracerwithwithLognow uses block-wide log indices for transaction and block traces, and bundle-wide indices fordebug_traceCallMany. Update consumers of the old field or transaction-local indices (#23337, #23797) — by @Sahil-4555, @lupin012 - Pending-state requests are rejected where matching state is unavailable. This affects
eth_call,eth_createAccessList,eth_simulateV1, proofs, witnesses, tracing, and GraphQLcall. Uselatestor an explicit canonical block for these requests (#22533) — by @yperbasis - Call validation respects fork activation. Call and simulation endpoints reject access lists before Berlin and blob hashes before Cancun;
eth_createAccessListalso rejects pre-Berlin blocks (#23700) — by @Sahil-4555 - EIP-7702 transaction-pool limits. Delegated senders may have only one in-flight transaction and cannot submit nonce-gapped transactions. Same-nonce replacement remains supported (#23294) — by @yperbasis
Added and Changed
RPC
- Logs returned by
erigon_getLogsByHash,eth_getFilterChanges, andeth_subscribe("logs")now includeblockTimestamp, matchingeth_getLogs(#23935, #23296) — by @lupin012, @taratorio eth_subscribe("syncing")reports sync-state changes over WebSocket. Both it andeth_syncingnow show snapshot download progress instead of remaining at block zero throughout the download (#22570, #22716) — by @lupin012- Minimal nodes can serve recent
debug_executionWitnessresults without commitment history using--witness.cache.blocksand--witness.cache.head-capture;--witness.cache.maxmbbounds cache memory.debug_subscribe("executionWitnesses")pushes newly built witnesses. These features require embedded RPC; head-capture serves cached blocks only, and the cache starts empty after a restart (#22384, #22663, #22407) — by @awskii eth_getHeaderByHashandeth_getHeaderByNumberprovide header-only queries in theethnamespace (#23717) — by @MysticRyuujin- State selection fixes prevent traces and fee queries from mixing committed and newly published blocks. Historical account and storage reads now use the end of the requested block, fixing incorrect values and inconsistent storage proofs around system-contract updates (#22533, #22987, #24056) — by @yperbasis, @lupin012, @AskAlexSharov
- Receipt, log, block, trace, and witness queries check the retention windows of the data they need. Pruned nodes can serve retained blocks and receipts without unnecessary state-history requirements, while requests for unavailable history fail explicitly (#23322, #23760, #23996) — by @lupin012
trace_callManypreserves earlier simulated calls' state regardless of the requested trace types and no longer reads changes from the next real block.eth_estimateGasapplies state overrides to balance and code checks as well as execution (#23121, #23951, #23655) — by @lupin012- Blob-fee handling now matches geth:
eth_estimateGasreserves funds for blobs before calculating the gas allowance, andeth_calldoes not charge the chain's blob base fee when blob fields are supplied without a nonzero blob fee cap (#23949) — by @lupin012 callTraceromitstofor failedCREATEandCREATE2calls instead of returning the zero address, matching geth (#23765) — by @AskAlexSharov- HTTP responses support negotiated Zstandard compression. Fully buffered gzip responses use less CPU at the cost of slightly larger bodies (#23482, #22882) — by @AskAlexSharov, @lupin012
Consensus layer and execution
- Reorgs can exceed the normal depth limit during non-finality. Changesets and block access lists are retained, and snapshot retirement waits for finality, preserving the data needed to recover (#23612) — by @taratorio
- Caplin resumes from a suitable locally saved finalized state on restart, avoiding an unnecessary remote checkpoint download and execution-history backfill.
--caplin.resume-max-staleness-epochslimits the state's age, capped by the chain's sidecar-retention window (#22746) — by @awskii - Caplin no longer blocks state-backed validator duties during a head-state copy, reducing missed sync-committee duties under load. Proposed blocks now include eligible BLS-to-execution withdrawal-credential changes (#24199, #22827) — by @lystopad, @awskii
- Blob-history backfill works with small peer sets, repairs gaps at snapshot boundaries, and only records complete, verified recoveries. Blob pruning now respects each chain's configured serving window, so it no longer discards sidecars that backfill is trying to restore (#23138, #24191; backport of #24044) — by @domiwei
- On Glamsterdam networks,
--caplin.builder.allow-private-urlsallows validator-configured builder URLs to resolve to private or loopback addresses (#23548) — by @domiwei - A slow transaction-pool gRPC subscriber can no longer block transaction gossip to peers (#23730) — by @Sahil-4555
RemoveOverlapsno longer deletes another component's in-progress.tmpfile: the block-snapshot merge path could unlink Caplin's in-flight blob-compression target, discarding an already-compressed range and forcing it to be redone..tmpremoval errors are now joined and returned instead of silently discarded (#24146, #24237) — by @AskAlexSharov, @lystopad- Hashing an incomplete Gloas execution-payload envelope is rejected instead of causing a nil-pointer panic (#24152) — by @yperbasis
Operations
- Unless explicitly configured, Go's soft memory limit (
GOMEMLIMIT) defaults to 80% of RAM or the container memory limit, whichever is lower. Code caches enforce their byte budget even with large contracts, reducing out-of-memory failures (#23757, #23790) — by @AskAlexSharov - Bloated MDBX databases are compacted automatically at startup when reclaimable space is at least 10 GB and exceeds four times the live data.
erigon db compact --datadir=<path>provides manual compaction while the node is stopped (#23956, #23677) — by @AskAlexSharov - Embedded RPC supports HTTPS through
--https.enabled,--https.cert, and--https.key, plus IPC through--socket.enabled. Use--http.url,--https.url, and--socket.urlto select TCP or Unix-socket endpoints (#23108) — by @lupin012
Full Changelog: v3.6.1...v3.7.0