Skip to main content

batch_ensure_heights

Function batch_ensure_heights 

Source
pub fn batch_ensure_heights(
    sapling: &BTreeSet<BlockHeight>,
    orchard: &BTreeSet<BlockHeight>,
    ironwood: &BTreeSet<BlockHeight>,
    anchor_retention: Option<&AnchorRetention>,
    range: RangeInclusive<BlockHeight>,
) -> [BTreeSet<BlockHeight>; 3]
Available on crate feature orchard only.
Expand description

Given the checkpoint heights present in each of the three shielded pools’ note commitment trees, in the order (Sapling, Orchard, Ironwood), returns for each pool the complete set of checkpoint heights it must ensure for a batch of scanned blocks covering range.

This is the whole of the rule, and the set a caller passes to ensure_checkpoints. It is the union of two obligations, and satisfying only the first is a silent correctness bug:

  1. Cross-pool alignment (cross_pool_ensure_heights): every pool must be checkpointed at every height that is checkpointed in any pool, so anchors align across trees.
  2. Anchor retention: every height anchor_retention retains within range. Scanning checkpoints a block only at its last note commitment, so a grid boundary landing on a block with no shielded output in ANY pool is never checkpointed by (1) either — and a retention policy can only keep alive a checkpoint that EXISTS. AnchorRetention is a promise to preserve a checkpoint, never to create one: omit this step and a consumer marks boundary heights that never materialize, leaving anything anchored to them permanently unprovable.

Obligation (2) has no effect when anchor_retention is None, so a caller with no retention policy gets exactly cross_pool_ensure_heights.

put_blocks calls this. It is public so that a consumer maintaining its note commitment trees by other means — accumulating updates in memory and flushing in bulk, or building shards out of band — composes the same set rather than rediscovering the rule, which is why the two obligations live behind one function instead of at each call site.