Since 2026-11-15 an xOneRS node on main lets the operator choose how much history it keeps. Six --history.* flags set the window for transaction indexes, bodies, receipts, logs, state and preimages; xone db prune applies the window to a stopped datadir; and two more flags make a snap-synced node fetch the history below its snapshot in the background. A node never prunes into the blocks that consensus rules read, and a request below a floor gets the typed unsupported history error, never an empty answer. None of this is in the v0.1.0 release, and we have not measured how much disk each setting saves.

For the sync modes see choosing a sync mode. For an RPC provider's view see archive vs full for RPC providers.

Which flags set the history window?

From the flag table in bin/xone/src/flags.rs. When we read it, the generated docs/cli/flags.md did not list all of these flags yet:

REFERENCE TABLEScroll to explore all columns →
Flag Keeps Default Notes
--history.transactions Transaction index (lookup by hash) for this many recent blocks 2,350,000 0 is the whole chain; geth-XDC's flag
--history.bodies Block bodies of this many recent blocks 0 (whole chain) PR #1100
--history.receipts Receipts of this many recent blocks 0 (whole chain) PR #1100
--history.logs Blocks whose logs eth_getLogs may serve 0 (whole chain) Disk follows --history.receipts
--history.state State of this many recent blocks, for RPC, unwind and snap serving 4,096 Minimum 3,213; 0 keeps every block and needs --gcmode archive (PR #1071)
--history.preimages all or required (only 20-byte address preimages) all Rows already stored stay until a later compaction (PR #1072)

The defaults keep what a node kept before these flags existed, so an upgrade changes nothing until you set one.

Why can the floor not go lower?

XDC consensus rules read blocks below the one they run on. A V1 reward reads the two epochs before a checkpoint; a V2 reward also reads the standby pool at a gap block; XDPoS_getMasternodesByNumber reads back to the gap block of the epoch switch (spec/retention.md). The node refuses a body or receipt floor that would cut into that lookback. For state, the minimum is 3,213 blocks: three epochs plus the gap, less one, plus the 64-block pivot offset that snap sync uses.

--history.state is written into the datadir. If you omit the flag on a later start, the node keeps the policy it saved.

How do I prune an existing datadir?

Stop the node, then run:

xone db prune --datadir <dir> --history.bodies 100000 --history.receipts 100000

It deletes bodies, receipts and, with the receipts, their logs below the window. The node must not be running. A running node with the same flags prunes after each import, so the window holds from then on.

--history.preimages required does not delete stored preimages at once; they stay until a later compaction (xone db compact, PR #1073).

How do I fill in history after a snap sync?

A snap-synced node starts with history only from its snapshot floor. PR #1135 adds two flags and a background service:

  • --history.bodies-from <block> and --history.receipts-from <block>: the lowest block to fetch. Unset keeps the snapshot floor; 0 goes back to genesis.
  • The backfill service fetches batches from peers. Each batch is checked against the header already stored and against the body and receipt roots. A mismatch drops the peer and nothing is stored.
  • It runs beside the live follower without taking its event queue.

The PR does not report a run on a live node, a duration or the disk it adds.

What does a client get below a floor?

The typed error, as for any history the node does not hold:

{"code": -32000, "message": "unsupported history: ...",
 "data": {"class": ..., "block": ..., "firstRetained": ..., "pivot": ...}}

eth_capabilities reports the oldest block held for state, transactions, logs, receipts and blocks, so a client or a load balancer can route an old query to an archive node first. See newer RPC methods.

How do other clients handle history?

REFERENCE TABLEScroll to explore all columns →
Client As stated by the client xOneRS on main
reth Pruned segments change which RPC calls a node can answer; the pruning page has availability tables (reth pruning) --history.* windows; typed unsupported history below them; eth_capabilities reports the floors
ethrex A snap-synced node keeps only headers below the pivot; backfill is opt-in with --history.chain postmerge (ethrex sync modes) --history.bodies-from and --history.receipts-from
geth-XDC --history.transactions keeps the transaction index for recent blocks (flags.go:379, as cited in xOne's flag table) same flag and meaning, default 2,350,000

Frequently asked questions

How do I make an xOne node keep less history?

Set --history.bodies, --history.receipts and --history.logs to the number of recent blocks to keep, and run xone db prune once on the stopped datadir. Needs a build from main after 2026-11-15.

Can I prune below the consensus lookback?

No. The node refuses a floor that cuts into the blocks consensus rules read, and state cannot go below 3,213 blocks.

How do I get full history on a snap-synced xOne node?

Set --history.bodies-from 0 and --history.receipts-from 0. A background service fetches and checks the missing bodies and receipts from peers.

How much disk does pruning save?

We have not measured it. Use xone db stats before and after, or measure-node.sh, on your own datadir.

Sources