Repository navigation
Releases: NethermindEth/nethermind
Release list
v2.1.0
Release notes
359 merged pull requests since 2.0.0, from 29 contributors.
Important
Sepolia: Glamsterdam activated on Tue, 06 Oct 2026, 13:53:36 UTC. Sepolia nodes must run 2.1.0 or later.
Note
Upgrading from 1.39.x? The breaking changes below cover 2.0.0 → 2.1.0 only. Apply the 2.0.0 breaking changes and upgrade checklist first; they are the complete 1.39.x → 2.0 list.
For most nodes this is an in-place upgrade with no resync. Read Breaking changes first if you run on the flat backend with a custom sync config, run poacore, run a Flashbots relay, parse Parity-style traces, or build plugins against Nethermind.
Highlights
- Glamsterdam on Sepolia. Final EIP-8037 state-gas rules, the
TX_MAX_TOTAL_GAS_LIMITtransaction cap, and Engine API alignment for Amsterdam. (#13140, #13484, #13627, #13554, #13583, #13586, #13755) - Faster EVM. The interpreter loop is replaced by tail-call chain dispatch, stack words stay in
UInt256limb layout, storage values stay asUInt256until they are persisted, and JUMPDEST analysis is rewritten. (#13128, #13323, #13420, #13189, #13810) - Lower
engine_newPayloadlatency. The response goes out as soon as the block has executed and its roots match, before the commit.engine_forkchoiceUpdatedstill waits for that head's commit. GC pauses no longer stall payloads the way they did. (#13647, #13711, #13476, #13334) - Per-transaction changeset index for flat archives (opt-in). A single-transaction trace starts at its target transaction instead of replaying the whole block before it:
debug_traceTransactionwent from ~7.1 s to ~28 ms in the PR's measurements. Whole-block traces run their transactions in parallel (6–10× faster). Enable withFlatDb.HistoryTransactionIndexEnabled=true. (#13454, #13426) - BAL healing after snap sync (flat backend). On the flat backend, the state left by snap sync is healed by replaying block access lists instead of downloading trie nodes. It is on by default (
Sync.BalHealing=true); set it tofalseto go back to trie-node healing. snap/2 is advertised only when BAL healing can run. (#12945) - Dual-stack IPv4/IPv6 networking. RLPx, discv4 and discv5 listen on both families, ENRs advertise both, and there is a new
Network.ExternalIpV6override. (#12679, #12982, #12983, #13731) - Flat backend safety rails. A flat DB that RocksDB had to auto-repair is now re-synced instead of trusted. Unsafe flat activations are refused at start instead of silently corrupting or discarding state. (#13645, #13644)
- Reclaim the patricia trie after a trie→flat conversion.
FlatDb.DropPruningTrieState=truedeletes the old trie store on the next start once the flat DB owns the state (~227 GB on mainnet). Off by default. (#13572) - RocksDB 11 through Nethermind's own bindings. The RocksDB package is replaced with
Nethermind.RocksDbBindings(RocksDB v10 → v11): source-generated P/Invoke with no marshalling stubs, and every native handle held in aSafeHandle. (#12853) - New EF bootnodes. The EF bootnode entries for mainnet, Sepolia and Hoodi are replaced with the new NodeOps fleet: five dual-stack nodes running both discv4 and discv5. (#13313)
- More zkVM targets. Stateless guests for SP1 and OpenVM ship alongside ZisK, and the ZisK toolchain moves to 1.3.0-alpha. (#13435, #13769, #13743)
Performance
- EVM dispatch and call frames: 3.8–4.5% faster block processing on the superblocks, realblocks and fusaka benchmark sets. (#13189)
- Storage values held as
UInt256: SLOAD 9–18%, SSTORE 42% and TSTORE ~50% faster, with no allocations on those paths. (#13420) - EVM stack in limb layout: 45–53% faster ADD, 16–36% faster SUB, and 9–18% faster shifts. (#13323)
- JUMPDEST analysis: worst-case analysis of 64 KiB initcode (a 200 MGas block of PUSH1/JUMPDEST patterns) drops from 0.4–3.2 s to 22–153 ms, depending on the SIMD tier. Initcode is analysed on first use. (#13810)
- Trie and storage-key hashing: 35–80% less time on transaction and receipt-root workloads. (#13552)
- Prewarming: a single fan-out while senders arrive gives superblocks processing a median −4.4%, P99 −27.9%, and +7.6% MGas/s. Prewarming and trie concurrency caps are removed, and parallel work is budgeted across the state root, blooms, the receipts root and prewarming (2–4% faster processing). (#13640, #13388, #13770)
- Carried caches: pre-block account and storage caches are carried across blocks. (#13100)
- Discovery traffic: on a warm-started Hoodi node, discovery traffic fell by 90% (152 KiB/s → 15 KiB/s), and the standalone bootnode uses ~44% less working set. (#13122)
- Snap sync: downloads are bounded and overlap with response processing. Whale-storage verification in
FlatTrieVerifieris parallelised. (#12623, #12615) - RPC:
eth_call,eth_estimateGasandeth_createAccessListno longer hash the transaction on every run (~0.2 ms on large calldata) (#13804). The stream interpreter is off by default because it lost on every measuredeth_callshape.eth_getFilterChangesis served from shared block logs. (#12999, #13742) - Intel hybrid CPUs: block processing is pinned to the performance cores by default (
Blocks.ProcessingCores). Nothing changes on other CPUs. (#13717)
⚠️ Breaking changes
If you run a node (config and startup)
- poacore / poacore_validator now ship
FlatDb.Enabled=falsebecause they use FastSync without SnapSync (#13644). A node on those configs that synced on 2.0.0 is on the flat backend, since flat is 2.0.0's default. On 2.1.0 it refuses to start (Refusing --FlatDb.Enabled=false on an existing flat DB). Either pass--FlatDb.Enabled=true, or delete theflat,flatHistoryandpersistedSnapshotdirectories and resync the state. --FlatDb.Enabled=falseon an existing flat DB is refused. In 2.0.0 the node silently discarded the state and resynced (#13428). It now stops with an error. (#13644)- Flat +
Sync.FastSync=true+Sync.SnapSync=falseis refused on a fresh node. Legacy tree sync on the flat backend can leave holes in the state. An already-synced node keeps running and logs a warning. The exception is importing from patricia (FlatDb.ImportFromPruningTrieState=trueon a datadir that holds patricia state). (#13644) - New
FlatDb.OnRepairsetting, defaultResync. If RocksDB auto-repairs the flat DB, the node now wipes the flat state and runs state sync again. Headers, bodies and receipts are kept. Archive nodes synced from genesis cannot snap-resync. SetFlatDb.OnRepair=Ignoreand plan a resync yourself if a repair is ever reported. (#13645) Receipt.MaxBlockDepthdefault raised back from 1,000 to 10,000, and the limit is now also enforced oneth_getFilterLogs. On nodes with the log index, only blocks the index cannot serve count towards the limit. A filter created byeth_newFilterover a wider range is still accepted, buteth_getFilterLogson it fails with-32602. (#13131)- Removed config keys:
FlatDb.EnablePreimageRecording,Db.PreimageDbRocksDbOptions,Db.PreimageDbAdditionalRocksDbOptions(#13690),LogIndex.VerifyRpcResponse(#13131), andGrpc.Enabled,Grpc.Host,Grpc.Portalong with the gRPC endpoint (#13330). A JSON config that still sets them logsInvalid configuration settingsat startup. Remove them from configs, environment variables and command-line flags. Merge.CompactMemorydefault changed fromYestoNo. This removes GC compaction stalls fromengine_newPayload. Steady-state RSS may be somewhat higher. (#13476)Init.LogRulesno longer routes to Seq, andSeq.MinLevelis now the floor for the Seq target. To send a namespace's Trace output to Seq, add an explicitwriteTo="seq"rule inNLog.config. (#13419)- Dual-stack by default. With
Network.LocalIpunset, the P2P TCP and discovery UDP listeners now try to bind[::]on Linux and Windows, so the P2P port may now be reachable over IPv6. Check your firewall. macOS stays IPv4-only. SetNetwork.LocalIp=0.0.0.0to keep IPv4-only. (#12982) Pruning.FullPruningTrigger=VolumeFreeSpacewith a threshold too low to ever trigger now logs a startup warning. Automatic pruning was already not running in that case, so nothing new is broken. (#13485)
If you run a Flashbots relay
Flashbots.EnableValidationnow defaults totrue.flashbots_validateBuilderSubmissionV3checks the submitted block's state root, receipts root, gas used and logs bloom against its execution. Set it tofalseexplicitly to get the old behaviour. (#13452)
If you integrate over JSON-RPC / Engine API
eth_getHeaderByNumber("pending")returnsnull, matching go-ethereum and execution-apis#877. (#13082)proof_getTransactionByHash/proof_getTransactionReceiptreturnresult: nullfor a transaction they cannot serve, instead of a-32000error.proof_getTransactionReceiptreturns-32002when the block can no longer be retraced. (#13366)- Parity
vmTracestack pushes are hex quantities (0x0,0x1), not byte strings. Word operations now report their pushes. (#13750, #13487) - Other trace output changes. Empty trace selections are accepted.
trace_getkeeps lookup errors instead of replacing them.trace_filterreturns an error when the requested history is unavailable, and bufferedtrace_filternow applies a singleJsonRpc.Timeoutto the whole request. Deleted-account fields carry deletion markers.callTraceromitstoon a failed top-level CREATE. (#13667, #13676, #13677, #13668, #13078) - **EIP-3155 /
structLogstraces are corrected...
zkVM guests v2.1.0-unstable+5c2a2768
Release notes
SP1 and OpenVM support
This release introduces initial support for SP1 and OpenVM zkVMs.
Updates and improvements for ZisK
In addition to ZisK v1.3.0-alpha support, this release brings impressive performance improvements:
| Block 25,532,382 | Old guest | This release | Change |
|---|---|---|---|
| Total cost | 75.66B | 36.46B | −51.8% (2.1× cheaper) |
| Steps | ~704M | 305.7M | −56.6% (2.3× fewer) |
Guest binaries
Built from 5c2a2768fdac1930af35aadf609b61bc6f4af8ee with the following SHA-256 checksums:
| zkVM | SHA-256 |
|---|---|
| ZisK | 69b7975c8fcbd3604984018870632336b412c9772c374d2e593298c928c9348d |
| SP1 | efddc2291fdfa64949ce115791b74ce454f7bd6bf1248a018e5b68bb8d5e66e2 |
| OpenVM | 79a7cd7509b10b339d372711186764024f97be1f307b892351d0fc7614ac35b6 |
Build signature
The packages are signed with the following OpenPGP key: AD12 7976 5093 C675 9CD8 A400 24A7 7461 6F1E 617E
v2.0.0
Release notes
669 merged pull requests since 1.39.3, from 39 contributors.
Nethermind 2.0.0 is a hardened, faster, archive-capable execution client, built for Ethereum, its L2s, and beyond. It consolidates everything shipped in 2.0.0-rc and 2.0.0-rc2.
Most nodes upgrade in place with no resync. There are breaking changes — read Breaking changes before upgrading, especially if you run an archive node, set custom config keys, or build against Nethermind as a library or plugin.
Important
Upgrading from 1.39.x? This page is the complete list of breaking changes from 1.39.x to 2.0. It replaces the 2.0.0-rc and 2.0.0-rc2 notes; the 2.0.0-rc release page has been removed. Go through Breaking changes and the Upgrade checklist below.
Going straight to 2.1.0 or later? Apply this list first, then the 2.1.0 breaking changes.
⚠️ Breaking changes
If you run a node (config)
Db.FlushOnExitis now an enum, not a boolean. Values:None,WalOnly,Full. The default changes from full-flush toWalOnly. If your config, env var, or CLI still setstrue/false, the node fails to start — changetrue→Full,false→None.Blocks.PreWarmStateOnBlockProcessingwas replaced byBlocks.PreWarming. New enum values:None,Block,BlockAndMempool(defaultBlockAndMempool). The old key is now silently ignored (you'll get a warning, not a crash) — rename it or you lose your setting.- Numeric config keys are now unsigned. Negative values are rejected and the node fails to start. The one common case:
Receipt.TxLookupLimit: -1(the old "never index" sentinel) must become18446744073709551615. Receipt.MaxBlockDepthdefault lowered from 10000 → 1000. A singleeth_getLogsspanning more than 1000 blocks is now rejected unless the log index is enabled. If you rely on wide ranges: raiseReceipt.MaxBlockDepth, split the query, or enable the log index. 2.1.0 restores the 10,000 default (#13131).FlatDb.HistoryRetentionis required whenever you set a window size or a since-block.FlatDb.HistoryRetentionBlockson its own fails to start. A window size without a mode,Rollingwithout a size,SinceBlockwithout a block, or both numbers at once, are all refused.- A configured
FinalTotalDifficultyis no longer treated as "TTD reached" (#12555). Custom-FTD configs that relied on that inference will wait for the real TTD. - sepolia and hoodi default configs are now discv5-only (hoodi's static bootnode list was removed). Stock-config nodes on those networks discover peers via discv5 + DNS. Custom
DiscoveryConfigis unaffected. - Mainnet ancient-history barrier raised (block 15537394 → 24600000). Existing nodes keep all their data. Only new or resyncing nodes retain less pre-24.6M history by default.
If you run an archive node
- Archive configs now enable the flat-database backend with history (see New archive layout below). Your existing patricia archive DB keeps working (the new flag is ignored on an existing DB — nothing corrupts). To actually run the new flat archive you must resync, or set
FlatDb.ImportFromPruningTrieState=truefor an in-place trie→flat import. Enabling flat history is forward-only — there is no backfill below the point you enable it.
If you integrate over JSON-RPC / Engine API
engine_newPayloadV5: a malformed block-access-list envelope now returns{"status":"INVALID", ...}(HTTP 200) instead of JSON-RPC error-32602. (#13012)trace_simulateV1: the response fieldstateChangeswas renamed tostateDiff. (#12892)- Receipt JSON on the
t8n/ direct-serialization path now emitsrootorstatus(mutually exclusive), not both. The standardeth_getTransactionReceiptpath is unchanged. (#12867) debug_traceCallnow uses a base fee of 0 for unpriced calls, matching go-ethereum. Reported gas figures change accordingly. (#12804)eth_maxPriorityFeePerGasreturned a gas price; it now returns a priority fee. (#13129)eth_getStorageAtposition parsing is stricter — spec-compliant hex-quantity clients are fine, but a client sending a bare number or un-prefixed string may now get a parse error. (Verify against your integrations.)- Amsterdam-gated (not active on mainnet yet, relevant if you test against devnets):
eth_callnow returns errors (out-of-gas, address collision, EF-prefix) where it previously returned0x;eth_estimateGasandeth_createAccessListreturn updated values. (#12806, #12971, #12970)
If you build against Nethermind (plugin / library authors)
- Many
IConfignumeric properties changed fromlong/inttoulong. This is source-breaking — recompile your plugins against 2.0.0.
Consensus / protocol
- EIP-7610 support removed. (#12935) No change on any live network — the storage-collision check is superseded by EIP-684 and was never activated as a fork. Only affects state-test / collision fixtures.
- Stricter RLPx/Snappy frame validation. (#12896) Malformed frames are now rejected/disconnected. Conformant peers (Geth, Besu, older Nethermind, CL relays) are unaffected — this is DoS hardening.
- Optimism
engine_signalSuperchainV1V0 byte layout corrected (7→8 bytes) to match op-geth/op-node. (#12805) OP-Stack operators only.
Dropped
ethernity-sepolianetwork removed (ethernity-mainnetis retained).
Upgrade checklist
From 1.39.x
- Stop the node. No resync is needed for a normal full node, and your existing patricia database stays patricia — it is detected at start.
- Audit your config for the breaking keys above. The ones that crash on start are
Db.FlushOnExit(bool→enum), any negative numeric value,Receipt.TxLookupLimit: -1, andFlatDb.HistoryRetentionBlockswithoutFlatDb.HistoryRetention. - Rename
Blocks.PreWarmStateOnBlockProcessing→Blocks.PreWarming(otherwise it is silently ignored). eth_getLogsusers: check whetherReceipt.MaxBlockDepth(now 1000) affects your queries.- Archive operators: decide between keeping your existing patricia archive (works as-is) or resyncing/importing to the new flat archive with history.
- Plugin/library authors: recompile against 2.0.0 (
IConfignumeric types changed). - Fresh nodes will serve snap. Turn it off with
Sync.SnapServingEnabled=falseif that is not what you want. - Start the node and confirm
2.0.0in the startup logs.
From 2.0.0-rc / 2.0.0-rc2
No database-format change and no resync. Do step 2 above (the FlatDb.HistoryRetention requirement arrived in rc2), then start.
Do not set --FlatDb.Enabled=false on an existing flat datadir — see Known issues.
Known issues
These were open at release against the flat backend, which is the default for a new database. A node that upgraded in place from 1.39.x keeps its patricia backend and is not exposed to any of them. Where a later release addresses an item, it is noted.
- A snap sync on the flat backend cannot resume across a restart. Every run clears the flat columns, so restarting mid-sync discards the state downloaded so far and starts again from zero. Plan an uninterrupted initial sync, or sync on
--FlatDb.Enabled=false(patricia/half-path), which does resume. A node that has reached the tip never re-enters snap, so this affects bring-up only. (#13601) - Copy-style full pruning is not available on the flat backend. A flat node accepts
Pruning.Mode=Hybrid,Pruning.FullPruningTrigger, andPruning.FullPruningThresholdMbwithout warning but never prunes, andadmin_prunereportsdisabled. If you depend on periodic full pruning, stay on the patricia backend for now. In-place upgrades from 1.39.x keep patricia and are unaffected. (#13600) From 2.1.0 the node logs a warning when an automatic full-pruning trigger is set on flat (#13644); pruning itself is still patricia-only. - Legacy (non-snap) state sync on the flat backend can produce a bad state. With
Sync.SnapSync=false, a restart during state sync can leave permanent account/storage holes (the trie is complete, the flat leaf is missing), and pivot changes can leave stale storage subtrees. Both surface later as a deterministicHeaderGasUsedMismatch. Use snap sync (the default), or resync on the patricia backend. (#13575, #13576) From 2.1.0 a fresh node refuses flat +Sync.FastSync=true+Sync.SnapSync=false(#13644). - A RocksDB auto-repair of a corrupted flat DB can silently drop leaves. The node then resumes as "already have state" and diverges from consensus. If RocksDB reports that it repaired your database, resync rather than continue. (#13577) Fixed in 2.1.0: a repaired flat DB is re-synced by default (
FlatDb.OnRepair=Resync, #13645). --FlatDb.Enabled=falseon an existing flat datadir silently discards the state and full-resyncs. The node does not refuse. The inverse (a patricia DB with the new flat default) is detected and protected. Do not pass that flag to an existing flat node. (#13428) Fixed in 2.1.0: the node refuses to start instead (#13644).
Two smaller JSON-RPC rough edges were also open at release: guard-rail rejections (-32002, -32005, 4444) still log one WARN per request (#13602), and "no state for that block" is answered with different error codes depending on the method (#13603). Both fixed in 2.1.0 (#13643).
Highlights
- Flat DB is the default state backend (#11931). `Fla...
v2.0.0-rc2
Important
Superseded by 2.0.0. The complete list of breaking changes from 1.39.x, including everything from 2.0.0-rc, is in the 2.0.0 breaking changes. The 2.0.0-rc release page has been removed.
Release notes
A second release candidate on top of 2.0.0-rc. Flat is now the default state backend for a fresh database, windowed archive config is explicit, and a set of sync, shutdown, and JSON-RPC fixes land on the RC.
No database-format change relative to 2.0.0-rc. An existing 2.0.0-rc does not need a resync.
Highlights
- Flat DB is the default for new state (#11931).
FlatDb.Enableddefaults totrue. A new node, or a resync, gets the flat backend. An existing patricia database is detected at start and stays patricia; an existing flat database stays flat. To sync a fresh node on patricia:--FlatDb.Enabled=false. - Explicit history-retention mode, plus
SinceBlock(#13162). Windowed archive is no longer "a non-zeroHistoryRetentionBlocks." The shape isFlatDb.HistoryRetention = None | Rolling | SinceBlock.SinceBlockkeeps everything from a fixed height onward and never prunes; below that height, reads fail closed. - Historical
eth_getProofon a flat archive (#13098). An unwindowed flat archive can serveeth_getProof(andproof_*) at covered historical heights. Off by default.
Fresh nodes on the default config also serve snap (Sync.SnapServingEnabled defaults on for the flat path). Set Sync.SnapServingEnabled=false if you do not want the extra outbound bandwidth. Existing patricia nodes are unaffected.
A patricia node upgraded to rc2 will still create empty flat column families on disk (the probe opens them before it notices the patricia state). Harmless extra disk and file descriptors; they are not used.
⚠️ Breaking changes (relative to 2.0.0-rc)
Coming from 1.39.x? Use the full list in the 2.0.0 breaking changes. On top of 2.0.0-rc, this release adds:
FlatDb.Enabledis default. Fresh / resyncing nodes get flat and snap-serving. Existing DBs are unchanged.FlatDb.HistoryRetentionis required whenever you set a window size or a since-block.HistoryRetentionBlocksalone fails to start. A window size without a mode,Rollingwithout a size,SinceBlockwithout a block, or both numbers at once, are all refused. That key only existed on the RC, so this is the moment to make the config honest rather than inferring forever.- A configured
FinalTotalDifficultyis no longer treated as "TTD reached" (#12555). Custom-FTD configs that relied on that inference will wait for the real TTD.
Sync, database & state
- Mainnet snap no longer livelocks on the last large-storage account; forced pivot updates are distance-guarded. (#13155, #13200 / #13310)
- A stalled snap sync is visible at the default log level. (#13248 / #13257)
- A malformed header response no longer stalls fast-headers. (#13019)
- Receipt bodies are looked up by number and hash. (#13139)
- In-flight sync dispatch is drained before the database is torn down, so a graceful restart of a syncing node no longer SIGSEGVs. (#13154 / #13309)
- Warmer misses no longer escape through shared trie children. (#13272)
- Compacted snapshots are released after base conversion; finalized forks are pruned from persisted snapshots. (#13223, #13230)
- Full-pruning snapshot trigger is measured from the pruning boundary. (#13199 / #13308)
JSON-RPC & Engine API
- Streamed
trace_*keeps the module rented until the result is written. Concurrent traces no longer collide on the overridable world scope. (#13095) - Unauthenticated input no longer produces empty HTTP 500s, leaked stack traces in
error.data, or a WARN flood of-32602s. A chunk-size ≥0x80000000is HTTP 400. Deep recursiveeth_estimateGasno longer answers-32603 "Stack empty."(#13194, #13195, #13197, #13198, #13156 / #13251) - A missing-argument marker on a required parameter is rejected as
-32602, not an NRE. (#13235) - Out-of-memory on the RPC path is logged without formatting the request. (#13225)
- The chainspec-misconfiguration warning no longer fires as a false positive; JSON-RPC logs when it actually opens. (#13202, #13203 / #13255)
eth_maxPriorityFeePerGasreturned a gas price; it now returns a priority fee. (#13129)- Each
engine_getPayloadresponse is built from a single block candidate; the improvement context of a replaced payload is disposed. (#13093, #13206)
Txpool, networking & other
- Corrupt light-blob records are skipped on pool restore instead of aborting it; blob persistence after revalidation is atomic. (#13032, #13045)
- Undersized ECIES ciphertexts throw controlled exceptions. (#13135)
- Kademlia discovery traffic is reduced on a healthy table. (#13124)
- Rlp/TxDecoder type-initializer cycle broken. (#13158)
Upgrade checklist
From 2.0.0-rc
- Stop the node. No resync.
- If your config sets
FlatDb.HistoryRetentionBlocks, addFlatDb.HistoryRetention=Rollingor the process will exit on start. - Leave
FlatDb.Enabledalone unless you are starting a new datadir and you want patricia (false). - Fresh nodes will serve snap. Turn it off with
Sync.SnapServingEnabled=falseif that is not what you want. - Start and confirm
2.0.0-rc2in the startup logs. A patricia node should log that an existing patricia state was detected.
From 1.39.x
Follow the 2.0.0 upgrade checklist: it covers 1.39.x → 2.0 in full, including the 2.0.0-rc items (Db.FlushOnExit bool→enum, unsigned numerics, Receipt.TxLookupLimit: -1, rename Blocks.PreWarmStateOnBlockProcessing) and the rc2 items above. A 1.39 patricia DB stays patricia.
Do not set --FlatDb.Enabled=false on an existing flat datadir. The node does not refuse; it discards the flat state and full-resyncs. The inverse (patricia DB + default flat) is detected and protected. (#13428) Fixed in 2.1.0: the node refuses to start instead (#13644).
What's Changed
- Reduce Kademlia discovery traffic on healthy tables by @flcl42 in #13124
- Exercise block downloader tests with flat and trie state backends by @asdacap in #13328
- feat(flat): explicit flat-history retention mode, with SinceBlock by @svlachakis in #13162
- fix(flatdb): release compacted snapshots after base conversion by @benaadams in #13223
- fix(flat): prevent warmer misses escaping through shared trie children by @benaadams in #13272
- fix(rpc): reject a missing-argument marker on a required parameter by @Matgothmog in #13235
- fix(jsonrpc): do not format the request when logging an OutOfMemoryException by @benaadams in #13225
- fix(rpc): stop unauthenticated input causing unhandled exceptions, empty 500s, leaked traces and WARN floods by @stdevMac in #13251
- feat(sync): make a stalled snap sync visible at default log level by @stdevMac in #13257
- test(jsonrpc): make Nethermind.JsonRpc.Test safe to run twice at once by @stdevMac in #13256
- fix(rpc): drop the chainspec-misconfiguration false positive, and say when JSON-RPC opens by @stdevMac in #13255
- fix(pruning): measure the full-pruning snapshot trigger from the pruning boundary by @stdevMac in #13308
- fix(sync): drain in-flight sync dispatch before database teardown by @stdevMac in #13309
- fix(snap): recover a stalled large-storage account and rate-limit the forced pivot by @stdevMac in #13310
- Enable flat DB by default; flip CI backend coverage by @asdacap in #11931
- feat(flat-history): historical eth_getProof from archive commitments by @svlachakis in #13098
- fix(rpc): keep the module rented until a streamed result has been written by @kamilchodola in #13095
- fix: eth_maxPriorityFeePerGas returned a gas price by @MysticRyuujin in #13129
- fix(rlp): break the Rlp/TxDecoder type initializer cycle by @LukaszRozmej in #13158
- fix(sync): stop a malformed header response from stalling fast-headers sync by @dipkakwani in #13019
- fix(flatdb): prune finalized forks from persisted snapshots by @benaadams in #13230
- fix(engine): build each getPayload response from a single block candidate by @dipkakwani in #13093
- fix: dispose the improvement context that replaces a retrieved payload by @LukaszRozmej in #13206
- ci: capture a dump when a test host hangs by @LukaszRozmej in #13149
- fix(sync): look up receipt bodies by number and hash by @LukaszRozmej in #13139
- Reject undersized ECIES ciphertexts with controlled exceptions by @flcl42 in https://github.com/NethermindEth/nethermind/pull...
v1.39.3
Important
This is a mandatory update for all node operators. Please upgrade at your earliest convenience.
Release notes
A patch release on top of 1.39.2 with reliability and hardening fixes across block processing, networking, and request decoding. No consensus or database-format changes, so it's a drop-in upgrade from any 1.39.x version.
Overview
3 changes since 1.39.2:
- Hardened ABI decoding against malformed input (#12588)
- Fixed pooled-memory cleanup in block processing and networking (#12034)
- Reduced allocations in EIP-6110 deposit-request decoding (#12185)
What's Changed
- Validate ABI decode allocation bounds by @flcl42 in #12588
- Fix undisposed array-pool list leaks by @batrr in #12034
- perf(requests): reuse a stack buffer for deposit request decoding by @AnkushinDaniil in #12185
- chore: update Directory.Build.props for 1.39.3 by @stdevMac in 28cbe2a0
Full Changelog: 1.39.2...1.39.3
Build signatures
The packages are signed with the following OpenPGP key: AD12 7976 5093 C675 9CD8 A400 24A7 7461 6F1E 617E
Guest for ZisK r8
Release notes
This is a public preview of the Nethermind guest for ZisK.
- Requires ZisK v1.0.0-alpha
- Supports standard chains and glamsterdam-devnet-7
Build signature
The package is signed with the following OpenPGP key: AD12 7976 5093 C675 9CD8 A400 24A7 7461 6F1E 617E
v1.39.2
Important
Given the number of CVEs from Microsoft this release fixes it is mandatory for all node operators.
Release notes
This is a patch release on top of 1.39.1 that updates the .NET dependencies to Microsoft's July 2026 servicing release (10.0.10), which 17 CVE security fixes, and makes the eth_getLogs block-range limit explicit and configurable.
Overview
4 changes since 1.39.1:
- .NET packages updated to 10.0.10 — Microsoft's July 2026 servicing update, which addresses several security vulnerabilities in .NET (#12449)
- Explicit, configurable
eth_getLogsblock-range limit — theReceipt.MaxBlockDepthoption (default 10,000 blocks) is now documented and applied consistently, including when"useIndex": falseis requested; requests exceeding the range are rejected with an "invalid params" (32602) error. Set to0to disable; ignored when the log index is enabled (#12509) - Routine dependency bumps:
Microsoft.IdentityModel.JsonWebTokens,System.CommandLine,Nethermind.Crypto.SecP256r1, and a RocksDB package rebuild (10.10.1.649 → 10.10.1.1747; same native RocksDB version) (#12449, #12491)
What's Changed
- chore: Update packages by @rubo in #12449
- hotfix: Configurable and explicit eth_getLogs scan limit by @alexb5dh in #12509
- Update 1.39.2 by @stdevMac in #12491
- chore: update Directory.Build.props for 1.39.2 by @stdevMac in 6a0e3c427c
Full Changelog: 1.39.1...1.39.2
Build signatures
The packages are signed with the following OpenPGP key: AD12 7976 5093 C675 9CD8 A400 24A7 7461 6F1E 617E
v1.39.1
Release notes
This is a patch release on top of 1.39.0 with a round of bug fixes and reliability improvements across snap sync, networking, JSON-RPC, and the experimental Flat DB.
Overview
Full diff: 1.39.0...1.39.1
8 changes since 1.39.0. Highlights:
- Flat DB (experimental, opt-in) — fixed a disposal race between shutdown and in-flight trie-warmer jobs (#12237)
eth_simulateV1now bounds the total block expansion, not just each inter-block gap (#12210)- Bad-block store is bounded by entry count as intended, instead of comparing against the DB byte size (#12225)
- Quieter logs — RLP limit diagnostics toned down (#12130)
Highlights
Sync
- Reject malformed snap range proofs instead of throwing (#12187)
- Verify the hash of trie nodes recovered via snap heal (#12200)
Networking
JSON-RPC & Engine API
- Bound
eth_simulateV1total block expansion, not just each gap (#12210) - Side-effect-free invalid-chain query and atomic node get-or-create in the invalid-chain tracker (#12208)
Storage & state
- Bound
BadBlockStoreby entry count, not DB byte size (#12225) - Flat DB (experimental, opt-in): lease the read-only bundle for in-flight trie-warmer jobs (#12237, fixes #12079)
What's Changed
- fix(snap): reject malformed range proofs instead of throwing by @AnkushinDaniil in #12187
- Tone down RLP limit logging by @flcl42 in #12130
- fix(network): reject zero-size RLPx frames in ZeroFrameDecoder by @AnkushinDaniil in #12202
- fix(synchronization): verify hash of snap-heal recovered trie node by @AnkushinDaniil in #12200
- fix(jsonrpc): bound eth_simulateV1 total block expansion, not just each gap by @AnkushinDaniil in #12210
- fix(merge): side-effect-free invalid-chain query, atomic node get-or-create by @AnkushinDaniil in #12208
- fix(blockchain): bound BadBlockStore by entry count, not DB byte size by @AnkushinDaniil in #12225
- fix(flatdb): lease the read-only bundle for in-flight trie warmer jobs by @AnkushinDaniil in #12237
- chore: update Directory.Build.props for 1.39.1 by @stdevMac in b7c51322a1
Full Changelog: 1.39.0...1.39.1
Build signatures
The packages are signed with the following OpenPGP key: AD12 7976 5093 C675 9CD8 A400 24A7 7461 6F1E 617E
v1.39.0
Release notes
This release focuses on node robustness, Flat DB durability — alongside the eth/71 wire protocol, a reworked discovery stack, a large JSON-RPC features-and-correctness batch, continued Block-level Access Lists (EIP-7928) maturation, and a broad round of EVM, precompile, and state performance work.
OP Karst reminder: the OP Karst hardfork (shipped in 1.38.1 and included here) activates on OP Mainnet: Wed, Jul 8, 2026 at 16:00:01 UTC. OP Stack operators must be on 1.38.1 or later before then.
Overview
Full diff: https://github.com/NethermindEth/nethermind/compare/1.38.1…1.39.0
337 changes since 1.38.1. Highlights include restart-safety fixes for header sync and pivot selection, a Flat DB durability overhaul, the eth/71 wire protocol, a rework of discv4 discovery, SSZ-REST transport for the Engine API, eight new JSON-RPC methods with a large correctness batch, EIP-7928 (BALs) devnet-7 support with major performance work, EraE fixes, and chain-specific improvements for XDC, Taiko, Optimism, and Arbitrum.
Highlights
Sync & restart safety
- Recover header sync after a lost chain level on unclean shutdown (#11994, fixes #8029)
- Unwedge
UpdatingPivotfor nodes restarted before the first pivot update (#11995) - Flush all column families in
ColumnsDb.Flush— makes column-DB writes (incl. Flat DB) durable across restarts (#12223, fixes #11993) - Refresh snap pivot instead of punishing the only peer (#11569, fixes #6803); support infinite pivot-update attempts via
1(#11600, fixes #5992) - Fix shutdown race in SnapProvider (#11807); accept receipts with zero bloom from peers (#11743); prevent negative RequestSize crash when the beacon pivot advances mid-sync (#11478)
- New
Sync.StaticSnapPivotoption for fixed-pivot snap sync from a frozen peer (#11943)
Flat DB (experimental, opt-in) durability & hardening
- Crash-durable snap finalize with a cheap restart wipe (#11997); preserve format markers when clearing the flat DB (#11996)
- Force-persist the head-reachable fork instead of an arbitrary one (#11967); persistence cache (#12035); prune orphaned non-canonical snapshots on persist (#11739)
- RLP-wrap storage slot values behind a versioned flag (#11909) with legacy-DB detection (#11975); improved state-backend compatibility and auto-detection (#11911, #11404)
- Stagger compaction per instance (#11756) with a
CompactionOffsetconfig to pin the schedule (#11958)
Networking & discovery
- eth/71 wire protocol (#10844); eth/70 hardening (#11456, #11615, #11754); eth/69 BlockRangeUpdate validation (#11796)
- discv4 rework (#8616) and discovery now defaults to V4 (#11614); faster discv4 timeout handling (#11859)
- Disconnect peers on unknown protocol message type (#11266); reduced per-message and per-peer allocations across Eth, Snap, and RLPx (#11639)
JSON-RPC
- New methods:
eth_getHeaderByHash/eth_getHeaderByNumber(#11531),eth_getRawTransactionByBlockHashAndIndex/eth_getRawTransactionByBlockNumberAndIndex/eth_sendRawTransactionSync(#11521),eth_signTransaction(#11517),eth_baseFee(#11522),debug_intermediateRoots(#11524),eth_capabilities(#11438),proof_call(#11732),proof_getProofWithMeta(#11498) - Streaming responses for
debug_*andtrace_*(#11693, #11755, #11781) with a synchronous-wait fix (#12006) - Correctness batch:
eth_estimateGaszero/revert semantics (#11780, #11783), reject EIP-1898 blockHash+blockNumber (#11777), reject oversized blob calls (#11782),eth_simulateV1fixes (#11506, #11665, #11841),eth_createAccessListreverted-frame accesses (#11431), omit non-specerrorfield from receipts (#11454), zero hashes for absenteth_getProofaccounts (#11912) - Route
eth_callthrough a shareable tx-processor pool (#11548); drain in-flight requests before disposing databases on shutdown (#11845)
Engine API
- SSZ-REST transport (#11301) with Accept-negotiation fix (#11856) and capabilities-warning fix (#12176)
- Fix forkchoice validation order (#11681); validate FCU safe/finalized by ancestry when main-chain markers are outdated (#11746); guard against null safe/finalized hash (#12110)
- Bound dangling block-cache growth (#11426); capture bad blocks at pre-process rejection stages (#11696)
Block-level Access Lists (EIP-7928)
- BAL devnet 6 and devnet 7 support (#11436, #11561) incl. the EIP-8037 intrinsic-gas cap (#11635, #11579)
- Network encoding fix (#11950), RLP fix (#11861), validation refactor (#11878), activation only when needed (#11795)
- Performance series: verify-only fast path (#11659), account-presence bitmap (#11661), single-pass build (#11676), reduced recording overhead on warm reads (#11905), allocation cuts (#11702, #11725)
Performance
- Fast ETH-transfer execution path (#11804); TrieWarmer reworked onto ThreadPool (#11848); tightened
CALLhot path with EIP-7702 delegation-to-precompile fix (#11547) - Precompiles: BN254 pairing optimizations (#11916, #11888), BLS G1MSM decoding (#11889), per-thread RIPEMD-160 (#11890), ModExp
int32overflow fix (#11692) - State: storage-trie warm-up driven from writes (#11409), RocksDB native memory reported to GC (#11453), lock-free
ChainHeadSpecProvider(#11618)
Chain-specific
- XDC: XDPoS RPC module (#10553), rewards upgrade (#11016), HotStuff and QC-manager refactors (#11711, #11644), snapshot recovery (#11602), discovery (#11527), sync fixes
- Taiko: Unzen scheduled on Taiko Hoodi (#11977) with zk-gas recalibrations (#11749, #11896, #11940); beacon-sync deadlock fix (#11648); engine payload aligned with alethia-reth (#11776)
- Optimism: OP Karst fork (#11917) and Superchain registry refresh with Base removal (#11655, #11852) — already shipped to OP operators in 1.38.1
- Arbitrum groundwork: ArbOS 60 multi-gas constraints (#10765) and EVM extension points
- zkEVM/stateless: migration to zkVM/SSZ standards (#11481, #11625), EEST stateless-execution tests (#11908), intrinsic zk gas (#11584)
Other notable
- EraE (EIP-4444) fixes and spec updates (#11727, #11771, #11772, #11928)
- Structured console logging via
-logging-format(#11610); non-default config values shown at startup (#11523); health UI behind a reverse proxy (#11946) - StatsAnalyzer plugin (#7345, #11766)
⚠️ Breaking / behavior changes
- Legacy
BloomStorageremoved (#11906) — the bloom-filter index database and its configuration are gone; log queries rely on the current log-index path. - Discovery defaults to V4 (#11614).
- Per-method JSON-RPC metrics are now enabled by default (#11494).
- Non-spec
errorfield removed from transaction receipts in JSON-RPC responses (#11454). - IPC socket is restricted to owner-only permissions when configured (#9449).
What’s Changed
- Add NETH004 analyzer banning ConcurrentDictionary.Keys/.Values by @asdacap in #11462
- fix: prevent negative RequestSize crash when beacon pivot destination advances mid-sync by @asdacap in #11478
- feat(zkevm): Migrate to zkVM standards by @rubo in #11481
- XDC - Rewards Upgrade by @cicr99 in #11016
- feat(zkevm): Enable BAL in stateless execution by @rubo in #11505
- test: regression tests for #9002 - barrier decrease after partial sync leaves feed stuck by @divi2806 in #11483
- RLP tx decoding fixes by @alexb5dh in #11496
- perf: report BloomFilter unmanaged allocation to GC by @asdacap in #11503
- fix: enable EnablePerMethodMetrics by default by @deffrian in #11494
- chore: Update dependencies by @benaadams in #11512
- eth/71 by @flcl42 in #10844
- fix: drop buffered frame bytes on
FrameQueue.Clearby @grubbyTimes in #11510 - perf(state): drive storage trie warm-up from writes via HintSet by @asdacap in #11409
- feat: BAL recorder plugin — record and replay block access lists for prewarming benchmarks by @asdacap in #11276
- fix(ReceiptForRpc): omit non-spec
errorfield from receipt JSON-RPC responses by @manusw7 in #11454 - fixed half-empty trace result by @DarkLord017 in #11466
- XDC Fix sync by @batrr in #11509
- Improve eth/70 checks by @flcl42 in #11456
- Minor fixes from AI audit by @alexb5dh in #11406
- fix: Fix dependency caching by @rubo in #11499
- Bal devnet 6 by @benaadams in #11436
- fix: stabilize ParallelUnbalancedWork fault propagation + flaky engine tests by @LukaszRozmej in #11534
- Eliminate ForcedNumberConversion boxing on set by @benaadams in #11536
- RPC: add
eth_getHeaderByHash,eth_getHeaderByNumberby @svlachakis in #11531 - Return remainder buffer to pool in KeccakHash.UpdateFinalTo by @benaadams in #11532
- Bump up the version to 1.39...
Guest for ZisK r7
Release notes
This is the first public preview of the Nethermind guest for ZisK.
- Requires ZisK v1.0.0-alpha
- Supports standard chains and glamsterdam-devnet-5
Build signature
The package is signed with the following OpenPGP key: AD12 7976 5093 C675 9CD8 A400 24A7 7461 6F1E 617E