miden_node_store/genesis/
mod.rs1use miden_protocol::Word;
2use miden_protocol::account::{Account, AccountPatch, AccountUpdateDetails};
3use miden_protocol::block::account_tree::{AccountIdKey, AccountTree};
4use miden_protocol::block::{
5 BlockAccountUpdate,
6 BlockBody,
7 BlockHeader,
8 BlockNoteTree,
9 BlockNumber,
10 BlockSignatures,
11 FeeParameters,
12 SignedBlock,
13 ValidatorConfig,
14};
15use miden_protocol::crypto::merkle::mmr::{Forest, MmrPeaks};
16use miden_protocol::crypto::merkle::smt::Smt;
17use miden_protocol::note::Nullifier;
18use miden_protocol::protocol_config::ProtocolConfig;
19use miden_protocol::transaction::OrderedTransactionHeaders;
20
21pub mod config;
22
23pub use miden_node_utils::genesis::GenesisBlock;
24
25#[derive(Clone, Debug, PartialEq, Eq)]
30pub struct GenesisState {
31 pub accounts: Vec<Account>,
32 pub fee_parameters: FeeParameters,
33 pub timestamp: u32,
34 pub validator_config: ValidatorConfig,
35 pub protocol_config: ProtocolConfig,
36}
37
38impl GenesisState {
39 pub fn new(
40 accounts: Vec<Account>,
41 fee_parameters: FeeParameters,
42 timestamp: u32,
43 validator_config: ValidatorConfig,
44 protocol_config: ProtocolConfig,
45 ) -> Self {
46 Self {
47 accounts,
48 fee_parameters,
49 timestamp,
50 validator_config,
51 protocol_config,
52 }
53 }
54
55 pub fn into_block(self) -> anyhow::Result<GenesisBlock> {
61 let accounts: Vec<BlockAccountUpdate> = self
62 .accounts
63 .iter()
64 .map(|account| -> anyhow::Result<_> {
65 let account_update_details = if account.id().is_private() {
66 AccountUpdateDetails::Private
67 } else {
68 AccountUpdateDetails::Public(AccountPatch::try_from(account.clone())?)
69 };
70
71 Ok(BlockAccountUpdate::new(
72 account.id(),
73 account.to_commitment(),
74 account_update_details,
75 )?)
76 })
77 .collect::<Result<Vec<_>, _>>()?;
78
79 let smt_entries = accounts.iter().map(|update| {
81 (
82 AccountIdKey::from(update.account_id()).as_word(),
83 update.final_state_commitment(),
84 )
85 });
86
87 let smt =
88 Smt::with_entries(smt_entries).expect("Failed to create LargeSmt for genesis accounts");
89
90 let account_smt = AccountTree::new(smt).expect("Failed to create AccountTree for genesis");
91
92 let empty_nullifiers: Vec<Nullifier> = Vec::new();
93 let empty_nullifier_tree = Smt::new();
94
95 let empty_output_notes = Vec::new();
96 let empty_block_note_tree = BlockNoteTree::empty();
97
98 let empty_transactions = OrderedTransactionHeaders::new_unchecked(Vec::new());
99
100 let validator_config = self.validator_config;
101
102 let header = BlockHeader::new(
103 Word::empty(),
104 BlockNumber::GENESIS,
105 MmrPeaks::new(Forest::empty(), Vec::new()).unwrap().hash_peaks(),
106 account_smt.root(),
107 empty_nullifier_tree.root(),
108 empty_block_note_tree.root(),
109 empty_transactions.commitment(),
110 validator_config,
111 self.fee_parameters,
112 self.protocol_config.to_commitment(),
113 None,
114 self.timestamp,
115 );
116
117 let body = BlockBody::new_unchecked(
118 accounts,
119 empty_output_notes,
120 empty_nullifiers,
121 empty_transactions,
122 );
123
124 let signatures = BlockSignatures::new(Vec::new())
125 .map_err(|err| anyhow::anyhow!("failed to build empty genesis signatures: {err}"))?;
126
127 GenesisBlock::new(SignedBlock::new(header, body, signatures)?, self.protocol_config)
128 }
129}