miden_node_store/state/
sync_state.rs1use std::ops::RangeInclusive;
2
3use miden_crypto::dsa::ecdsa_k256_keccak::Signature;
4use miden_node_utils::tracing::miden_instrument;
5use miden_protocol::account::AccountId;
6use miden_protocol::block::{BlockHeader, BlockNumber};
7use miden_protocol::crypto::merkle::mmr::{Forest, MmrDelta, MmrProof};
8
9use super::State;
10use crate::COMPONENT;
11use crate::db::models::queries::StorageMapValuesPage;
12use crate::db::{AccountVaultValue, NoteSyncUpdate, NullifierInfo};
13use crate::errors::{DatabaseError, NoteSyncError, StateSyncError};
14
15impl State {
19 pub async fn sync_transactions(
22 &self,
23 account_ids: Vec<AccountId>,
24 block_range: RangeInclusive<BlockNumber>,
25 ) -> Result<(BlockNumber, Vec<crate::db::TransactionRecord>), DatabaseError> {
26 self.db.select_transactions_records(account_ids, block_range).await
27 }
28
29 #[miden_instrument(
31 level = "debug",
32 target = COMPONENT,
33 skip_all,
34 err,
35 )]
36 pub async fn sync_chain_mmr(
37 &self,
38 block_range: RangeInclusive<BlockNumber>,
39 ) -> Result<(MmrDelta, BlockHeader, Signature), StateSyncError> {
40 let block_from = *block_range.start();
41 let block_to = *block_range.end();
42
43 let (block_header, signature) = self
46 .db
47 .select_block_header_and_signature_by_block_num(block_to)
48 .await?
49 .expect("block_to should exist in the database");
50
51 if block_from == block_to {
52 return Ok((
53 MmrDelta {
54 forest: Forest::new(block_from.as_usize()).expect("block index fits in u32"),
55 data: vec![],
56 },
57 block_header,
58 signature,
59 ));
60 }
61
62 let from_forest = (block_from + 1).as_usize();
72 let to_forest = block_to.as_usize();
73
74 let mmr_delta = self
75 .inner
76 .read()
77 .await
78 .blockchain
79 .as_mmr()
80 .get_delta(
81 Forest::new(from_forest).expect("from_forest fits in u32"),
82 Forest::new(to_forest).expect("to_forest fits in u32"),
83 )
84 .map_err(StateSyncError::FailedToBuildMmrDelta)?;
85
86 Ok((mmr_delta, block_header, signature))
87 }
88
89 #[miden_instrument(
98 level = "debug",
99 target = COMPONENT,
100 skip_all,
101 err,
102 )]
103 pub async fn sync_notes(
104 &self,
105 note_tags: Vec<u32>,
106 block_range: RangeInclusive<BlockNumber>,
107 ) -> Result<(Vec<(NoteSyncUpdate, MmrProof)>, BlockNumber), NoteSyncError> {
108 let block_end = *block_range.end();
109 let mmr_checkpoint = block_end + 1;
113
114 let note_syncs = self.db.get_note_sync_multi(block_range, note_tags.into()).await?;
115
116 let mut results = Vec::new();
117
118 {
119 let inner = self.inner.read().await;
120
121 for note_sync in note_syncs {
122 let mmr_proof =
123 inner.blockchain.open_at(note_sync.block_header.block_num(), mmr_checkpoint)?;
124 results.push((note_sync, mmr_proof));
125 }
126 }
127
128 let last_block_checked =
130 results.last().map_or(block_end, |(update, _)| update.block_header.block_num());
131
132 Ok((results, last_block_checked))
133 }
134
135 pub async fn sync_nullifiers(
136 &self,
137 prefix_len: u32,
138 nullifier_prefixes: Vec<u32>,
139 block_range: RangeInclusive<BlockNumber>,
140 ) -> Result<(Vec<NullifierInfo>, BlockNumber), DatabaseError> {
141 self.db
142 .select_nullifiers_by_prefix(prefix_len, nullifier_prefixes, block_range)
143 .await
144 }
145
146 pub async fn sync_account_vault(
151 &self,
152 account_id: AccountId,
153 block_range: RangeInclusive<BlockNumber>,
154 ) -> Result<(BlockNumber, Vec<AccountVaultValue>), DatabaseError> {
155 self.db.get_account_vault_sync(account_id, block_range).await
156 }
157
158 pub async fn sync_account_storage_maps(
160 &self,
161 account_id: AccountId,
162 block_range: RangeInclusive<BlockNumber>,
163 ) -> Result<StorageMapValuesPage, DatabaseError> {
164 self.db.select_storage_map_sync_values(account_id, block_range, None).await
165 }
166}