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