use miden_protocol::account::AccountCode;
use super::{BTreeMap, Word};
use crate::errors::TransactionKernelError;
#[derive(Debug, Clone, Default)]
pub struct AccountProcedureIndexMap(BTreeMap<Word, BTreeMap<Word, u8>>);
impl AccountProcedureIndexMap {
pub fn new<'code>(account_codes: impl IntoIterator<Item = &'code AccountCode>) -> Self {
let mut index_map = Self::default();
for account_code in account_codes {
if !index_map.0.contains_key(&account_code.commitment()) {
index_map.insert_code(account_code);
}
}
index_map
}
pub fn insert_code(&mut self, code: &AccountCode) {
let mut procedure_map = BTreeMap::new();
for (proc_idx, proc_root) in code.procedures().iter().enumerate() {
let proc_idx =
u8::try_from(proc_idx).expect("account code should contain at most 256 procedures");
procedure_map.insert(*proc_root.mast_root(), proc_idx);
}
self.0.insert(code.commitment(), procedure_map);
}
pub fn get_proc_index(
&self,
code_commitment: Word,
procedure_root: Word,
) -> Result<u8, TransactionKernelError> {
self.0
.get(&code_commitment)
.ok_or(TransactionKernelError::UnknownCodeCommitment(code_commitment))?
.get(&procedure_root)
.cloned()
.ok_or(TransactionKernelError::UnknownAccountProcedure(procedure_root))
}
}