use alloc::collections::BTreeMap;
use alloc::vec::Vec;
use miden_protocol::Word;
use miden_protocol::account::{AccountVaultDelta, AccountVaultPatch, AssetDelta};
use miden_protocol::asset::AssetId;
use crate::TransactionKernelError;
use crate::host::tx_event::AssetPatch;
#[derive(Debug, Clone, Default)]
pub(crate) struct VaultUpdateTracker {
asset_deltas: Vec<AssetDelta>,
entries: BTreeMap<AssetId, (Word, Word)>,
}
impl VaultUpdateTracker {
pub fn update_patch(&mut self, patch: AssetPatch) -> Result<(), TransactionKernelError> {
self.entries
.entry(patch.asset_id)
.and_modify(|(_, r#final)| *r#final = patch.final_vault_value)
.or_insert((patch.initial_vault_value, patch.final_vault_value));
Ok(())
}
pub fn add_delta(&mut self, delta: AssetDelta) {
self.asset_deltas.push(delta);
}
pub fn reset_delta(&mut self) {
self.asset_deltas.clear();
}
pub fn into_delta(self) -> AccountVaultDelta {
AccountVaultDelta::new(self.asset_deltas)
.expect("tx kernel should emit a valid vault delta")
}
pub fn into_patch(self) -> AccountVaultPatch {
let normalized = self
.entries
.into_iter()
.filter_map(|(key, (initial_value, final_value))| {
if final_value == initial_value {
None
} else {
Some((key, final_value))
}
})
.collect();
AccountVaultPatch::new(normalized)
.expect("vault update events should only be tracked for valid assets")
}
}