use std::collections::HashSet;
use std::ops::ControlFlow;
use miden_node_tracing::miden_instrument;
use miden_protocol::Word;
use miden_protocol::account::AccountId;
use miden_protocol::note::{NoteId, Nullifier};
use super::StateView;
use crate::COMPONENT;
use crate::db::NullifierInfo;
use crate::errors::DatabaseError;
#[derive(Debug, Default)]
pub struct TransactionInputs {
pub account_commitment: Word,
pub nullifiers: Vec<NullifierInfo>,
pub found_unauthenticated_notes: HashSet<NoteId>,
pub new_account_id_prefix_is_unique: Option<bool>,
}
impl StateView {
#[miden_instrument(
target = COMPONENT,
fields(
account.id = account_id,
note.nullifiers = nullifiers,
),
)]
pub async fn get_transaction_inputs(
&self,
account_id: AccountId,
nullifiers: &[Nullifier],
unauthenticated_note_ids: Vec<NoteId>,
) -> Result<TransactionInputs, DatabaseError> {
let tree_inputs = self.with_inner_read_blocking(|inner| {
let account_commitment = inner.account_tree.get_latest_commitment(account_id);
let new_account_id_prefix_is_unique = if account_commitment.is_empty() {
Some(!inner.account_tree.contains_account_id_prefix_in_latest(account_id.prefix()))
} else {
None
};
if let Some(false) = new_account_id_prefix_is_unique {
return ControlFlow::Break(TransactionInputs {
new_account_id_prefix_is_unique,
..Default::default()
});
}
let nullifiers = nullifiers
.iter()
.map(|nullifier| NullifierInfo {
nullifier: *nullifier,
block_num: inner.nullifier_tree.get_block_num(nullifier).unwrap_or_default(),
})
.collect();
ControlFlow::Continue((account_commitment, nullifiers, new_account_id_prefix_is_unique))
});
let (account_commitment, nullifiers, new_account_id_prefix_is_unique) = match tree_inputs {
ControlFlow::Continue(inputs) => inputs,
ControlFlow::Break(response) => return Ok(response),
};
let found_unauthenticated_notes =
self.db.select_existing_note_ids(unauthenticated_note_ids, self.tip()).await?;
Ok(TransactionInputs {
account_commitment,
nullifiers,
found_unauthenticated_notes,
new_account_id_prefix_is_unique,
})
}
}