miden_node_store/
genesis.rs

1use 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// GENESIS STATE
14// ================================================================================================
15
16/// Represents the state at genesis, which will be used to derive the genesis block.
17#[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    /// Returns the block header and the account SMT
30    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        // SAFETY: Header and accounts should be valid by construction.
76        // No notes or nullifiers are created at genesis, which is consistent with the above empty
77        // block note tree root and empty nullifier tree root.
78        Ok(ProvenBlock::new_unchecked(
79            header,
80            accounts,
81            empty_output_notes,
82            empty_nullifiers,
83        ))
84    }
85}
86
87// SERIALIZATION
88// ================================================================================================
89
90impl 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}