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