Sync from a checkpoint
Without checkpoint sync, a new beacon node replays every block since genesis, which takes days on mainnet. With it, the node downloads a recent finalized state from a beacon node you trust and follows the chain within minutes.
Before you begin
- A beacon node with an empty data directory. Checkpoint sync only applies to a fresh database.
- A connected execution client. See Connect your execution client.
Start the node
-
Pick a provider. Use your own synced beacon node, or a public endpoint from the community checkpoint sync endpoints list. Pick one run by an organization you trust.
-
Add
--checkpoint-sync-urlto your beacon node command. From theconsensusfolder, with the layout from Connect your execution client:./prysm.sh beacon-chain \--mainnet \--datadir=$HOME/ethereum/data/mainnet/beacon \--execution-endpoint=http://localhost:8551 \--jwt-secret=$HOME/ethereum/data/jwt.hex \--checkpoint-sync-url=https://sync-mainnet.beaconcha.in \--beacon-db-pruning.\prysm.bat beacon-chain `--mainnet `--datadir=$HOME\ethereum\data\mainnet\beacon `--execution-endpoint=http://localhost:8551 `--jwt-secret=$HOME\ethereum\data\jwt.hex `--checkpoint-sync-url=https://sync-mainnet.beaconcha.in `--beacon-db-pruning./prysm.sh beacon-chain \--mainnet \--datadir=$HOME/ethereum/data/mainnet/beacon \--execution-endpoint=$HOME/ethereum/data/mainnet/execution/geth.ipc \--checkpoint-sync-url=https://sync-mainnet.beaconcha.in \--beacon-db-pruning.\prysm.bat beacon-chain `--mainnet `--datadir=$HOME\ethereum\data\mainnet\beacon `--execution-endpoint=\\.\pipe\geth.ipc `--checkpoint-sync-url=https://sync-mainnet.beaconcha.in `--beacon-db-pruning--beacon-db-pruningdeletes blocks and states older than about 5 months, the oldest data other nodes can still ask for, so the database stops growing. Leave it out if you need the full history.Running validators? Also add:
--postpone-shutdown-for-proposalsWhen you stop or restart the beacon node, it then waits until your validators' upcoming block proposals are done. See Don't restart just before a proposal.
-
Watch the logs. A successful download looks like this:
INFO node: Checkpoint sync - Downloading origin state and blockINFO checkpoint-sync: Downloaded checkpoint sync state and block. blockRoot=0x… blockSlot=… stateRoot=0x… stateSlot=…You can leave the flag in place. On later restarts, the node finds its database and carries on from where it stopped. It logs:
Origin checkpoint found in the database, ignoring checkpoint sync flags
Verify the checkpoint
A broken or malicious provider could hand you a state from the wrong chain. Once the node runs, compare its finalized checkpoint with a second provider that has nothing to do with the first.
-
Ask your node for its finalized checkpoint, and note
data.finalized.epochanddata.finalized.root:curl -s http://localhost:3500/eth/v1/beacon/states/head/finality_checkpointscurl.exe -s http://localhost:3500/eth/v1/beacon/states/head/finality_checkpoints -
Ask a second provider. Endpoints from the list above report their finalized epoch and root at
/checkpointz/v1/status:curl -s https://mainnet.checkpoint.sigp.io/checkpointz/v1/statuscurl.exe -s https://mainnet.checkpoint.sigp.io/checkpointz/v1/statusYou can also open the epoch in a block explorer:
https://beaconcha.in/epoch/<EPOCH>.
For the same epoch, the roots must be identical. If the epochs differ, finality has just moved on: query both again. If the roots differ, stop your validator, delete the beacon node's data directory, and sync again from another provider.
Check that it works
curl -s http://localhost:3500/eth/v1/node/syncing
curl.exe -s http://localhost:3500/eth/v1/node/syncing
Right after the checkpoint sync, head_slot starts near the checkpoint slot, and sync_distance drops quickly. When is_syncing is false, the node is following the chain, and the logs show a Synced new block line for every block. is_optimistic: true means the execution client is still syncing; your validators can't do their duties until it catches up.
Download older blocks (backfill)
A checkpoint-synced node has no blocks from before the checkpoint. It validates fine without them, but it can't serve them to peers or return them from its API. To download them in the background once the node is synced, add:
--enable-backfill
By default, backfill goes back about 5 months (33,024 epochs): the history every node must be able to serve, and the same window --beacon-db-pruning keeps. To go further back, also add --backfill-oldest-slot=<SLOT>, and leave out --beacon-db-pruning, which would delete those blocks again. A slot more recent than the 5-month limit is ignored with a warning.
The node logs its progress, then:
INFO backfill: Backfill in progress batchesRemaining=… completion=…% lowestBackfilledSlot=… targetSlot=…
INFO backfill: Backfill is complete lowestBackfilledSlot=… targetSlot=…
Sync during a long period without finality
--checkpoint-sync-url always downloads the last finalized checkpoint. When the network hasn't finalized for a long time, that checkpoint is old, and a new node has a lot of chain to replay before it's useful. You can start from a recent, unfinalized block instead.
Prysm treats the block you pick as final. If it's later reorged out, the node can't recover: delete its data directory and sync again. Pick a block at least a few epochs old, and check its root against a second source.
You need a synced beacon node you trust that serves the Beacon API, such as your own. Replace <BEACON_NODE> with its URL.
-
Pick a slot. It must be the first slot of an epoch at least 2 epochs before the current one, and it must hold a block. Replace
<SLOT>with it and get the block's root:curl -s <BEACON_NODE>/eth/v1/beacon/blocks/<SLOT>/rootcurl.exe -s <BEACON_NODE>/eth/v1/beacon/blocks/<SLOT>/rootA
404means the slot is empty: pick another epoch. Comparedata.rootwith a second, independent source, such as a block explorer. -
Download the state at that slot, and the block by its root. Replace
<BLOCK_ROOT>with the root from the previous step:curl -H 'Accept: application/octet-stream' <BEACON_NODE>/eth/v2/debug/beacon/states/<SLOT> -o state.sszcurl -H 'Accept: application/octet-stream' <BEACON_NODE>/eth/v2/beacon/blocks/<BLOCK_ROOT> -o block.sszcurl.exe -H 'Accept: application/octet-stream' <BEACON_NODE>/eth/v2/debug/beacon/states/<SLOT> -o state.sszcurl.exe -H 'Accept: application/octet-stream' <BEACON_NODE>/eth/v2/beacon/blocks/<BLOCK_ROOT> -o block.ssz -
Start the node from the files. With an empty data directory, add these instead of
--checkpoint-sync-url:--checkpoint-state=state.ssz--checkpoint-block=block.sszPrysm refuses to start if the block doesn't match the state. Otherwise, it warns:
WARN checkpoint-sync: Checkpoint syncing from files. If this anchor is not finalized and is reorged out the node cannot recover and the database must be deleted
Until the network finalizes again, the node reports a justified epoch lower than its finalized epoch. That's expected.
Good to know
- No internet access to a provider? Download the checkpoint as files on another machine with
prysmctl checkpoint-sync download, then start the node with--checkpoint-stateand--checkpoint-block.
Troubleshooting
The node ignores the checkpoint, but you wanted a fresh sync. Prysm logs:
Origin checkpoint found in the database, ignoring checkpoint sync flags
The data directory already holds a database. Stop the node and start it once with --force-clear-db, or point --datadir at an empty directory.
The checkpoint download fails or times out. Prysm logs:
Error retrieving checkpoint origin state and block
The provider is down, rate-limited, or unreachable. Try another one from the list.
The download worked, but the node stays behind or has few peers. Checkpoint sync only sets the starting point. Peers and sync speed depend on your network setup.