mina_tree/scan_state/transaction_logic/
protocol_state.rs1use crate::{
2 proofs::field::FieldWitness,
3 scan_state::currency::{Amount, Length, Signed, Slot},
4 sparse_ledger::LedgerIntf,
5};
6use mina_curves::pasta::Fp;
7use mina_p2p_messages::{
8 bigint::InvalidBigInt,
9 v2::{self, MinaStateProtocolStateValueStableV2},
10};
11
12#[derive(Debug, Clone)]
13pub struct EpochLedger<F: FieldWitness> {
14 pub hash: F,
15 pub total_currency: Amount,
16}
17
18#[derive(Debug, Clone)]
19pub struct EpochData<F: FieldWitness> {
20 pub ledger: EpochLedger<F>,
21 pub seed: F,
22 pub start_checkpoint: F,
23 pub lock_checkpoint: F,
24 pub epoch_length: Length,
25}
26
27#[derive(Debug, Clone)]
28pub struct ProtocolStateView {
29 pub snarked_ledger_hash: Fp,
30 pub blockchain_length: Length,
31 pub min_window_density: Length,
32 pub total_currency: Amount,
33 pub global_slot_since_genesis: Slot,
34 pub staking_epoch_data: EpochData<Fp>,
35 pub next_epoch_data: EpochData<Fp>,
36}
37
38pub fn protocol_state_view(
40 state: &MinaStateProtocolStateValueStableV2,
41) -> Result<ProtocolStateView, InvalidBigInt> {
42 let MinaStateProtocolStateValueStableV2 {
43 previous_state_hash: _,
44 body,
45 } = state;
46
47 protocol_state_body_view(body)
48}
49
50pub fn protocol_state_body_view(
51 body: &v2::MinaStateProtocolStateBodyValueStableV2,
52) -> Result<ProtocolStateView, InvalidBigInt> {
53 let cs = &body.consensus_state;
54 let sed = &cs.staking_epoch_data;
55 let ned = &cs.next_epoch_data;
56
57 Ok(ProtocolStateView {
58 snarked_ledger_hash: body
61 .blockchain_state
62 .ledger_proof_statement
63 .target
64 .first_pass_ledger
65 .to_field()?,
66 blockchain_length: Length(cs.blockchain_length.as_u32()),
67 min_window_density: Length(cs.min_window_density.as_u32()),
68 total_currency: Amount(cs.total_currency.as_u64()),
69 global_slot_since_genesis: (&cs.global_slot_since_genesis).into(),
70 staking_epoch_data: EpochData {
71 ledger: EpochLedger {
72 hash: sed.ledger.hash.to_field()?,
73 total_currency: Amount(sed.ledger.total_currency.as_u64()),
74 },
75 seed: sed.seed.to_field()?,
76 start_checkpoint: sed.start_checkpoint.to_field()?,
77 lock_checkpoint: sed.lock_checkpoint.to_field()?,
78 epoch_length: Length(sed.epoch_length.as_u32()),
79 },
80 next_epoch_data: EpochData {
81 ledger: EpochLedger {
82 hash: ned.ledger.hash.to_field()?,
83 total_currency: Amount(ned.ledger.total_currency.as_u64()),
84 },
85 seed: ned.seed.to_field()?,
86 start_checkpoint: ned.start_checkpoint.to_field()?,
87 lock_checkpoint: ned.lock_checkpoint.to_field()?,
88 epoch_length: Length(ned.epoch_length.as_u32()),
89 },
90 })
91}
92
93pub type GlobalState<L> = GlobalStateSkeleton<L, Signed<Amount>, Slot>;
94
95#[derive(Debug, Clone)]
96pub struct GlobalStateSkeleton<L, SignedAmount, Slot> {
97 pub first_pass_ledger: L,
98 pub second_pass_ledger: L,
99 pub fee_excess: SignedAmount,
100 pub supply_increase: SignedAmount,
101 pub protocol_state: ProtocolStateView,
102 pub block_global_slot: Slot,
106}
107
108impl<L: LedgerIntf + Clone> GlobalState<L> {
109 pub fn first_pass_ledger(&self) -> L {
110 self.first_pass_ledger.create_masked()
111 }
112
113 #[must_use]
114 pub fn set_first_pass_ledger(&self, should_update: bool, ledger: L) -> Self {
115 let mut this = self.clone();
116 if should_update {
117 this.first_pass_ledger.apply_mask(ledger);
118 }
119 this
120 }
121
122 pub fn second_pass_ledger(&self) -> L {
123 self.second_pass_ledger.create_masked()
124 }
125
126 #[must_use]
127 pub fn set_second_pass_ledger(&self, should_update: bool, ledger: L) -> Self {
128 let mut this = self.clone();
129 if should_update {
130 this.second_pass_ledger.apply_mask(ledger);
131 }
132 this
133 }
134
135 pub fn fee_excess(&self) -> Signed<Amount> {
136 self.fee_excess
137 }
138
139 #[must_use]
140 pub fn set_fee_excess(&self, fee_excess: Signed<Amount>) -> Self {
141 let mut this = self.clone();
142 this.fee_excess = fee_excess;
143 this
144 }
145
146 pub fn supply_increase(&self) -> Signed<Amount> {
147 self.supply_increase
148 }
149
150 #[must_use]
151 pub fn set_supply_increase(&self, supply_increase: Signed<Amount>) -> Self {
152 let mut this = self.clone();
153 this.supply_increase = supply_increase;
154 this
155 }
156
157 pub fn block_global_slot(&self) -> Slot {
158 self.block_global_slot
159 }
160}