Skip to main content

miden_protocol/transaction/
verifier.rs

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