miden_node_store/
genesis.rs1use miden_lib::transaction::TransactionKernel;
2use miden_objects::{
3 ACCOUNT_TREE_DEPTH, Digest,
4 account::{Account, delta::AccountUpdateDetails},
5 block::{BlockAccountUpdate, BlockHeader, BlockNoteTree, BlockNumber, ProvenBlock},
6 crypto::merkle::{MmrPeaks, SimpleSmt, Smt},
7 note::Nullifier,
8 utils::serde::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable},
9};
10
11use crate::errors::GenesisError;
12
13#[derive(Debug, PartialEq, Eq)]
18pub struct GenesisState {
19 pub accounts: Vec<Account>,
20 pub version: u32,
21 pub timestamp: u32,
22}
23
24impl GenesisState {
25 pub fn new(accounts: Vec<Account>, version: u32, timestamp: u32) -> Self {
26 Self { accounts, version, timestamp }
27 }
28
29 pub fn into_block(self) -> Result<ProvenBlock, GenesisError> {
31 let accounts: Vec<BlockAccountUpdate> = self
32 .accounts
33 .iter()
34 .map(|account| {
35 let account_update_details = if account.id().is_public() {
36 AccountUpdateDetails::New(account.clone())
37 } else {
38 AccountUpdateDetails::Private
39 };
40
41 BlockAccountUpdate::new(
42 account.id(),
43 account.commitment(),
44 account_update_details,
45 vec![],
46 )
47 })
48 .collect();
49
50 let account_smt: SimpleSmt<ACCOUNT_TREE_DEPTH> =
51 SimpleSmt::with_leaves(accounts.iter().map(|update| {
52 (update.account_id().prefix().into(), update.final_state_commitment().into())
53 }))?;
54
55 let empty_nullifiers: Vec<Nullifier> = Vec::new();
56 let empty_nullifier_tree = Smt::new();
57
58 let empty_output_notes = Vec::new();
59 let empty_block_note_tree = BlockNoteTree::empty();
60
61 let header = BlockHeader::new(
62 self.version,
63 Digest::default(),
64 BlockNumber::GENESIS,
65 MmrPeaks::new(0, Vec::new()).unwrap().hash_peaks(),
66 account_smt.root(),
67 empty_nullifier_tree.root(),
68 empty_block_note_tree.root(),
69 Digest::default(),
70 TransactionKernel::kernel_commitment(),
71 Digest::default(),
72 self.timestamp,
73 );
74
75 Ok(ProvenBlock::new_unchecked(
79 header,
80 accounts,
81 empty_output_notes,
82 empty_nullifiers,
83 ))
84 }
85}
86
87impl Serializable for GenesisState {
91 fn write_into<W: ByteWriter>(&self, target: &mut W) {
92 assert!(u64::try_from(self.accounts.len()).is_ok(), "too many accounts in GenesisState");
93 target.write_usize(self.accounts.len());
94 target.write_many(&self.accounts);
95
96 target.write_u32(self.version);
97 target.write_u32(self.timestamp);
98 }
99}
100
101impl Deserializable for GenesisState {
102 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
103 let num_accounts = source.read_usize()?;
104 let accounts = source.read_many::<Account>(num_accounts)?;
105
106 let version = source.read_u32()?;
107 let timestamp = source.read_u32()?;
108
109 Ok(Self::new(accounts, version, timestamp))
110 }
111}