Expand description
In-process retry for the boot-time chain reads (#2159).
build_chain_and_handlers runs four fail-closed chain bootstraps in
sequence: the CapacityBond registry snapshot, the slash-detection
enumeration, the PaymentPool usdc() self-check and the ContentBlacklist
deny-set enumeration with its enforcement pass. Each one must succeed before
the node serves, and a boot is only as likely to succeed as the product of
its reads. A single transient provider error therefore must not end the
process: each bootstrap retries its read phase through BootRetry::run and
fails only on a deterministic fault or once the shared boot deadline passes.
The best-effort fee-share reads (fee_shares::seed_from_chain) run between
the slash and usdc() reads. They retry the same way but fall back to the
floor share instead of failing boot, and they run on a short sub-budget
(BootRetry::capped) so a flapping provider cannot spend the deadline the
later fail-closed reads need.
Startup stays fail-closed. A retry delays readiness; it never opens the ALPN router before the deny-set is loaded and enforced.
Three boot-time facts shape the loop:
- No signal handler exists yet, so SIGTERM or SIGINT ends a retrying boot at once. The only durable writes a boot attempt makes are sticky, idempotent cache evictions; everything else it sets is in memory. An abrupt exit therefore needs no teardown.
SharedHeadcaches a failed head read for half the poll interval. Retries inside that window replay the cached error — the first two at the default 7 s poll interval — so the cost is at most one cache TTL of the budget.- The metrics listener binds after these reads, so
decdn_chain_boot_read_retries_totalis scrapeable only once boot completes. The per-attemptWARNis the live signal during boot.
Structs§
- Boot
Retry - The shared deadline for the boot-time chain reads. Build one per boot and pass it by reference to every bootstrap. See the module docs.