miden_node_store/genesis/
mod.rs1use miden_protocol::Word;
2use miden_protocol::account::delta::AccountUpdateDetails;
3use miden_protocol::account::{Account, AccountDelta};
4use miden_protocol::block::account_tree::{AccountTree, account_id_to_smt_key};
5use miden_protocol::block::{
6 BlockAccountUpdate,
7 BlockBody,
8 BlockHeader,
9 BlockNoteTree,
10 BlockNumber,
11 BlockProof,
12 BlockSigner,
13 FeeParameters,
14 ProvenBlock,
15};
16use miden_protocol::crypto::merkle::mmr::{Forest, MmrPeaks};
17use miden_protocol::crypto::merkle::smt::{LargeSmt, MemoryStorage, Smt};
18use miden_protocol::note::Nullifier;
19use miden_protocol::transaction::{OrderedTransactionHeaders, TransactionKernel};
20
21use crate::errors::GenesisError;
22
23pub mod config;
24
25#[derive(Clone, Debug, PartialEq, Eq)]
30pub struct GenesisState<S> {
31 pub accounts: Vec<Account>,
32 pub fee_parameters: FeeParameters,
33 pub version: u32,
34 pub timestamp: u32,
35 pub block_signer: S,
36}
37
38pub struct GenesisBlock(ProvenBlock);
41
42impl GenesisBlock {
43 pub fn inner(&self) -> &ProvenBlock {
44 &self.0
45 }
46
47 pub fn into_inner(self) -> ProvenBlock {
48 self.0
49 }
50}
51
52impl<S> GenesisState<S> {
53 pub fn new(
54 accounts: Vec<Account>,
55 fee_parameters: FeeParameters,
56 version: u32,
57 timestamp: u32,
58 signer: S,
59 ) -> Self {
60 Self {
61 accounts,
62 fee_parameters,
63 version,
64 timestamp,
65 block_signer: signer,
66 }
67 }
68}
69
70impl<S: BlockSigner> GenesisState<S> {
71 pub fn into_block(self) -> Result<GenesisBlock, GenesisError> {
73 let accounts: Vec<BlockAccountUpdate> = self
74 .accounts
75 .iter()
76 .map(|account| {
77 let account_update_details = if account.id().is_public() {
78 AccountUpdateDetails::Delta(
79 AccountDelta::try_from(account.clone())
80 .map_err(GenesisError::AccountDelta)?,
81 )
82 } else {
83 AccountUpdateDetails::Private
84 };
85
86 Ok(BlockAccountUpdate::new(
87 account.id(),
88 account.commitment(),
89 account_update_details,
90 ))
91 })
92 .collect::<Result<Vec<_>, GenesisError>>()?;
93
94 let smt_entries = accounts.iter().map(|update| {
96 (account_id_to_smt_key(update.account_id()), update.final_state_commitment())
97 });
98
99 let smt = LargeSmt::with_entries(MemoryStorage::default(), smt_entries)
101 .expect("Failed to create LargeSmt for genesis accounts");
102
103 let account_smt = AccountTree::new(smt).expect("Failed to create AccountTree for genesis");
104
105 let empty_nullifiers: Vec<Nullifier> = Vec::new();
106 let empty_nullifier_tree = Smt::new();
107
108 let empty_output_notes = Vec::new();
109 let empty_block_note_tree = BlockNoteTree::empty();
110
111 let empty_transactions = OrderedTransactionHeaders::new_unchecked(Vec::new());
112
113 let header = BlockHeader::new(
114 self.version,
115 Word::empty(),
116 BlockNumber::GENESIS,
117 MmrPeaks::new(Forest::empty(), Vec::new()).unwrap().hash_peaks(),
118 account_smt.root(),
119 empty_nullifier_tree.root(),
120 empty_block_note_tree.root(),
121 Word::empty(),
122 TransactionKernel.to_commitment(),
123 self.block_signer.public_key(),
124 self.fee_parameters,
125 self.timestamp,
126 );
127
128 let body = BlockBody::new_unchecked(
129 accounts,
130 empty_output_notes,
131 empty_nullifiers,
132 empty_transactions,
133 );
134
135 let block_proof = BlockProof::new_dummy();
136
137 let signature = self.block_signer.sign(&header);
138 Ok(GenesisBlock(ProvenBlock::new_unchecked(header, body, signature, block_proof)))
142 }
143}