mina_core/block/
genesis.rs

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}