From 6d0e89adacca44255bd330eb03b3be42d05d7564 Mon Sep 17 00:00:00 2001 From: Stavros Vlachakis <89769224+svlachakis@users.noreply.github.com> Date: Tue, 1 Sep 2026 11:51:55 +0300 Subject: [PATCH 1/8] docs: archive node shapes and configuration for 2.0 --- docs/fundamentals/archive-nodes.md | 53 +++++++++++++++++++++++++ docs/fundamentals/history-pruning.md | 4 ++ docs/fundamentals/performance-tuning.md | 2 +- docs/fundamentals/private-networks.md | 2 +- 4 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 docs/fundamentals/archive-nodes.md diff --git a/docs/fundamentals/archive-nodes.md b/docs/fundamentals/archive-nodes.md new file mode 100644 index 0000000000..88d2e787e4 --- /dev/null +++ b/docs/fundamentals/archive-nodes.md @@ -0,0 +1,53 @@ +--- +title: Archive nodes +sidebar_position: 8 +--- + +Starting with Nethermind 2.0, archive functionality is built on the flat database: per-block state changesets captured during ordinary syncing answer historical queries, with no extra database and no special sync mode. Three archive shapes are available, all reached the same two ways - a full sync from genesis, or a snap sync to the tip that captures history from the pivot onwards. + +Two independent groups of configuration options compose: + +- `FlatDb.History*` governs historical **state** - what answers `eth_call`, `eth_getBalance`, and `eth_getStorageAt` at old blocks. +- `History.*` governs historical **blocks and receipts** - what answers `eth_getBlockBy*`, `eth_getTransactionReceipt`, and `eth_getLogs`. See [History pruning](./history-pruning.md). + +## Archive shapes + +- **Full archive** answers every historical query at every height, state and receipts, from genesis. +- **Windowed archive** answers everything a full archive does, but only for the last [`FlatDb.HistoryRetentionBlocks`](./configuration.md#flatdb-historyretentionblocks) blocks. Older queries are refused with a pruned-history error - never answered wrongly from live state. Disk stays bounded: the pruner reclaims continuously as the window rolls. +- **Address-slice archive** is a windowed node whose named contracts additionally answer to their full slice depth - state, logs, and transactions - while everything else rolls with the window. + +## Configuration + +| Setting | Full archive | Windowed archive | Address-slice archive | What it controls | +|---|---|---|---|---| +| [`FlatDb.Enabled`](./configuration.md#flatdb-enabled) | `true` | `true` | `true` | The flat database; everything below builds on it. | +| [`FlatDb.HistoryEnabled`](./configuration.md#flatdb-historyenabled) | `true` | `true` | `true` | Captures per-block state changesets - historical state queries answer from these. | +| [`FlatDb.HistoryRetentionBlocks`](./configuration.md#flatdb-historyretentionblocks) | `0` (default) | e.g. `450000` | e.g. `450000` | The state-history window, in blocks below the tip. `0` keeps state history from genesis. | +| [`FlatDb.HistorySliceAddresses`](./configuration.md#flatdb-historysliceaddresses) | unset | unset | e.g. `0xC02a...,0xA0b8...:2000000` | Contracts kept queryable beyond the general window: their state rows survive pruning, and every block one of these addresses appears in keeps its receipts and full body, so logs and transactions stay answerable. `addr` retains forever; `addr:N` retains while a height is within `N` blocks of the head. | +| [`History.Pruning`](./configuration.md#history-pruning) | `Disabled` (default) | `Rolling` | `Rolling` | Block-and-receipt expiry. Independent of state history, but a windowed node normally rolls both. | +| [`History.RetentionEpochs`](./configuration.md#history-retentionepochs) | - | default `82125` | default `82125` | How many epochs (32 blocks each) of bodies and receipts the rolling pruner keeps. Must be at least the chain's `minHistoryRetentionEpochs` chainspec parameter. | +| [`LogIndex.Enabled`](./configuration.md#logindex-enabled) | recommended | recommended | recommended | The address/topic to block-number index behind fast `eth_getLogs`. Builds over whatever receipts the node stores. | +| [`Receipt.TxLookupLimit`](./configuration.md#receipt-txlookuplimit) | `0` | `0` | `0` | `0` keeps the transaction-hash lookup index for every stored height; retained sliced heights keep their entries either way. | +| [`Sync.AncientBodiesBarrier`](./configuration.md#sync-ancientbodiesbarrier) / [`Sync.AncientReceiptsBarrier`](./configuration.md#sync-ancientreceiptsbarrier) | `0` | - | - | A full archive that should serve receipts from genesis must also download them; see [History pruning](./history-pruning.md). | + +Every archive setting is default-off: a node that configures none of them behaves exactly as before. + +:::warning Important +Setting `FlatDb.HistoryRetentionBlocks` to a non-zero value selects the windowed row format and requires fresh flat history: enabling it on an existing unwindowed flat-history database is refused, and there is no in-place conversion. Start with a fresh sync. +::: + +:::warning Important +Do not turn on [full state pruning](./state-pruning.md) on an archive node, as these are two opposing features. Set [`Pruning.Mode`](./configuration.md#pruning-mode) to `None`. +::: + +## Historical queries and the window + +Within the window, the node answers historical RPC exactly like a full archive. Below it, queries fail closed: historical state reads (`eth_call`, `eth_getBalance`, `eth_getStorageAt`) below the window return a pruned-history error instead of resolving against live state. + +On an address-slice node, reads below the general window serve only the sliced addresses and fail closed for everything else. Answering sliced logs below a previously pruned boundary requires `History.Pruning` to stay enabled: at startup, the pruner validates from which depth each slice's logs are provably retained, and without it those reads fail closed. + +## Notes + +- A slice retention shallower than the general window is refused at startup, because it would delete an address's rows inside the advertised window. +- The state-history pruner paces itself with [`FlatDb.HistoryPruneIntervalBlocks`](./configuration.md#flatdb-historypruneintervalblocks) (default `1024`) and [`FlatDb.HistoryPrunePassBudgetSeconds`](./configuration.md#flatdb-historyprunepassbudgetseconds) (default `5`). The pass budget must exceed the longest historical query the node serves, since deletes wait for in-flight historical reads. +- [`FlatDb.HistoryVerifyEveryBlock`](./configuration.md#flatdb-historyverifyeveryblock) (default off) runs a one-shot background proof on unwindowed archives: it rebuilds the state root from history rows at every covered block and compares it against the node's own headers. Memory usage follows state size. diff --git a/docs/fundamentals/history-pruning.md b/docs/fundamentals/history-pruning.md index ff12799d4d..be5abd35d3 100644 --- a/docs/fundamentals/history-pruning.md +++ b/docs/fundamentals/history-pruning.md @@ -21,6 +21,10 @@ Removing history that is already stored is a separate, opt-in step controlled by Pruning never removes the genesis block or anything at or above the sync pivot. Use [`History.PruningInterval`](./configuration.md#history-pruninginterval) and [`History.PruningTimeoutSeconds`](./configuration.md#history-pruningtimeoutseconds) to control how often it runs and how long a single pass may take. +Blocks in which an address listed in [`FlatDb.HistorySliceAddresses`](./configuration.md#flatdb-historysliceaddresses) appears keep their receipts and bodies beyond the rolling window, so logs and transactions for those contracts stay answerable; see [Archive nodes](./archive-nodes.md). + +`History.Pruning` removes blocks and receipts only. Historical state has its own, independent retention; see [Archive nodes](./archive-nodes.md). + ## Era1 format The pre-Merge historical data is serviced in [Era1](https://github.com/status-im/nimbus-eth2/blob/stable/docs/e2store.md#era-files) format, which is an archival format initially designed for the consensus layer by Nimbus. diff --git a/docs/fundamentals/performance-tuning.md b/docs/fundamentals/performance-tuning.md index 9599904aca..0240f06211 100644 --- a/docs/fundamentals/performance-tuning.md +++ b/docs/fundamentals/performance-tuning.md @@ -1,6 +1,6 @@ --- title: Performance tuning -sidebar_position: 8 +sidebar_position: 9 --- By default, Nethermind is configured for general use cases that fit well for most users. However, to improve various aspects of Nethermind performance, there are options for different subsystems that can be configured for your specific needs. diff --git a/docs/fundamentals/private-networks.md b/docs/fundamentals/private-networks.md index 586b5c9eda..48d467f338 100644 --- a/docs/fundamentals/private-networks.md +++ b/docs/fundamentals/private-networks.md @@ -1,7 +1,7 @@ --- title: Private networks description: Use Kurtosis to deploy a private Ethereum devnet with Nethermind and any consensus client at any scale you need, wherever you need it. -sidebar_position: 9 +sidebar_position: 10 --- This guide will walk you through using [Kurtosis `ethereum-package`](https://github.com/ethpandaops/ethereum-package) to spin up a private, proof-of-stake (PoS) Ethereum devnet with three full Ethereum nodes locally over Docker. At the end of the guide, you will learn how to scale up your testnet on Kubernetes as well as enable optional services for your local testnet, such as network observability tools (e.g., Grafana, Prometheus) and Flashbot's `mev-boost` infrastructure to simulate MEV workflows. From 410a66525e4944f3299be8e17526e3a539789445 Mon Sep 17 00:00:00 2001 From: Stavros Vlachakis <89769224+svlachakis@users.noreply.github.com> Date: Tue, 1 Sep 2026 11:58:19 +0300 Subject: [PATCH 2/8] docs: receiptless archive via Receipt.DeriveFromState --- docs/fundamentals/archive-nodes.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/fundamentals/archive-nodes.md b/docs/fundamentals/archive-nodes.md index 88d2e787e4..d5e93f2103 100644 --- a/docs/fundamentals/archive-nodes.md +++ b/docs/fundamentals/archive-nodes.md @@ -28,6 +28,7 @@ Two independent groups of configuration options compose: | [`History.RetentionEpochs`](./configuration.md#history-retentionepochs) | - | default `82125` | default `82125` | How many epochs (32 blocks each) of bodies and receipts the rolling pruner keeps. Must be at least the chain's `minHistoryRetentionEpochs` chainspec parameter. | | [`LogIndex.Enabled`](./configuration.md#logindex-enabled) | recommended | recommended | recommended | The address/topic to block-number index behind fast `eth_getLogs`. Builds over whatever receipts the node stores. | | [`Receipt.TxLookupLimit`](./configuration.md#receipt-txlookuplimit) | `0` | `0` | `0` | `0` keeps the transaction-hash lookup index for every stored height; retained sliced heights keep their entries either way. | +| [`Receipt.DeriveFromState`](./configuration.md#receipt-derivefromstate) | optional | - | - | The receiptless variant: receipts are derived from state instead of persisted. See [Receiptless archive](#receiptless-archive). | | [`Sync.AncientBodiesBarrier`](./configuration.md#sync-ancientbodiesbarrier) / [`Sync.AncientReceiptsBarrier`](./configuration.md#sync-ancientreceiptsbarrier) | `0` | - | - | A full archive that should serve receipts from genesis must also download them; see [History pruning](./history-pruning.md). | Every archive setting is default-off: a node that configures none of them behaves exactly as before. @@ -46,6 +47,15 @@ Within the window, the node answers historical RPC exactly like a full archive. On an address-slice node, reads below the general window serve only the sliced addresses and fail closed for everything else. Answering sliced logs below a previously pruned boundary requires `History.Pruning` to stay enabled: at startup, the pruner validates from which depth each slice's logs are provably retained, and without it those reads fail closed. +## Receiptless archive + +[`Receipt.DeriveFromState`](./configuration.md#receipt-derivefromstate) trades the receipt store for computation: receipt writes are skipped, and a receipt query re-executes the block over its parent state, serving the result only when it reproduces the block header's receipts root. It requires state history for the queried block, so it pairs with a full archive. + +- Receipts already on disk are still served, and pre-Byzantium receipts and the transaction index are always written. +- A skipped receipt is retained in memory until history capture durably covers its block, and is persisted if capture permanently stops, so a capture breakdown does not lose receipts. +- A query that misses the cache costs a full block execution, so a public endpoint should be rate limited; concurrency is bounded by [`JsonRpc.EthModuleConcurrentInstances`](./configuration.md#jsonrpc-ethmoduleconcurrentinstances). +- Peers are told no receipts are available. + ## Notes - A slice retention shallower than the general window is refused at startup, because it would delete an address's rows inside the advertised window. From ace5a292fbd1be972dec76ff10216757bc97b756 Mon Sep 17 00:00:00 2001 From: Stavros Vlachakis <89769224+svlachakis@users.noreply.github.com> Date: Tue, 1 Sep 2026 12:01:01 +0300 Subject: [PATCH 3/8] docs: describe behavior without duplicating defaults; rolling pruning reclaims in background --- docs/fundamentals/archive-nodes.md | 8 ++++---- docs/fundamentals/history-pruning.md | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/fundamentals/archive-nodes.md b/docs/fundamentals/archive-nodes.md index d5e93f2103..1c5dbfcbb0 100644 --- a/docs/fundamentals/archive-nodes.md +++ b/docs/fundamentals/archive-nodes.md @@ -22,10 +22,10 @@ Two independent groups of configuration options compose: |---|---|---|---|---| | [`FlatDb.Enabled`](./configuration.md#flatdb-enabled) | `true` | `true` | `true` | The flat database; everything below builds on it. | | [`FlatDb.HistoryEnabled`](./configuration.md#flatdb-historyenabled) | `true` | `true` | `true` | Captures per-block state changesets - historical state queries answer from these. | -| [`FlatDb.HistoryRetentionBlocks`](./configuration.md#flatdb-historyretentionblocks) | `0` (default) | e.g. `450000` | e.g. `450000` | The state-history window, in blocks below the tip. `0` keeps state history from genesis. | -| [`FlatDb.HistorySliceAddresses`](./configuration.md#flatdb-historysliceaddresses) | unset | unset | e.g. `0xC02a...,0xA0b8...:2000000` | Contracts kept queryable beyond the general window: their state rows survive pruning, and every block one of these addresses appears in keeps its receipts and full body, so logs and transactions stay answerable. `addr` retains forever; `addr:N` retains while a height is within `N` blocks of the head. | +| [`FlatDb.HistoryRetentionBlocks`](./configuration.md#flatdb-historyretentionblocks) | `0` (default) | the window size, in blocks | the window size, in blocks | The state-history window, in blocks below the tip. `0` keeps state history from genesis. | +| [`FlatDb.HistorySliceAddresses`](./configuration.md#flatdb-historysliceaddresses) | unset | unset | the sliced addresses | Contracts kept queryable beyond the general window: their state rows survive pruning, and every block one of these addresses appears in keeps its receipts and full body, so logs and transactions stay answerable. `address` retains forever; `address:N` retains while a height is within `N` blocks of the head. | | [`History.Pruning`](./configuration.md#history-pruning) | `Disabled` (default) | `Rolling` | `Rolling` | Block-and-receipt expiry. Independent of state history, but a windowed node normally rolls both. | -| [`History.RetentionEpochs`](./configuration.md#history-retentionepochs) | - | default `82125` | default `82125` | How many epochs (32 blocks each) of bodies and receipts the rolling pruner keeps. Must be at least the chain's `minHistoryRetentionEpochs` chainspec parameter. | +| [`History.RetentionEpochs`](./configuration.md#history-retentionepochs) | - | the retention window, in epochs | the retention window, in epochs | How many epochs of bodies and receipts the rolling pruner keeps. Must be at least the chain's `minHistoryRetentionEpochs` chainspec parameter. | | [`LogIndex.Enabled`](./configuration.md#logindex-enabled) | recommended | recommended | recommended | The address/topic to block-number index behind fast `eth_getLogs`. Builds over whatever receipts the node stores. | | [`Receipt.TxLookupLimit`](./configuration.md#receipt-txlookuplimit) | `0` | `0` | `0` | `0` keeps the transaction-hash lookup index for every stored height; retained sliced heights keep their entries either way. | | [`Receipt.DeriveFromState`](./configuration.md#receipt-derivefromstate) | optional | - | - | The receiptless variant: receipts are derived from state instead of persisted. See [Receiptless archive](#receiptless-archive). | @@ -59,5 +59,5 @@ On an address-slice node, reads below the general window serve only the sliced a ## Notes - A slice retention shallower than the general window is refused at startup, because it would delete an address's rows inside the advertised window. -- The state-history pruner paces itself with [`FlatDb.HistoryPruneIntervalBlocks`](./configuration.md#flatdb-historypruneintervalblocks) (default `1024`) and [`FlatDb.HistoryPrunePassBudgetSeconds`](./configuration.md#flatdb-historyprunepassbudgetseconds) (default `5`). The pass budget must exceed the longest historical query the node serves, since deletes wait for in-flight historical reads. +- The state-history pruner paces itself with [`FlatDb.HistoryPruneIntervalBlocks`](./configuration.md#flatdb-historypruneintervalblocks) and [`FlatDb.HistoryPrunePassBudgetSeconds`](./configuration.md#flatdb-historyprunepassbudgetseconds). The pass budget must exceed the longest historical query the node serves, since deletes wait for in-flight historical reads. - [`FlatDb.HistoryVerifyEveryBlock`](./configuration.md#flatdb-historyverifyeveryblock) (default off) runs a one-shot background proof on unwindowed archives: it rebuilds the state root from history rows at every covered block and compares it against the node's own headers. Memory usage follows state size. diff --git a/docs/fundamentals/history-pruning.md b/docs/fundamentals/history-pruning.md index be5abd35d3..1cd1c48669 100644 --- a/docs/fundamentals/history-pruning.md +++ b/docs/fundamentals/history-pruning.md @@ -19,6 +19,8 @@ Removing history that is already stored is a separate, opt-in step controlled by - `UseAncientBarriers` — removes stored block bodies and receipts below the lower of the two ancient barriers. - `Rolling` — keeps a moving window of the most recent [`History.RetentionEpochs`](./configuration.md#history-retentionepochs) epochs and prunes below it as the head advances. The configured window must be at least the `minHistoryRetentionEpochs` chainspec parameter of the network, and a node that has just synced only starts pruning once its stored history grows past the window. +Pruning publishes the new retention boundary first and reclaims the space below it in the background, in bounded passes that do not block block processing. Disk space returns gradually as the database rewrites its files. + Pruning never removes the genesis block or anything at or above the sync pivot. Use [`History.PruningInterval`](./configuration.md#history-pruninginterval) and [`History.PruningTimeoutSeconds`](./configuration.md#history-pruningtimeoutseconds) to control how often it runs and how long a single pass may take. Blocks in which an address listed in [`FlatDb.HistorySliceAddresses`](./configuration.md#flatdb-historysliceaddresses) appears keep their receipts and bodies beyond the rolling window, so logs and transactions for those contracts stay answerable; see [Archive nodes](./archive-nodes.md). From 2470f988ec5678cbcd654193eb0b1b58479210de Mon Sep 17 00:00:00 2001 From: Stavros Vlachakis <89769224+svlachakis@users.noreply.github.com> Date: Tue, 1 Sep 2026 12:16:01 +0300 Subject: [PATCH 4/8] docs: log and block query behavior below the pruning boundary --- docs/fundamentals/archive-nodes.md | 8 ++++++-- docs/fundamentals/history-pruning.md | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/fundamentals/archive-nodes.md b/docs/fundamentals/archive-nodes.md index 1c5dbfcbb0..826d0b00d8 100644 --- a/docs/fundamentals/archive-nodes.md +++ b/docs/fundamentals/archive-nodes.md @@ -43,9 +43,13 @@ Do not turn on [full state pruning](./state-pruning.md) on an archive node, as t ## Historical queries and the window -Within the window, the node answers historical RPC exactly like a full archive. Below it, queries fail closed: historical state reads (`eth_call`, `eth_getBalance`, `eth_getStorageAt`) below the window return a pruned-history error instead of resolving against live state. +Within the window, the node answers historical RPC exactly like a full archive. Below it, queries fail closed rather than answering wrongly: -On an address-slice node, reads below the general window serve only the sliced addresses and fail closed for everything else. Answering sliced logs below a previously pruned boundary requires `History.Pruning` to stay enabled: at startup, the pruner validates from which depth each slice's logs are provably retained, and without it those reads fail closed. +- Historical state reads (`eth_call`, `eth_getBalance`, `eth_getStorageAt`) below the window return a pruned-history error instead of resolving against live state. +- `eth_getLogs` over heights whose receipts were pruned returns an error instead of silently returning fewer logs than the range holds. +- Block and receipt queries below the earliest block the node still serves return a pruned-history error, consistent with the block range the node advertises to its peers. + +On an address-slice node, reads below the general window serve only the sliced addresses and fail closed for everything else. Log queries filtered to sliced addresses keep answering below the general boundary, served from the log index at the cost of the matches rather than the size of the range. Answering sliced logs below a previously pruned boundary requires `History.Pruning` to stay enabled: at startup, the pruner validates from which depth each slice's logs are provably retained, and without it those reads fail closed. ## Receiptless archive diff --git a/docs/fundamentals/history-pruning.md b/docs/fundamentals/history-pruning.md index 1cd1c48669..6aaac3720b 100644 --- a/docs/fundamentals/history-pruning.md +++ b/docs/fundamentals/history-pruning.md @@ -25,6 +25,8 @@ Pruning never removes the genesis block or anything at or above the sync pivot. Blocks in which an address listed in [`FlatDb.HistorySliceAddresses`](./configuration.md#flatdb-historysliceaddresses) appears keep their receipts and bodies beyond the rolling window, so logs and transactions for those contracts stay answerable; see [Archive nodes](./archive-nodes.md). +`eth_getLogs` over a range whose receipts have been pruned returns an error rather than silently returning fewer logs than the range holds, and block queries below the earliest block the node still serves answer with a pruned-history error. + `History.Pruning` removes blocks and receipts only. Historical state has its own, independent retention; see [Archive nodes](./archive-nodes.md). ## Era1 format From c86aa4fcdfb6e1c3227faa725174e91e0aef3bbd Mon Sep 17 00:00:00 2001 From: Stavros Vlachakis <89769224+svlachakis@users.noreply.github.com> Date: Tue, 1 Sep 2026 12:47:20 +0300 Subject: [PATCH 5/8] docs: archive table links to each option's home instead of restating it --- docs/fundamentals/archive-nodes.md | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/docs/fundamentals/archive-nodes.md b/docs/fundamentals/archive-nodes.md index 826d0b00d8..6787157c4b 100644 --- a/docs/fundamentals/archive-nodes.md +++ b/docs/fundamentals/archive-nodes.md @@ -18,18 +18,20 @@ Two independent groups of configuration options compose: ## Configuration -| Setting | Full archive | Windowed archive | Address-slice archive | What it controls | +Each option is documented in its own section of the [configuration reference](./configuration.md); this page is the archive-node view of them. The table shows which options make up each shape - follow the links for what every option does. + +| Setting | Full archive | Windowed archive | Address-slice archive | Role | |---|---|---|---|---| -| [`FlatDb.Enabled`](./configuration.md#flatdb-enabled) | `true` | `true` | `true` | The flat database; everything below builds on it. | -| [`FlatDb.HistoryEnabled`](./configuration.md#flatdb-historyenabled) | `true` | `true` | `true` | Captures per-block state changesets - historical state queries answer from these. | -| [`FlatDb.HistoryRetentionBlocks`](./configuration.md#flatdb-historyretentionblocks) | `0` (default) | the window size, in blocks | the window size, in blocks | The state-history window, in blocks below the tip. `0` keeps state history from genesis. | -| [`FlatDb.HistorySliceAddresses`](./configuration.md#flatdb-historysliceaddresses) | unset | unset | the sliced addresses | Contracts kept queryable beyond the general window: their state rows survive pruning, and every block one of these addresses appears in keeps its receipts and full body, so logs and transactions stay answerable. `address` retains forever; `address:N` retains while a height is within `N` blocks of the head. | -| [`History.Pruning`](./configuration.md#history-pruning) | `Disabled` (default) | `Rolling` | `Rolling` | Block-and-receipt expiry. Independent of state history, but a windowed node normally rolls both. | -| [`History.RetentionEpochs`](./configuration.md#history-retentionepochs) | - | the retention window, in epochs | the retention window, in epochs | How many epochs of bodies and receipts the rolling pruner keeps. Must be at least the chain's `minHistoryRetentionEpochs` chainspec parameter. | -| [`LogIndex.Enabled`](./configuration.md#logindex-enabled) | recommended | recommended | recommended | The address/topic to block-number index behind fast `eth_getLogs`. Builds over whatever receipts the node stores. | -| [`Receipt.TxLookupLimit`](./configuration.md#receipt-txlookuplimit) | `0` | `0` | `0` | `0` keeps the transaction-hash lookup index for every stored height; retained sliced heights keep their entries either way. | -| [`Receipt.DeriveFromState`](./configuration.md#receipt-derivefromstate) | optional | - | - | The receiptless variant: receipts are derived from state instead of persisted. See [Receiptless archive](#receiptless-archive). | -| [`Sync.AncientBodiesBarrier`](./configuration.md#sync-ancientbodiesbarrier) / [`Sync.AncientReceiptsBarrier`](./configuration.md#sync-ancientreceiptsbarrier) | `0` | - | - | A full archive that should serve receipts from genesis must also download them; see [History pruning](./history-pruning.md). | +| [`FlatDb.Enabled`](./configuration.md#flatdb-enabled) | `true` | `true` | `true` | The flat database itself. | +| [`FlatDb.HistoryEnabled`](./configuration.md#flatdb-historyenabled) | `true` | `true` | `true` | Captures the per-block state changesets. | +| [`FlatDb.HistoryRetentionBlocks`](./configuration.md#flatdb-historyretentionblocks) | `0` (default) | the window size, in blocks | the window size, in blocks | The state-history window; `0` keeps state history from genesis. | +| [`FlatDb.HistorySliceAddresses`](./configuration.md#flatdb-historysliceaddresses) | unset | unset | the sliced addresses | Contracts kept queryable beyond the general window. | +| [`History.Pruning`](./configuration.md#history-pruning) | `Disabled` (default) | `Rolling` | `Rolling` | Block-and-receipt expiry; see [History pruning](./history-pruning.md). | +| [`History.RetentionEpochs`](./configuration.md#history-retentionepochs) | - | the retention window, in epochs | the retention window, in epochs | How much block-and-receipt history the rolling pruner keeps. | +| [`LogIndex.Enabled`](./configuration.md#logindex-enabled) | recommended | recommended | recommended | The index behind fast `eth_getLogs`. | +| [`Receipt.TxLookupLimit`](./configuration.md#receipt-txlookuplimit) | `0` | `0` | `0` | `0` keeps the transaction-hash lookup index for every stored height. | +| [`Receipt.DeriveFromState`](./configuration.md#receipt-derivefromstate) | optional | - | - | The receiptless variant; see [Receiptless archive](#receiptless-archive). | +| [`Sync.AncientBodiesBarrier`](./configuration.md#sync-ancientbodiesbarrier) / [`Sync.AncientReceiptsBarrier`](./configuration.md#sync-ancientreceiptsbarrier) | `0` | - | - | A full archive that should serve receipts from genesis must also download them. | Every archive setting is default-off: a node that configures none of them behaves exactly as before. From 58f2cecea9bcd84855f5e6531320de6c76d2cbb6 Mon Sep 17 00:00:00 2001 From: Stavros Vlachakis <89769224+svlachakis@users.noreply.github.com> Date: Tue, 1 Sep 2026 13:30:15 +0300 Subject: [PATCH 6/8] docs: drop prewarming toggle removed in 2.0 --- docs/fundamentals/performance-tuning.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/fundamentals/performance-tuning.md b/docs/fundamentals/performance-tuning.md index 0240f06211..651dfc73af 100644 --- a/docs/fundamentals/performance-tuning.md +++ b/docs/fundamentals/performance-tuning.md @@ -57,8 +57,7 @@ Old bodies and receipts are mainly limited by your Internet connection. With a 1 Block processing time is primarily limited by SSD performance. In practice, it is the SSD's _response time_, not just its IOPS, that matters. However, since most SSDs don't advertise response times, IOPS often serves as a useful approximation. -Nethermind includes a _prewarming_ feature that parallelizes state reads by executing transactions concurrently, warming up state reads for the main block processing. This effectively hides SSD latency, although it increases CPU usage. For non-validator nodes, where RPC throughput is more important, you can turn off this optimization by setting the [`Blocks.PreWarmStateOnBlockProcessing`](../fundamentals/configuration.md#blocks-prewarmstateonblockprocessing) option to `false`. While disabling prewarming may conserve CPU resources, the benefits are typically minor. - +Nethermind includes a _prewarming_ feature that parallelizes state reads by executing transactions concurrently, warming up state reads for the main block processing. This effectively hides SSD latency, although it increases CPU usage. ## Memory Ethereum aims to be maximally decentralized, so the default Nethermind configuration minimizes system resource usage. However, several tunable parameters are available if your system has large enough memory. From 29c1b64a387e9e7e37ecdbbf8122632778b2ace2 Mon Sep 17 00:00:00 2001 From: Stavros Vlachakis <89769224+svlachakis@users.noreply.github.com> Date: Tue, 1 Sep 2026 13:31:39 +0300 Subject: [PATCH 7/8] docs: align the pruned-range getLogs wording --- docs/fundamentals/archive-nodes.md | 2 +- docs/fundamentals/history-pruning.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/fundamentals/archive-nodes.md b/docs/fundamentals/archive-nodes.md index 6787157c4b..df593475a8 100644 --- a/docs/fundamentals/archive-nodes.md +++ b/docs/fundamentals/archive-nodes.md @@ -48,7 +48,7 @@ Do not turn on [full state pruning](./state-pruning.md) on an archive node, as t Within the window, the node answers historical RPC exactly like a full archive. Below it, queries fail closed rather than answering wrongly: - Historical state reads (`eth_call`, `eth_getBalance`, `eth_getStorageAt`) below the window return a pruned-history error instead of resolving against live state. -- `eth_getLogs` over heights whose receipts were pruned returns an error instead of silently returning fewer logs than the range holds. +- `eth_getLogs` over a range covering pruned heights returns an error rather than silently returning fewer logs than the range holds. - Block and receipt queries below the earliest block the node still serves return a pruned-history error, consistent with the block range the node advertises to its peers. On an address-slice node, reads below the general window serve only the sliced addresses and fail closed for everything else. Log queries filtered to sliced addresses keep answering below the general boundary, served from the log index at the cost of the matches rather than the size of the range. Answering sliced logs below a previously pruned boundary requires `History.Pruning` to stay enabled: at startup, the pruner validates from which depth each slice's logs are provably retained, and without it those reads fail closed. diff --git a/docs/fundamentals/history-pruning.md b/docs/fundamentals/history-pruning.md index 6aaac3720b..48b094e22a 100644 --- a/docs/fundamentals/history-pruning.md +++ b/docs/fundamentals/history-pruning.md @@ -25,7 +25,7 @@ Pruning never removes the genesis block or anything at or above the sync pivot. Blocks in which an address listed in [`FlatDb.HistorySliceAddresses`](./configuration.md#flatdb-historysliceaddresses) appears keep their receipts and bodies beyond the rolling window, so logs and transactions for those contracts stay answerable; see [Archive nodes](./archive-nodes.md). -`eth_getLogs` over a range whose receipts have been pruned returns an error rather than silently returning fewer logs than the range holds, and block queries below the earliest block the node still serves answer with a pruned-history error. +`eth_getLogs` over a range covering pruned heights returns an error rather than silently returning fewer logs than the range holds, and block queries below the earliest block the node still serves answer with a pruned-history error. `History.Pruning` removes blocks and receipts only. Historical state has its own, independent retention; see [Archive nodes](./archive-nodes.md). From 2a46e1559673dda32522e2f23904ed8425a35f68 Mon Sep 17 00:00:00 2001 From: Stavros Vlachakis <89769224+svlachakis@users.noreply.github.com> Date: Tue, 1 Sep 2026 13:33:09 +0300 Subject: [PATCH 8/8] docs: simplify the sliced-blocks retention sentence --- docs/fundamentals/history-pruning.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/fundamentals/history-pruning.md b/docs/fundamentals/history-pruning.md index 48b094e22a..9632ffdd24 100644 --- a/docs/fundamentals/history-pruning.md +++ b/docs/fundamentals/history-pruning.md @@ -23,7 +23,7 @@ Pruning publishes the new retention boundary first and reclaims the space below Pruning never removes the genesis block or anything at or above the sync pivot. Use [`History.PruningInterval`](./configuration.md#history-pruninginterval) and [`History.PruningTimeoutSeconds`](./configuration.md#history-pruningtimeoutseconds) to control how often it runs and how long a single pass may take. -Blocks in which an address listed in [`FlatDb.HistorySliceAddresses`](./configuration.md#flatdb-historysliceaddresses) appears keep their receipts and bodies beyond the rolling window, so logs and transactions for those contracts stay answerable; see [Archive nodes](./archive-nodes.md). +Blocks containing any address in [`FlatDb.HistorySliceAddresses`](./configuration.md#flatdb-historysliceaddresses) retain their receipts and bodies beyond the rolling window, so logs and transactions for those contracts stay answerable; see [Archive nodes](./archive-nodes.md). `eth_getLogs` over a range covering pruned heights returns an error rather than silently returning fewer logs than the range holds, and block queries below the earliest block the node still serves answer with a pruned-history error.