use alloc::collections::BTreeMap;
use alloc::string::{String, ToString};
use alloc::vec::Vec;
use miden_core::{Felt, Word};
use miden_crypto::EMPTY_WORD;
use crate::AccountDeltaError;
use crate::account::{
AccountStorage,
AccountStorageDelta,
StorageMap,
StorageMapDelta,
StorageSlot,
};
use crate::note::NoteAssets;
#[derive(Clone, Debug, Default)]
pub struct AccountStorageDeltaBuilder {
values: BTreeMap<u8, Word>,
maps: BTreeMap<u8, StorageMapDelta>,
}
impl AccountStorageDeltaBuilder {
pub fn new() -> Self {
Self {
values: BTreeMap::new(),
maps: BTreeMap::new(),
}
}
pub fn add_cleared_items(mut self, items: impl IntoIterator<Item = u8>) -> Self {
self.values.extend(items.into_iter().map(|slot| (slot, EMPTY_WORD)));
self
}
pub fn add_updated_values(mut self, items: impl IntoIterator<Item = (u8, Word)>) -> Self {
self.values.extend(items);
self
}
pub fn add_updated_maps(
mut self,
items: impl IntoIterator<Item = (u8, StorageMapDelta)>,
) -> Self {
self.maps.extend(items);
self
}
pub fn build(self) -> Result<AccountStorageDelta, AccountDeltaError> {
AccountStorageDelta::from_parts(self.values, self.maps)
}
}
pub struct SlotWithIndex {
pub slot: StorageSlot,
pub index: u8,
}
pub const FAUCET_STORAGE_DATA_SLOT: u8 = 0;
pub const STORAGE_INDEX_0: u8 = 0;
pub const STORAGE_INDEX_1: u8 = 1;
pub const STORAGE_INDEX_2: u8 = 2;
pub const STORAGE_VALUE_0: Word =
Word::new([Felt::new(1), Felt::new(2), Felt::new(3), Felt::new(4)]);
pub const STORAGE_VALUE_1: Word =
Word::new([Felt::new(5), Felt::new(6), Felt::new(7), Felt::new(8)]);
pub const STORAGE_LEAVES_2: [(Word, Word); 2] = [
(
Word::new([Felt::new(101), Felt::new(102), Felt::new(103), Felt::new(104)]),
Word::new([Felt::new(1_u64), Felt::new(2_u64), Felt::new(3_u64), Felt::new(4_u64)]),
),
(
Word::new([Felt::new(105), Felt::new(106), Felt::new(107), Felt::new(108)]),
Word::new([Felt::new(5_u64), Felt::new(6_u64), Felt::new(7_u64), Felt::new(8_u64)]),
),
];
impl AccountStorage {
pub fn mock() -> Self {
AccountStorage::new(Self::mock_storage_slots()).unwrap()
}
pub fn mock_storage_slots() -> Vec<StorageSlot> {
vec![Self::mock_item_0().slot, Self::mock_item_1().slot, Self::mock_item_2().slot]
}
pub fn mock_item_0() -> SlotWithIndex {
SlotWithIndex {
slot: StorageSlot::Value(STORAGE_VALUE_0),
index: STORAGE_INDEX_0,
}
}
pub fn mock_item_1() -> SlotWithIndex {
SlotWithIndex {
slot: StorageSlot::Value(STORAGE_VALUE_1),
index: STORAGE_INDEX_1,
}
}
pub fn mock_item_2() -> SlotWithIndex {
SlotWithIndex {
slot: StorageSlot::Map(Self::mock_map()),
index: STORAGE_INDEX_2,
}
}
pub fn mock_map() -> StorageMap {
StorageMap::with_entries(STORAGE_LEAVES_2).unwrap()
}
}
pub fn prepare_assets(note_assets: &NoteAssets) -> Vec<String> {
let mut assets = Vec::new();
for &asset in note_assets.iter() {
let asset_word = Word::from(asset);
assets.push(asset_word.to_string());
}
assets
}