From f0d2ef660e9ef2ec219334740c8034633c613aea Mon Sep 17 00:00:00 2001 From: erhant Date: Fri, 10 Jul 2026 22:43:41 +0300 Subject: [PATCH] chore: add TODO doc about transient apply failures [skip ci] --- lez/chain_state/DESIGN.md | 4 ---- lez/chain_state/src/apply.rs | 3 +++ lez/sequencer/core/src/lib.rs | 6 ++++++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/lez/chain_state/DESIGN.md b/lez/chain_state/DESIGN.md index 600fb23f..35e9a2b9 100644 --- a/lez/chain_state/DESIGN.md +++ b/lez/chain_state/DESIGN.md @@ -6,10 +6,6 @@ backs decentralized sequencing. Status: **interface freeze** — the contract the produce-on-turn and follow-blocks tracks build against. Changing them after the tracks split forces rework in both. -Branch: `erhant/lez-two-tip-chain-state` (off `erhant/indexer-recoverable-invalid-blocks`). - ---- - ## 1. Motivation Decentralized sequencing requires every honest node — sequencer or indexer — to diff --git a/lez/chain_state/src/apply.rs b/lez/chain_state/src/apply.rs index 42a77b35..5e2ff6f1 100644 --- a/lez/chain_state/src/apply.rs +++ b/lez/chain_state/src/apply.rs @@ -30,6 +30,9 @@ pub enum AcceptOutcome { /// Chained but failed to apply, possibly transiently /// ([`BlockIngestError::is_retryable`]); nothing recorded, tip and state /// untouched. The caller retries and parks once it gives up. + /// + /// TODO: Only the indexer's `accept_block` emits this today; the sequencer's + /// `ChainState` parks on all failures without retrying (see `on_follow`). RetryableFailure(BlockIngestError), } diff --git a/lez/sequencer/core/src/lib.rs b/lez/sequencer/core/src/lib.rs index 2c834a7b..927170a9 100644 --- a/lez/sequencer/core/src/lib.rs +++ b/lez/sequencer/core/src/lib.rs @@ -343,6 +343,12 @@ impl SequencerCore { /// Feed one channel delta into the follow state and mirror it to the store: /// revert orphaned, then apply and persist adopted and finalized blocks. /// Production builds on this same head. + /// + /// TODO: unlike the indexer's ingest loop, this path does not retry + /// `is_retryable` (transient) apply failures — a failed block just parks and + /// relies on a valid successor or a restart. `ChainState` never emits + /// `AcceptOutcome::RetryableFailure` yet; adding retry parity here is a + /// follow-up. fn on_follow( dbio: Arc, chain: Arc>,