Skip to main content

dig_block/types/
status.rs

1//! Block and checkpoint lifecycle enums ([`BlockStatus`], [`CheckpointStatus`]).
2//!
3//! **ATT-003 — [`BlockStatus`]:** [ATT-003](docs/requirements/domains/attestation/specs/ATT-003.md) /
4//! [NORMATIVE § ATT-003](docs/requirements/domains/attestation/NORMATIVE.md) /
5//! [SPEC §2.5](docs/resources/SPEC.md).
6//!
7//! **CKP-003 — [`CheckpointStatus`]:** [CKP-003](docs/requirements/domains/checkpoint/specs/CKP-003.md) /
8//! [NORMATIVE § CKP-003](docs/requirements/domains/checkpoint/NORMATIVE.md) /
9//! [SPEC §2.8](docs/resources/SPEC.md).
10//!
11//! ## Usage
12//!
13//! Consensus / chain layers assign and transition status; this crate only defines the **labels** and
14//! (for [`BlockStatus`]) **read-only predicates** (`is_finalized`, `is_canonical`). State-machine enforcement
15//! lives outside dig-block ([SPEC design note](docs/resources/SPEC.md) — transitions are not a type-level FSM here).
16//! [`CheckpointStatus`] carries winner identity in [`CheckpointStatus::WinnerSelected`] / [`CheckpointStatus::Finalized`].
17//!
18//! ## Rationale
19//!
20//! - **Bincode:** Both enums derive [`Serialize`] / [`Deserialize`] ([SER-001](docs/requirements/domains/serialization/specs/SER-001.md))
21//!   for `AttestedBlock` / checkpoint payloads.
22//! - **Copy + Eq:** [`BlockStatus`] and [`CheckpointStatus`] use [`Copy`] where all payloads are [`Copy`] ([`crate::primitives::Bytes32`]).
23//! - **Checkpoint ladder (informal):** Typical progression `Pending` → `Collecting` → `WinnerSelected` → `Finalized`, or terminal `Failed` ([CKP-003](docs/requirements/domains/checkpoint/specs/CKP-003.md) implementation notes).
24
25use serde::{Deserialize, Serialize};
26
27use crate::primitives::Bytes32;
28
29/// Lifecycle status of an attested block ([SPEC §2.5](docs/resources/SPEC.md)).
30///
31/// **Semantics (ATT-003):** `Pending` is the initial constructor default for [`crate::AttestedBlock`] (ATT-001).
32/// `SoftFinalized` means signing threshold met without L1 checkpoint; `HardFinalized` means L1-confirmed.
33/// `Orphaned` / `Rejected` are non-canonical terminal classes for fork competition and validation failure.
34#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
35pub enum BlockStatus {
36    /// Awaiting validation / attestation progress.
37    Pending,
38    /// Structurally and execution-valid locally; not yet soft-final.
39    Validated,
40    /// Enough validator stake signed; not yet checkpointed on L1.
41    SoftFinalized,
42    /// Confirmed via L1 checkpoint / hard finality path.
43    HardFinalized,
44    /// Superseded on a competing fork (still on a side chain from this node’s view).
45    Orphaned,
46    /// Failed validation; must not be treated as canonical.
47    Rejected,
48}
49
50impl BlockStatus {
51    /// `true` iff this status represents **soft or hard** finality (ATT-003 / SPEC §2.5 derived methods).
52    ///
53    /// **Finality ladder:** Only [`Self::SoftFinalized`] and [`Self::HardFinalized`] count; `Validated` is explicitly
54    /// non-final so callers can distinguish “passed validation” from “met stake threshold”.
55    #[inline]
56    pub fn is_finalized(&self) -> bool {
57        matches!(self, Self::SoftFinalized | Self::HardFinalized)
58    }
59
60    /// `false` only for [`Self::Orphaned`] and [`Self::Rejected`] (non-canonical); `true` for all other variants.
61    ///
62    /// **Rationale:** Pending / Validated / finalized states may still appear on the canonical chain; orphaned and
63    /// rejected blocks must be excluded from canonical progress metrics.
64    #[inline]
65    pub fn is_canonical(&self) -> bool {
66        !matches!(self, Self::Orphaned | Self::Rejected)
67    }
68}
69
70/// L2 checkpoint **epoch** lifecycle ([SPEC §2.8](docs/resources/SPEC.md), [CKP-003](docs/requirements/domains/checkpoint/specs/CKP-003.md)).
71///
72/// **Variants:** Three unit variants (`Pending`, `Collecting`, `Failed`) and two struct variants that pin the
73/// winning checkpoint hash (`winner_hash`) — first with off-chain `winner_score`, then with on-chain `l1_height`
74/// after L1 inclusion.
75#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
76pub enum CheckpointStatus {
77    /// Epoch has not yet started checkpoint collection.
78    Pending,
79    /// Validators are submitting checkpoint proposals for the epoch.
80    Collecting,
81    /// Winning checkpoint chosen off-chain / in L2 consensus; not yet L1-confirmed.
82    WinnerSelected {
83        /// Identity (hash) of the winning checkpoint proposal.
84        winner_hash: Bytes32,
85        /// Score used for comparison during winner selection ([CKP-004](docs/requirements/domains/checkpoint/specs/CKP-004.md) will define computation).
86        winner_score: u64,
87    },
88    /// Winning checkpoint confirmed on L1 at `l1_height`.
89    Finalized {
90        /// Same logical winner as in [`Self::WinnerSelected`] once finalized.
91        winner_hash: Bytes32,
92        /// L1 block height at which inclusion was observed.
93        l1_height: u32,
94    },
95    /// Epoch checkpointing failed (e.g. insufficient participation).
96    Failed,
97}