miden_node_store/state/
sync_state.rs1use std::ops::RangeInclusive;
2
3use miden_crypto::dsa::ecdsa_k256_keccak::Signature;
4use miden_protocol::account::AccountId;
5use miden_protocol::block::{BlockHeader, BlockNumber};
6use miden_protocol::crypto::merkle::mmr::{Forest, MmrDelta, MmrProof};
7use tracing::instrument;
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 #[instrument(level = "debug", target = COMPONENT, skip_all, ret(level = "debug"), err)]
31 pub async fn sync_chain_mmr(
32 &self,
33 block_range: RangeInclusive<BlockNumber>,
34 ) -> Result<(MmrDelta, BlockHeader, Signature), StateSyncError> {
35 let block_from = *block_range.start();
36 let block_to = *block_range.end();
37
38 let (block_header, signature) = self
41 .db
42 .select_block_header_and_signature_by_block_num(block_to)
43 .await?
44 .expect("block_to should exist in the database");
45
46 if block_from == block_to {
47 return Ok((
48 MmrDelta {
49 forest: Forest::new(block_from.as_usize()).expect("block index fits in u32"),
50 data: vec![],
51 },
52 block_header,
53 signature,
54 ));
55 }
56
57 let from_forest = (block_from + 1).as_usize();
67 let to_forest = block_to.as_usize();
68
69 let mmr_delta = self
70 .inner
71 .read()
72 .await
73 .blockchain
74 .as_mmr()
75 .get_delta(
76 Forest::new(from_forest).expect("from_forest fits in u32"),
77 Forest::new(to_forest).expect("to_forest fits in u32"),
78 )
79 .map_err(StateSyncError::FailedToBuildMmrDelta)?;
80
81 Ok((mmr_delta, block_header, signature))
82 }
83
84 #[instrument(level = "debug", target = COMPONENT, skip_all, ret(level = "debug"), err)]
93 pub async fn sync_notes(
94 &self,
95 note_tags: Vec<u32>,
96 block_range: RangeInclusive<BlockNumber>,
97 ) -> Result<(Vec<(NoteSyncUpdate, MmrProof)>, BlockNumber), NoteSyncError> {
98 let block_end = *block_range.end();
99 let mmr_checkpoint = block_end + 1;
103
104 let note_syncs = self.db.get_note_sync_multi(block_range, note_tags.into()).await?;
105
106 let mut results = Vec::new();
107
108 {
109 let inner = self.inner.read().await;
110
111 for note_sync in note_syncs {
112 let mmr_proof =
113 inner.blockchain.open_at(note_sync.block_header.block_num(), mmr_checkpoint)?;
114 results.push((note_sync, mmr_proof));
115 }
116 }
117
118 let last_block_checked =
120 results.last().map_or(block_end, |(update, _)| update.block_header.block_num());
121
122 Ok((results, last_block_checked))
123 }
124
125 pub async fn sync_nullifiers(
126 &self,
127 prefix_len: u32,
128 nullifier_prefixes: Vec<u32>,
129 block_range: RangeInclusive<BlockNumber>,
130 ) -> Result<(Vec<NullifierInfo>, BlockNumber), DatabaseError> {
131 self.db
132 .select_nullifiers_by_prefix(prefix_len, nullifier_prefixes, block_range)
133 .await
134 }
135
136 pub async fn sync_account_vault(
141 &self,
142 account_id: AccountId,
143 block_range: RangeInclusive<BlockNumber>,
144 ) -> Result<(BlockNumber, Vec<AccountVaultValue>), DatabaseError> {
145 self.db.get_account_vault_sync(account_id, block_range).await
146 }
147
148 pub async fn sync_account_storage_maps(
150 &self,
151 account_id: AccountId,
152 block_range: RangeInclusive<BlockNumber>,
153 ) -> Result<StorageMapValuesPage, DatabaseError> {
154 self.db.select_storage_map_sync_values(account_id, block_range, None).await
155 }
156}