How long the loop waits on a local catchup read. Consensus cuts local reads short, so that it
can still vote in time. The loop has no such deadline, while peers may have pruned the heights
it reads, so a slow read cut short on every try would stall it.
The state at the epoch boundary leaf, from catchup: the block frontier and the whole reward
tree, each checked against its root in the boundary header.
The leaves at heights, which the data pruned height says are gone, from the query moduleβs
peers through its light client, retrying until they arrive. The light client verifies leaves
of every protocol version, and one proof covers the run: it proves the last leaf final and
chains the rest to it. The loop needs each leaf once, so the leaves are stored neither in this
database, where the pruner would only delete them again, nor in the light clientβs cache.
Apply every leaf above parent_leaf as it arrives. Leaves come from the local stream, except
those the data pruner has already deleted: the availability layer never fetches a leaf at or
below the data pruned height, so the stream would wait for one forever. Those come from peers,
in runs. Returns when the stream ends, or when a leaf from peers does not extend the parent.
The data pruned height when it is at or above height. The leaf and header there are out of
local reach: the pruner deleted them, and the availability layer never fetches below its
marker. A failed read counts as not pruned; every caller asks again before long, and the loop
must not end over a transient database error.
Archive nodes and nodes without a pruner are meant to have complete trees, which a state that
started from a boundary snapshot, as on a node that was pruned before, never gets: the loop only
moves forward. So say so.
Run f until it succeeds. An error would end the loop for good, possibly after a seed that
waited minutes for peers, so the steps of its start retry, as the leaves it applies do.
Store a snapshot at a recent epoch boundary for a loop with no state of its own, and return the
boundary, which the loop then resumes from as after a restart.
Store state, the state at the epoch boundary height, as the loopβs head snapshot. The loop
keeps nothing of state: on every start it rebuilds the headβs state from the header and fills
it from this database, so the head needs what a state update stores: