github erigontech/erigon v3.7.0

6 hours ago

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=false to select sequential commitment (#23831, #23972; closes #21137) — by @awskii
  • Broad RPC performance improvements. Faster eth_getLogs, eth_feeHistory, and eth_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=false when creating the datadir. Receipt retention follows state-history retention unless --prune.receipts.distance is 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/v2 Docker platform and amd64v2 tarball 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.commit and --experimental.streaming-commitment from startup arguments; these flags now prevent startup (#23051, #23191) — by @AskAlexSharov, @awskii
  • Required JSON-RPC arguments cannot be null. A null required positional argument now returns -32602 instead
    of silently becoming a zero value, matching geth (#23668) — by @lupin012
  • Caplin restart migration. On upgrade, nodes with --caplin.checkpoint-sync.disable must 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_getFilterLogs queries the filter's stored criteria without draining eth_getFilterChanges or 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_getLogs and erigon_getLatestLogs rename timestamp to blockTimestamp. callTracer with withLog now uses block-wide log indices for transaction and block traces, and bundle-wide indices for debug_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 GraphQL call. Use latest or 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_createAccessList also 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, and eth_subscribe("logs") now include blockTimestamp, matching eth_getLogs (#23935, #23296) — by @lupin012, @taratorio
  • eth_subscribe("syncing") reports sync-state changes over WebSocket. Both it and eth_syncing now show snapshot download progress instead of remaining at block zero throughout the download (#22570, #22716) — by @lupin012
  • Minimal nodes can serve recent debug_executionWitness results without commitment history using --witness.cache.blocks and --witness.cache.head-capture; --witness.cache.maxmb bounds 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_getHeaderByHash and eth_getHeaderByNumber provide header-only queries in the eth namespace (#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_callMany preserves earlier simulated calls' state regardless of the requested trace types and no longer reads changes from the next real block. eth_estimateGas applies state overrides to balance and code checks as well as execution (#23121, #23951, #23655) — by @lupin012
  • Blob-fee handling now matches geth: eth_estimateGas reserves funds for blobs before calculating the gas allowance, and eth_call does not charge the chain's blob base fee when blob fields are supplied without a nonzero blob fee cap (#23949) — by @lupin012
  • callTracer omits to for failed CREATE and CREATE2 calls 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-epochs limits 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-urls allows 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
  • RemoveOverlaps no longer deletes another component's in-progress .tmp file: 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. .tmp removal 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.url to select TCP or Unix-socket endpoints (#23108) — by @lupin012

Full Changelog: v3.6.1...v3.7.0

Don't miss a new erigon release

NewReleases is sending notifications on new releases.