Make BlockSender optionally use checkpoints when closing a gap

Author: ma2bdCreated Aug 27, 2026Updated Aug 27, 2026

Summary

BlockSender::send_missing_blocks closes a gap by replaying every height it holds in the range, bounded per round by max_catch_up_blocks. It has no notion of checkpoints: checkpoint does not appear in linera-core/src/block_sender.rs or linera-core/src/chain_worker/export.rs at all.

The client's own catch-up does have one. RemoteNodeUpdater::sync_chain_height calls push_checkpoint_if_useful, which reads requested_latest_checkpoint_height and, when the validator's next_block_height is at or below it, sends that single checkpoint certificate instead of the prefix below it.

So the two catch-up strategies differ, and any caller that shares BlockSender gets the exporter's.

Why the exporter has not needed it

Export is incremental: a destination is normally a block or two behind, where the fast path would rarely fire. The case it does not cover well is a validator joining a long-lived chain, where bounded replay converges over many rounds instead of skipping the history outright. That looks deliberate — the same reasoning as not replaying the admin chain inline from another chain's push — but it is not stated anywhere, so it is unclear whether checkpoints were considered and rejected or simply never came up.

Proposal

Give BlockSender an optional checkpoint-aware catch-up and let both callers use it:

  • the client keeps the behaviour it has today,
  • the exporter gains a fast path it currently lacks,
  • a caller without a local node inherits it.

The blocker

latest_checkpoint_height is a RegisterView on ChainStateView (linera-chain/src/chain.rs:372), set when a block's body starts_with_checkpoint(). push_checkpoint_if_useful reads it through the local node, so a BlockSender — which holds only storage and the caller's payload — has no way to reach it. Making this work needs a storage-level way to find a chain's latest checkpoint height.

Impact while this is open

Landing the proposal/validated-certificate upload on BlockSender regresses catch-up to replay on three paths that were checkpoint-aware:

  • the height/round sync under a block proposal,
  • the height sync under a validated certificate when the validator is behind,
  • the origin catch-up for MissingCrossChainUpdates.

Other users of send_chain_information keep the fast path. test_proposal_pushes_checkpoint_to_lagging_validator covers the first of these and is ignored until this is fixed.

Whether this costs anything real depends on how often chains actually emit checkpoints, which has not been measured.

Source: linera-io/linera-protocol