瀏覽代碼

Narrow the saga/commit seam now that the ledger is never re-injected

The ledger handle is supplied when LedgerCtx is constructed, so the
deserialize-then-inject dance no longer exists. Drop inject_ledger and
rewrite the surrounding docs to describe the handle as construction-time
state rather than something reattached after a pause.

Reduce LoadedState and the load/plan phase helpers to private: they are
internal to the two-phase commit and were never meant to be part of the
crate's public surface.
Cesar Rodas 2 周之前
父節點
當前提交
319be8332d
共有 3 個文件被更改,包括 18 次插入24 次删除
  1. 0 1
      crates/kuatia/src/ledger.rs
  2. 7 7
      crates/kuatia/src/ledger/commit.rs
  3. 11 16
      crates/kuatia/src/saga.rs

+ 0 - 1
crates/kuatia/src/ledger.rs

@@ -34,7 +34,6 @@ mod query;
 mod transition;
 
 pub use balance::SubAccountBalance;
-pub use commit::LoadedState;
 
 /// Default grace window (milliseconds) for the balance projection watermark: how
 /// far behind live a snapshot is allowed to advance, covering commit-to-visibility

+ 7 - 7
crates/kuatia/src/ledger/commit.rs

@@ -77,15 +77,15 @@ enum PendingRecord {
 }
 
 /// State loaded in phase 1, passed to the pure validation in phase 2.
-pub struct LoadedState {
+struct LoadedState {
     /// Postings being consumed by the envelope.
-    pub consumed_postings: Vec<Posting>,
+    consumed_postings: Vec<Posting>,
     /// Accounts referenced by the envelope.
-    pub accounts: HashMap<AccountId, kuatia_core::Account>,
+    accounts: HashMap<AccountId, kuatia_core::Account>,
     /// Current balances for all referenced (account, asset) pairs.
-    pub balances: HashMap<(AccountId, AssetId), Cent>,
+    balances: HashMap<(AccountId, AssetId), Cent>,
     /// The book gating this transfer, if one is loaded (`None` = unrestricted default).
-    pub book: Option<Book>,
+    book: Option<Book>,
 }
 
 impl Ledger {
@@ -95,7 +95,7 @@ impl Ledger {
 
     /// Phase 1: load all state needed for validation.
     #[instrument(skip(self, envelope), name = "ledger.load")]
-    pub async fn load(&self, envelope: &Envelope) -> Result<LoadedState, LedgerError> {
+    async fn load(&self, envelope: &Envelope) -> Result<LoadedState, LedgerError> {
         let consumed_postings = if envelope.consumes().is_empty() {
             vec![]
         } else {
@@ -147,7 +147,7 @@ impl Ledger {
     }
 
     /// Phase 2: run pure validation and produce a plan.
-    pub fn plan(
+    fn plan(
         &self,
         envelope: &Envelope,
         loaded: &LoadedState,

+ 11 - 16
crates/kuatia/src/saga.rs

@@ -104,9 +104,8 @@ pub(crate) async fn verify_postings(
 
 /// Saga context that wraps a ledger and tracks state across steps.
 ///
-/// The ledger handle is `#[serde(skip)]` -- after deserializing a paused
-/// execution you must call [`inject_ledger`](LedgerCtx::inject_ledger)
-/// before resuming.
+/// The ledger handle is `#[serde(skip)]`: it is supplied when the context is
+/// constructed and is not part of the serialized form.
 #[derive(Clone, Serialize, Deserialize)]
 pub struct LedgerCtx {
     /// Receipts collected from completed steps.
@@ -161,23 +160,19 @@ impl LedgerCtx {
         }
     }
 
-    /// Re-inject the ledger handle after deserializing a paused execution.
-    pub fn inject_ledger(&mut self, ledger: Arc<Ledger>) {
-        self.ledger = Some(ledger);
-    }
-
-    /// Borrow the ledger, returning an error if not injected.
+    /// Borrow the ledger, returning an error if the handle is absent.
     pub fn ledger(&self) -> Result<&Ledger, LedgerError> {
-        self.ledger.as_ref().map(|l| l.as_ref()).ok_or_else(|| {
-            internal("ledger not injected -- call inject_ledger() after deserializing")
-        })
+        self.ledger
+            .as_ref()
+            .map(|l| l.as_ref())
+            .ok_or_else(|| internal("ledger handle missing from saga context"))
     }
 
-    /// Clone the ledger `Arc`, returning an error if not injected.
+    /// Clone the ledger `Arc`, returning an error if the handle is absent.
     pub fn ledger_arc(&self) -> Result<Arc<Ledger>, LedgerError> {
-        self.ledger.clone().ok_or_else(|| {
-            internal("ledger not injected -- call inject_ledger() after deserializing")
-        })
+        self.ledger
+            .clone()
+            .ok_or_else(|| internal("ledger handle missing from saga context"))
     }
 }