miden_node_store/state/view/
state_witnesses.rs1use std::collections::BTreeMap;
4
5use miden_protocol::account::AccountId;
6use miden_protocol::block::account_tree::AccountWitness;
7use miden_protocol::block::nullifier_tree::NullifierWitness;
8use miden_protocol::note::Nullifier;
9
10use super::StateView;
11
12#[derive(Clone, Debug)]
14pub struct StateWitnesses {
15 pub account_witnesses: BTreeMap<AccountId, AccountWitness>,
16 pub nullifier_witnesses: BTreeMap<Nullifier, NullifierWitness>,
17}
18
19impl StateView {
20 pub fn get_state_witnesses(
22 &self,
23 account_ids: &[AccountId],
24 nullifiers: &[Nullifier],
25 ) -> StateWitnesses {
26 self.with_inner_read_blocking(|inner| {
27 let account_witnesses = account_ids
29 .iter()
30 .copied()
31 .map(|account_id| (account_id, inner.account_tree.open_latest(account_id)))
32 .collect::<BTreeMap<AccountId, AccountWitness>>();
33
34 let nullifier_witnesses: BTreeMap<Nullifier, NullifierWitness> = nullifiers
36 .iter()
37 .copied()
38 .map(|nullifier| (nullifier, inner.nullifier_tree.open(&nullifier)))
39 .collect();
40
41 StateWitnesses { account_witnesses, nullifier_witnesses }
42 })
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use miden_node_utils::fee::{test_fee_params, test_protocol_config};
49 use miden_protocol::Word;
50 use miden_protocol::block::ValidatorConfig;
51 use miden_protocol::note::Nullifier;
52 use miden_protocol::testing::random_secret_key::random_secret_key;
53
54 use crate::GenesisState;
55 use crate::state::State;
56
57 #[tokio::test(flavor = "multi_thread")]
58 async fn state_witnesses_include_requested_nullifiers() {
59 let data_directory = tempfile::tempdir().expect("tempdir should be created");
60 bootstrap_store(data_directory.path());
61 let (state, _block_writer, _proof_writer) = State::for_tests(data_directory.path()).await;
62
63 let nullifier = Nullifier::from_raw(Word::from([1_u32, 2, 3, 4]));
64 let witnesses = state.view().get_state_witnesses(&[], &[nullifier]);
65
66 assert!(witnesses.account_witnesses.is_empty());
67 assert!(witnesses.nullifier_witnesses.contains_key(&nullifier));
68 }
69
70 fn bootstrap_store(path: &std::path::Path) {
71 let signer = random_secret_key();
72 let genesis_state = GenesisState::new(
73 vec![],
74 test_fee_params(),
75 1,
76 ValidatorConfig::new(vec![signer.public_key()], 1)
77 .expect("validator config should be valid"),
78 test_protocol_config(),
79 );
80 let genesis_block = genesis_state.into_block().expect("genesis block should be created");
81
82 State::bootstrap(genesis_block, path).expect("store should bootstrap");
83 }
84}