use miden_protocol::CoreLibrary;
use miden_protocol::transaction::{ProvenTransaction, TransactionKernel};
use miden_protocol::vm::ProgramInfo;
use miden_verifier::verify_with_precompiles;
use super::TransactionVerifierError;
pub struct TransactionVerifier {
tx_program_info: ProgramInfo,
proof_security_level: u32,
}
impl TransactionVerifier {
pub fn new(proof_security_level: u32) -> Self {
let tx_program_info = TransactionKernel::program_info();
Self { tx_program_info, proof_security_level }
}
pub fn verify(&self, transaction: &ProvenTransaction) -> Result<(), TransactionVerifierError> {
let stack_inputs = TransactionKernel::build_input_stack(
transaction.account_id(),
transaction.account_update().initial_state_commitment(),
transaction.input_notes().commitment(),
transaction.ref_block_commitment(),
transaction.ref_block_num(),
);
let stack_outputs = TransactionKernel::build_output_stack(
transaction.account_update().final_state_commitment(),
transaction.account_update().account_delta_commitment(),
transaction.output_notes().commitment(),
transaction.fee(),
transaction.expiration_block_num(),
);
let precompile_verifiers = CoreLibrary::default().verifier_registry();
let proof_security_level = verify_with_precompiles(
self.tx_program_info.clone(),
stack_inputs,
stack_outputs,
transaction.proof().clone(),
&precompile_verifiers,
)
.map_err(TransactionVerifierError::TransactionVerificationFailed)?
.0;
if proof_security_level < self.proof_security_level {
return Err(TransactionVerifierError::InsufficientProofSecurityLevel {
actual: proof_security_level,
expected_minimum: self.proof_security_level,
});
}
Ok(())
}
}