Nothing schedules checkpoints, so catch-up is unbounded in practice

Author: ma2bdCreated Aug 12, 2026Updated Aug 12, 2026

Nothing in the protocol or the node software schedules checkpoints. ChainClient::checkpoint is invoked from exactly two places in the workspace: the unit tests, and the linera CLI (linera-service/src/cli/main.rs). There is no policy, interval, or protocol rule that causes a chain to checkpoint.

Client::push_checkpoint_if_useful in linera-core/src/updater.rs does not close this: it pushes an existing checkpoint to a validator that lacks it, so that the validator can install the chain's execution state without replaying pre-checkpoint blocks. It never creates one.

Why it matters

Catch-up work for a node joining, recovering, or bootstrapping a chain is proportional to the height above that chain's latest checkpoint. On a chain that never checkpoints, that is its entire history.

The mechanism to bound it already exists and works — bootstrap_chain_from_checkpoint installs the published state blob and resumes from that height, and reset_and_reexecute_chain replays only from latest_checkpoint_height. It is the frequency that is unmanaged.

The specification records this rather than papering over it: linera_core::proof::availability::BoundedCatchUp is a caveat rather than a lemma for exactly this reason, and it is why assumptions::BoundedRecovery cannot be discharged for a node that has fallen far behind. See #6692.

What a fix would need to decide

  • Who triggers it. The chain owner's client is the only party that can propose a SystemOperation::Checkpoint, so any automatic policy lives in ChainClient, not in a validator.
  • On what trigger. Block-height delta since the last checkpoint is the obvious candidate; state size or elapsed time are alternatives.
  • Who pays. A checkpoint publishes the execution-state dump as blobs, priced and charged to the block that publishes it, so a frequency policy is also a cost policy.
  • Chains that cannot checkpoint at all. A chain that has published to or consumed a system event stream is refused by prepare_checkpoint and check_checkpoint_preconditions respectively — the admin chain among them. Those chains have no bound available and would need a separate answer.

Source: linera-io/linera-protocol