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