Skip to main content

hypercall_recovery/
component.rs

1use crate::digest::DigestField;
2use crate::quiesce::MutationSource;
3use crate::replay::ReplayDisposition;
4use crate::snapshot::SnapshotField;
5use serde::Serialize;
6
7/// Typed name for restart-owned state components.
8#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
9#[serde(rename_all = "snake_case")]
10pub enum RestartComponentName {
11    OrderbookState,
12    CashLedger,
13    MarketCatalog,
14    PriceIvInputs,
15    HypercoreState,
16    MmpLiquidation,
17    AuthNonce,
18    TierRiskLimits,
19    PmSettlementState,
20    PersistentEngineStateEnvelope,
21}
22
23impl RestartComponentName {
24    pub const fn as_str(self) -> &'static str {
25        match self {
26            Self::OrderbookState => "orderbook_state",
27            Self::CashLedger => "cash_ledger",
28            Self::MarketCatalog => "market_catalog",
29            Self::PriceIvInputs => "price_iv_inputs",
30            Self::HypercoreState => "hypercore_state",
31            Self::MmpLiquidation => "mmp_liquidation",
32            Self::AuthNonce => "auth_nonce",
33            Self::TierRiskLimits => "tier_risk_limits",
34            Self::PmSettlementState => "pm_settlement_state",
35            Self::PersistentEngineStateEnvelope => "persistent_engine_state_envelope",
36        }
37    }
38}
39
40impl std::fmt::Display for RestartComponentName {
41    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42        f.write_str(self.as_str())
43    }
44}
45
46/// Static metadata for a restart-owned component.
47#[derive(Debug, Clone, Copy, PartialEq, Eq)]
48pub struct RestartComponentDescriptor {
49    pub name: RestartComponentName,
50    pub mutation_sources: &'static [MutationSource],
51    pub snapshot_fields: &'static [SnapshotField],
52    pub digest_fields: &'static [DigestField],
53}
54
55/// Contract every restart-owned component must implement.
56///
57/// The concrete engine state and command types still live outside this crate.
58/// Capture and restore contexts are intentionally separate because snapshot
59/// capture often needs a durable boundary while restore mutates engine state.
60pub trait RestartStateComponent<CaptureCtx, RestoreCtx, Command, Digest> {
61    const NAME: RestartComponentName;
62    type Snapshot;
63
64    fn capture(ctx: &CaptureCtx) -> Self::Snapshot;
65    fn restore(ctx: &mut RestoreCtx, snapshot: &Self::Snapshot);
66    fn digest(ctx: &CaptureCtx) -> Digest;
67    fn replay(command: &Command, ctx: &mut RestoreCtx) -> ReplayDisposition;
68    fn mutation_sources() -> &'static [MutationSource];
69
70    fn descriptor() -> RestartComponentDescriptor {
71        RestartComponentDescriptor {
72            name: Self::NAME,
73            mutation_sources: Self::mutation_sources(),
74            snapshot_fields: &[],
75            digest_fields: &[],
76        }
77    }
78}