node/transition_frontier/sync/ledger/
mod.rs

1pub mod snarked;
2pub mod staged;
3
4mod transition_frontier_sync_ledger_state;
5pub use transition_frontier_sync_ledger_state::*;
6
7mod transition_frontier_sync_ledger_actions;
8pub use transition_frontier_sync_ledger_actions::*;
9
10mod transition_frontier_sync_ledger_reducer;
11
12mod transition_frontier_sync_ledger_effects;
13pub use transition_frontier_sync_ledger_effects::*;
14
15use mina_p2p_messages::v2::{LedgerHash, MinaBaseStagedLedgerHashStableV1, StateHash};
16use openmina_core::block::ArcBlockWithHash;
17use serde::{Deserialize, Serialize};
18
19#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
20pub enum SyncLedgerTargetKind {
21    StakingEpoch,
22    NextEpoch,
23    Root,
24}
25
26#[derive(Serialize, Deserialize, Debug, Clone)]
27pub struct SyncLedgerTarget {
28    pub kind: SyncLedgerTargetKind,
29    pub snarked_ledger_hash: LedgerHash,
30    pub staged: Option<SyncStagedLedgerTarget>,
31}
32
33#[derive(Serialize, Deserialize, Debug, Clone)]
34pub struct SyncLedgerTargetWithStaged {
35    pub kind: SyncLedgerTargetKind,
36    pub snarked_ledger_hash: LedgerHash,
37    pub staged: SyncStagedLedgerTarget,
38}
39
40#[derive(Serialize, Deserialize, Debug, Clone)]
41pub struct SyncStagedLedgerTarget {
42    pub block_hash: StateHash,
43    pub hashes: MinaBaseStagedLedgerHashStableV1,
44}
45
46impl SyncLedgerTarget {
47    /// Set synchronization target to ledger at the root of transition frontier.
48    pub fn root(root_block: &ArcBlockWithHash) -> Self {
49        Self {
50            kind: SyncLedgerTargetKind::Root,
51            snarked_ledger_hash: root_block.snarked_ledger_hash().clone(),
52            staged: Some(SyncStagedLedgerTarget {
53                block_hash: root_block.hash().clone(),
54                hashes: root_block.staged_ledger_hashes().clone(),
55            }),
56        }
57    }
58
59    /// Set synchronization target to current best tip's staking epoch ledger.
60    pub fn staking_epoch(best_tip: &ArcBlockWithHash) -> Self {
61        // TODO(tizoc): should this return None when it matches the genesis ledger?
62        Self {
63            kind: SyncLedgerTargetKind::StakingEpoch,
64            snarked_ledger_hash: best_tip.staking_epoch_ledger_hash().clone(),
65            staged: None,
66        }
67    }
68
69    /// Set synchronization target to current best tip's staking epoch ledger.
70    ///
71    /// Will return `None` if we shouldn't synchronize it, in case when
72    /// current next_epoch_ledger isn't finalized (reached root) or it
73    /// is equal to the genesis ledger.
74    ///
75    /// In such case, we will reconstruct next_epoch_ledger anyways,
76    /// once transition frontier's root will be first slot in the bew epoch.
77    pub fn next_epoch(best_tip: &ArcBlockWithHash, root_block: &ArcBlockWithHash) -> Option<Self> {
78        if best_tip.next_epoch_ledger_hash() != root_block.next_epoch_ledger_hash() {
79            return None;
80        } else if best_tip.next_epoch_ledger_hash() == best_tip.genesis_ledger_hash() {
81            return None;
82        }
83        Some(Self {
84            kind: SyncLedgerTargetKind::NextEpoch,
85            snarked_ledger_hash: best_tip.next_epoch_ledger_hash().clone(),
86            staged: None,
87        })
88    }
89
90    pub fn with_staged(self) -> Option<SyncLedgerTargetWithStaged> {
91        Some(SyncLedgerTargetWithStaged {
92            kind: self.kind,
93            snarked_ledger_hash: self.snarked_ledger_hash,
94            staged: self.staged?,
95        })
96    }
97}
98
99impl From<SyncLedgerTargetWithStaged> for SyncLedgerTarget {
100    fn from(value: SyncLedgerTargetWithStaged) -> Self {
101        Self {
102            kind: value.kind,
103            snarked_ledger_hash: value.snarked_ledger_hash,
104            staged: Some(value.staged),
105        }
106    }
107}