Summary
A forkpoint is a saved snapshot of consensus state. It lets a node restart from a known-good point instead of replaying the chain from genesis. It holds everything the node needs to rejoin consensus: where it was in the blocktree, the proof it needs to enter the next round, and the validator sets that check that proof. On disk, a forkpoint is theforkpoint.rlp and forkpoint.toml pair you handle during installation and recovery. This page covers what those files hold and how a node uses them to sync on startup.
What a forkpoint contains
A forkpoint holds three fields:root— the root of the node’s blocktree, which points to its highest committed block. Syncing starts here.high_certificate— the highest quorum certificate (QC) or timeout certificate (TC) the node has seen. It’s the proof the node needs to enter the next round.validator_sets— the validator sets that check those certificates. There’s usually one, for the current epoch. During an epoch change there are two, so the node can check certificates on both sides of the boundary.
high_certificate verifies against the validator_sets before using it.
Startup sync
A node loads its forkpoint and then syncs to the network tip in three steps.- Fetch the blocks up to the root. The node uses blocksync to pull the
2 × execution_delaycommitted blocks up to and includingroot. These are needed for reserve-balance checking under the transaction fee mechanism, and they have to be in place before state can sync. - Statesync. The node brings MonadDb up to version
root − execution_delay. While this runs, it listens for new proposals and sets them aside in a buffer. See statesync. - Replay. Once both syncs finish, the node builds its blocktree from
rootandhigh_certificate, then replays the buffered proposals to reach the tip.
- On startup, it pulls blocks that sit behind the root, and it runs before statesync (step 1 above).
- During normal operation, it does the reverse: statesync gets the node close to the tip, and blocksync fetches the last few blocks to close the gap, the way getting into the stadium comes before finding your seat. This catch-up role is the one the blocksync page describes.
high_certificate.round() + 1, so a node never votes at or below a round it already voted in. That’s what makes restarting from a forkpoint safe instead of a source of double votes.
How forkpoints are persisted
A node writes a new forkpoint each time it enters a new round or finalizes a block. New rounds come constantly, soforkpoint.toml changes roughly every round.
Each write produces two files:
forkpoint.rlp— the canonical, RLP-encoded form.forkpoint.toml— a human-readable, TOML-encoded form.
--forkpoint-config path points at; the bundled systemd unit points at forkpoint.toml.
Both are written to a temporary file first and then renamed, so a process crash mid-write doesn’t corrupt the forkpoint. Each write also keeps a backup copy, keyed by the root sequence number and round, so earlier forkpoints stay around for recovery.
