use alloc::collections::BTreeMap;
use alloc::sync::Arc;
use miden_protocol::Word;
use miden_protocol::account::{AccountId, StorageMapKey, StorageMapWitness};
use miden_protocol::block::BlockNumber;
use miden_protocol::note::NoteScript;
use miden_protocol::transaction::AccountInputs;
use miden_tx::TransactionMastStore;
use crate::utils::RwLock;
pub(super) struct DataStoreCache {
pub(super) mast_store: Arc<TransactionMastStore>,
foreign_account_inputs: RwLock<BTreeMap<AccountId, AccountInputs>>,
note_scripts: RwLock<BTreeMap<Word, NoteScript>>,
storage_map_witnesses: RwLock<BTreeMap<(Word, StorageMapKey), StorageMapWitness>>,
ref_block: RwLock<Option<BlockNumber>>,
}
impl DataStoreCache {
pub(super) fn new() -> Self {
Self {
mast_store: Arc::new(TransactionMastStore::new()),
foreign_account_inputs: RwLock::new(BTreeMap::new()),
note_scripts: RwLock::new(BTreeMap::new()),
storage_map_witnesses: RwLock::new(BTreeMap::new()),
ref_block: RwLock::new(None),
}
}
pub(super) fn replace_foreign_account_inputs(
&self,
foreign_accounts: impl IntoIterator<Item = AccountInputs>,
) {
let mut cache = self.foreign_account_inputs.write();
cache.clear();
for account_inputs in foreign_accounts {
cache.insert(account_inputs.id(), account_inputs);
}
}
pub(super) fn insert_foreign_account_inputs(&self, account_inputs: AccountInputs) {
self.foreign_account_inputs.write().insert(account_inputs.id(), account_inputs);
}
pub(super) fn get_foreign_account_inputs(
&self,
account_id: AccountId,
) -> Option<AccountInputs> {
self.foreign_account_inputs.read().get(&account_id).cloned()
}
pub(super) fn with_foreign_account_inputs<R>(
&self,
account_id: AccountId,
f: impl FnOnce(&AccountInputs) -> R,
) -> Option<R> {
self.foreign_account_inputs.read().get(&account_id).map(f)
}
pub(super) fn insert_note_scripts(&self, note_scripts: impl IntoIterator<Item = NoteScript>) {
let mut cache = self.note_scripts.write();
for script in note_scripts {
cache.insert(script.root().into(), script);
}
}
pub(super) fn get_note_script(&self, script_root: Word) -> Option<NoteScript> {
self.note_scripts.read().get(&script_root).cloned()
}
pub(super) fn insert_storage_map_witness(
&self,
map_root: Word,
map_key: StorageMapKey,
witness: StorageMapWitness,
) {
self.storage_map_witnesses.write().insert((map_root, map_key), witness);
}
pub(super) fn get_storage_map_witness(
&self,
map_root: Word,
map_key: StorageMapKey,
) -> Option<StorageMapWitness> {
self.storage_map_witnesses.read().get(&(map_root, map_key)).cloned()
}
pub(super) fn ref_block(&self) -> Option<BlockNumber> {
*self.ref_block.read()
}
pub(super) fn set_ref_block(&self, block_num: BlockNumber) {
*self.ref_block.write() = Some(block_num);
}
}