miden_tx/verifier/
mod.rs

1use miden_protocol::CoreLibrary;
2use miden_protocol::transaction::{ProvenTransaction, TransactionKernel};
3use miden_protocol::vm::ProgramInfo;
4use miden_verifier::verify_with_precompiles;
5
6use super::TransactionVerifierError;
7
8// TRANSACTION VERIFIER
9// ================================================================================================
10
11/// The [TransactionVerifier] is used to verify  [ProvenTransaction]s.
12///
13/// The [TransactionVerifier] contains a [ProgramInfo] object which is associated with the
14/// transaction kernel program.  The `proof_security_level` specifies the minimum security
15/// level that the transaction proof must have in order to be considered valid.
16pub struct TransactionVerifier {
17    tx_program_info: ProgramInfo,
18    proof_security_level: u32,
19}
20
21impl TransactionVerifier {
22    /// Returns a new [TransactionVerifier] instantiated with the specified security level.
23    pub fn new(proof_security_level: u32) -> Self {
24        let tx_program_info = TransactionKernel::program_info();
25        Self { tx_program_info, proof_security_level }
26    }
27
28    /// Verifies the provided [`ProvenTransaction`] against the transaction kernel.
29    ///
30    /// # Errors
31    /// Returns an error if:
32    /// - Transaction verification fails.
33    /// - The security level of the verified proof is insufficient.
34    pub fn verify(&self, transaction: &ProvenTransaction) -> Result<(), TransactionVerifierError> {
35        // build stack inputs and outputs
36        let stack_inputs = TransactionKernel::build_input_stack(
37            transaction.account_id(),
38            transaction.account_update().initial_state_commitment(),
39            transaction.input_notes().commitment(),
40            transaction.ref_block_commitment(),
41            transaction.ref_block_num(),
42        );
43        let stack_outputs = TransactionKernel::build_output_stack(
44            transaction.account_update().final_state_commitment(),
45            transaction.account_update().account_delta_commitment(),
46            transaction.output_notes().commitment(),
47            transaction.fee(),
48            transaction.expiration_block_num(),
49        );
50
51        // verify transaction proof
52        let precompile_verifiers = CoreLibrary::default().verifier_registry();
53        let proof_security_level = verify_with_precompiles(
54            self.tx_program_info.clone(),
55            stack_inputs,
56            stack_outputs,
57            transaction.proof().clone(),
58            &precompile_verifiers,
59        )
60        .map_err(TransactionVerifierError::TransactionVerificationFailed)?
61        .0;
62
63        // check security level
64        if proof_security_level < self.proof_security_level {
65            return Err(TransactionVerifierError::InsufficientProofSecurityLevel {
66                actual: proof_security_level,
67                expected_minimum: self.proof_security_level,
68            });
69        }
70
71        Ok(())
72    }
73}