miden_node_store/
genesis.rs

1use miden_lib::transaction::TransactionKernel;
2use miden_objects::{
3    Digest,
4    account::{Account, delta::AccountUpdateDetails},
5    block::{
6        AccountTree, BlockAccountUpdate, BlockHeader, BlockNoteTree, BlockNumber, ProvenBlock,
7    },
8    crypto::merkle::{MmrPeaks, Smt},
9    note::Nullifier,
10    transaction::OrderedTransactionHeaders,
11    utils::serde::{ByteReader, Deserializable, DeserializationError},
12};
13
14use crate::errors::GenesisError;
15
16// GENESIS STATE
17// ================================================================================================
18
19/// Represents the state at genesis, which will be used to derive the genesis block.
20#[derive(Clone, Debug, PartialEq, Eq)]
21pub struct GenesisState {
22    pub accounts: Vec<Account>,
23    pub version: u32,
24    pub timestamp: u32,
25}
26
27/// A type-safety wrapper ensuring that genesis block data can only be created from
28/// [`GenesisState`].
29pub struct GenesisBlock(ProvenBlock);
30
31impl GenesisBlock {
32    pub fn inner(&self) -> &ProvenBlock {
33        &self.0
34    }
35
36    pub fn into_inner(self) -> ProvenBlock {
37        self.0
38    }
39}
40
41impl GenesisState {
42    pub fn new(accounts: Vec<Account>, version: u32, timestamp: u32) -> Self {
43        Self { accounts, version, timestamp }
44    }
45
46    /// Returns the block header and the account SMT
47    pub fn into_block(self) -> Result<GenesisBlock, GenesisError> {
48        let accounts: Vec<BlockAccountUpdate> = self
49            .accounts
50            .iter()
51            .map(|account| {
52                let account_update_details = if account.id().is_public() {
53                    AccountUpdateDetails::New(account.clone())
54                } else {
55                    AccountUpdateDetails::Private
56                };
57
58                BlockAccountUpdate::new(account.id(), account.commitment(), account_update_details)
59            })
60            .collect();
61
62        let account_smt = AccountTree::with_entries(
63            accounts
64                .iter()
65                .map(|update| (update.account_id(), update.final_state_commitment())),
66        )
67        .map_err(GenesisError::AccountTree)?;
68
69        let empty_nullifiers: Vec<Nullifier> = Vec::new();
70        let empty_nullifier_tree = Smt::new();
71
72        let empty_output_notes = Vec::new();
73        let empty_block_note_tree = BlockNoteTree::empty();
74
75        let empty_transactions = OrderedTransactionHeaders::new_unchecked(Vec::new());
76
77        let header = BlockHeader::new(
78            self.version,
79            Digest::default(),
80            BlockNumber::GENESIS,
81            MmrPeaks::new(0, Vec::new()).unwrap().hash_peaks(),
82            account_smt.root(),
83            empty_nullifier_tree.root(),
84            empty_block_note_tree.root(),
85            Digest::default(),
86            TransactionKernel::kernel_commitment(),
87            Digest::default(),
88            self.timestamp,
89        );
90
91        // SAFETY: Header and accounts should be valid by construction.
92        // No notes or nullifiers are created at genesis, which is consistent with the above empty
93        // block note tree root and empty nullifier tree root.
94        Ok(GenesisBlock(ProvenBlock::new_unchecked(
95            header,
96            accounts,
97            empty_output_notes,
98            empty_nullifiers,
99            empty_transactions,
100        )))
101    }
102}
103
104// SERIALIZATION
105// ================================================================================================
106
107impl Deserializable for GenesisState {
108    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
109        let num_accounts = source.read_usize()?;
110        let accounts = source.read_many::<Account>(num_accounts)?;
111
112        let version = source.read_u32()?;
113        let timestamp = source.read_u32()?;
114
115        Ok(Self::new(accounts, version, timestamp))
116    }
117}