mina_core/block/
genesis.rs

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}