1use mina_p2p_messages::{
2 bigint::InvalidBigInt,
3 v2::{self, StateHash},
4};
5
6use crate::constants::{constraint_constants, slots_per_window};
7
8#[allow(clippy::too_many_arguments)]
9pub fn genesis_and_negative_one_protocol_states(
10 constants: v2::MinaBaseProtocolConstantsCheckedValueStableV1,
11 genesis_ledger_hash: v2::LedgerHash,
12 genesis_total_currency: v2::CurrencyAmountStableV1,
13 staking_epoch_ledger_hash: v2::LedgerHash,
14 staking_epoch_total_currency: v2::CurrencyAmountStableV1,
15 next_epoch_ledger_hash: v2::LedgerHash,
16 next_epoch_total_currency: v2::CurrencyAmountStableV1,
17 genesis_winner: v2::NonZeroCurvePoint,
18 empty_pending_coinbase_hash: v2::PendingCoinbaseHash,
19 empty_local_state: v2::MinaTransactionLogicZkappCommandLogicLocalStateValueStableV1,
20 empty_body_hash: v2::ConsensusBodyReferenceStableV1,
21 genesis_vrf_output: v2::ConsensusVrfOutputTruncatedStableV1,
22 staking_epoch_seed: v2::EpochSeed,
23 next_epoch_seed: v2::EpochSeed,
24 updated_next_epoch_seed: v2::EpochSeed,
25) -> Result<
26 (
27 v2::MinaStateProtocolStateValueStableV2,
28 v2::MinaStateProtocolStateValueStableV2,
29 StateHash,
30 ),
31 InvalidBigInt,
32> {
33 let negative_one = protocol_state(
34 constants.clone(),
35 genesis_ledger_hash.clone(),
36 genesis_total_currency.clone(),
37 staking_epoch_ledger_hash.clone(),
38 staking_epoch_total_currency.clone(),
39 next_epoch_ledger_hash.clone(),
40 next_epoch_total_currency.clone(),
41 genesis_winner.clone(),
42 empty_pending_coinbase_hash.clone(),
43 empty_local_state.clone(),
44 empty_body_hash.clone(),
45 staking_epoch_seed.clone(),
46 next_epoch_seed.clone(),
47 true,
48 );
49 let negative_one_hash = negative_one.try_hash()?;
50 let mut genesis = protocol_state(
51 constants,
52 genesis_ledger_hash,
53 genesis_total_currency,
54 staking_epoch_ledger_hash,
55 staking_epoch_total_currency,
56 next_epoch_ledger_hash,
57 next_epoch_total_currency,
58 genesis_winner,
59 empty_pending_coinbase_hash,
60 empty_local_state,
61 empty_body_hash,
62 staking_epoch_seed,
63 updated_next_epoch_seed.clone(),
64 false,
65 );
66 if constraint_constants().fork.is_none() {
67 genesis.previous_state_hash = negative_one_hash.clone();
68 }
69 genesis.body.genesis_state_hash = negative_one_hash.clone();
70 genesis.body.consensus_state.last_vrf_output = genesis_vrf_output;
71 genesis.body.consensus_state.next_epoch_data =
72 v2::ConsensusProofOfStakeDataEpochDataNextValueVersionedValueStableV1 {
73 seed: updated_next_epoch_seed,
74 lock_checkpoint: negative_one_hash,
75 epoch_length: 2.into(),
76 ..genesis.body.consensus_state.next_epoch_data
77 };
78 let genesis_hash = genesis.try_hash()?;
79
80 Ok((negative_one, genesis, genesis_hash))
81}
82
83#[allow(clippy::too_many_arguments)]
84fn protocol_state(
85 constants: v2::MinaBaseProtocolConstantsCheckedValueStableV1,
86 genesis_ledger_hash: v2::LedgerHash,
87 genesis_total_currency: v2::CurrencyAmountStableV1,
88 staking_epoch_ledger_hash: v2::LedgerHash,
89 staking_epoch_total_currency: v2::CurrencyAmountStableV1,
90 next_epoch_ledger_hash: v2::LedgerHash,
91 next_epoch_total_currency: v2::CurrencyAmountStableV1,
92 genesis_winner: v2::NonZeroCurvePoint,
93 empty_pending_coinbase_hash: v2::PendingCoinbaseHash,
94 empty_local_state: v2::MinaTransactionLogicZkappCommandLogicLocalStateValueStableV1,
95 empty_body_hash: v2::ConsensusBodyReferenceStableV1,
96 staking_epoch_seed: v2::EpochSeed,
97 next_epoch_seed: v2::EpochSeed,
98 negative_one: bool,
99) -> v2::MinaStateProtocolStateValueStableV2 {
100 v2::MinaStateProtocolStateValueStableV2 {
101 previous_state_hash: match constraint_constants().fork.as_ref() {
102 None => StateHash::zero(),
103 Some(_) if negative_one => StateHash::zero(),
104 Some(fork) => StateHash::from_fp(fork.state_hash),
105 },
106 body: v2::MinaStateProtocolStateBodyValueStableV2 {
107 genesis_state_hash: StateHash::zero(),
108 blockchain_state: blockchain_state(
109 genesis_ledger_hash.clone(),
110 constants.genesis_state_timestamp,
111 empty_pending_coinbase_hash,
112 empty_local_state,
113 empty_body_hash,
114 ),
115 consensus_state: consensus_state(
116 &constants,
117 genesis_total_currency,
118 staking_epoch_ledger_hash,
119 staking_epoch_total_currency,
120 next_epoch_ledger_hash,
121 next_epoch_total_currency,
122 genesis_winner,
123 staking_epoch_seed,
124 next_epoch_seed,
125 negative_one,
126 ),
127 constants,
128 },
129 }
130}
131
132fn blockchain_state(
133 genesis_ledger_hash: v2::LedgerHash,
134 genesis_state_timestamp: v2::BlockTimeTimeStableV1,
135 empty_pending_coinbase_hash: v2::PendingCoinbaseHash,
136 empty_local_state: v2::MinaTransactionLogicZkappCommandLogicLocalStateValueStableV1,
137 empty_body_hash: v2::ConsensusBodyReferenceStableV1,
138) -> v2::MinaStateBlockchainStateValueStableV2 {
139 let stmt_registers = v2::MinaStateBlockchainStateValueStableV2LedgerProofStatementSource {
140 first_pass_ledger: genesis_ledger_hash.clone(),
141 second_pass_ledger: genesis_ledger_hash.clone(),
142 pending_coinbase_stack: v2::MinaBasePendingCoinbaseStackVersionedStableV1::empty(),
143 local_state: empty_local_state,
144 };
145 let empty_fee_excess = v2::TokenFeeExcess {
146 token: v2::TokenIdKeyHash::default(),
147 amount: v2::SignedAmount {
148 magnitude: v2::CurrencyFeeStableV1(0u64.into()),
149 sgn: v2::SgnStableV1::Pos,
150 },
151 };
152 let ledger_proof_statement = v2::MinaStateBlockchainStateValueStableV2LedgerProofStatement {
153 source: stmt_registers.clone(),
154 target: stmt_registers.clone(),
155 connecting_ledger_left: genesis_ledger_hash.clone(),
156 connecting_ledger_right: genesis_ledger_hash.clone(),
157 supply_increase: v2::MinaStateBlockchainStateValueStableV2SignedAmount {
158 magnitude: v2::CurrencyAmountStableV1(0u64.into()),
159 sgn: v2::SgnStableV1::Pos,
160 },
161 fee_excess: v2::MinaBaseFeeExcessStableV1(empty_fee_excess.clone(), empty_fee_excess),
162 sok_digest: (),
163 };
164
165 v2::MinaStateBlockchainStateValueStableV2 {
166 staged_ledger_hash: v2::MinaBaseStagedLedgerHashStableV1::zero(
167 genesis_ledger_hash.clone(),
168 empty_pending_coinbase_hash,
169 ),
170 genesis_ledger_hash,
171 ledger_proof_statement,
172 timestamp: genesis_state_timestamp,
173 body_reference: empty_body_hash,
174 }
175}
176
177#[allow(clippy::too_many_arguments)]
178fn consensus_state(
179 constants: &v2::MinaBaseProtocolConstantsCheckedValueStableV1,
180 genesis_total_currency: v2::CurrencyAmountStableV1,
181 staking_epoch_ledger_hash: v2::LedgerHash,
182 staking_epoch_total_currency: v2::CurrencyAmountStableV1,
183 next_epoch_ledger_hash: v2::LedgerHash,
184 next_epoch_total_currency: v2::CurrencyAmountStableV1,
185 genesis_winner: v2::NonZeroCurvePoint,
186 staking_epoch_seed: v2::EpochSeed,
187 next_epoch_seed: v2::EpochSeed,
188 negative_one: bool,
189) -> v2::ConsensusProofOfStakeDataConsensusStateValueStableV2 {
190 let is_genesis = if negative_one { 0 } else { 1 };
191 let (blockchain_length, global_slot_since_genesis) = match constraint_constants().fork.as_ref()
192 {
193 None => (is_genesis, 0),
194 Some(fork) => (
195 fork.blockchain_length + is_genesis,
196 fork.global_slot_since_genesis,
197 ),
198 };
199
200 v2::ConsensusProofOfStakeDataConsensusStateValueStableV2 {
201 blockchain_length: v2::UnsignedExtendedUInt32StableV1(blockchain_length.into()),
202 epoch_count: v2::UnsignedExtendedUInt32StableV1::default(),
203 min_window_density: slots_per_window(constants).into(),
204 sub_window_densities: std::iter::once(is_genesis.into())
205 .chain(
206 (1..constraint_constants().sub_windows_per_window)
207 .map(|_| constants.slots_per_sub_window),
208 )
209 .collect(),
210 last_vrf_output: v2::ConsensusVrfOutputTruncatedStableV1::zero(),
211 total_currency: genesis_total_currency,
212 curr_global_slot_since_hard_fork: v2::ConsensusGlobalSlotStableV1 {
213 slot_number: v2::MinaNumbersGlobalSlotSinceHardForkMStableV1::SinceHardFork(
214 v2::UnsignedExtendedUInt32StableV1::default(),
215 ),
216 slots_per_epoch: constants.slots_per_epoch,
217 },
218 global_slot_since_genesis: v2::MinaNumbersGlobalSlotSinceGenesisMStableV1::SinceGenesis(
219 global_slot_since_genesis.into(),
220 ),
221 staking_epoch_data:
222 v2::ConsensusProofOfStakeDataEpochDataStakingValueVersionedValueStableV1::zero(
223 staking_epoch_ledger_hash,
224 staking_epoch_total_currency,
225 staking_epoch_seed,
226 ),
227 next_epoch_data:
228 v2::ConsensusProofOfStakeDataEpochDataNextValueVersionedValueStableV1::zero(
229 next_epoch_ledger_hash,
230 next_epoch_total_currency,
231 next_epoch_seed,
232 ),
233 has_ancestor_in_same_checkpoint_window: !negative_one,
234 block_stake_winner: genesis_winner.clone(),
235 block_creator: genesis_winner.clone(),
236 coinbase_receiver: genesis_winner,
237 supercharge_coinbase: true,
238 }
239}