bankai_verify/
batch.rs

1extern crate alloc;
2use alloc::vec::Vec;
3
4use bankai_types::fetch::ProofWrapper;
5use bankai_types::proofs::HashingFunctionDto;
6use bankai_types::verify::evm::EvmResults;
7use bankai_types::verify::BatchResults;
8
9use crate::bankai::stwo::verify_stwo_proof;
10use crate::evm::beacon::BeaconVerifier;
11use crate::evm::execution::ExecutionVerifier;
12use crate::VerifyError;
13
14/// Verifies a complete batch of proofs generated by the Bankai SDK
15///
16/// **All data returned by this function is cryptographically guaranteed to be valid.**
17/// Once verification succeeds, no further validation is required. This guarantee is
18/// provided by Bankai's stateless light client architecture using STWO zero-knowledge proofs.
19///
20/// This is the main entry point for verifying proof bundles. It performs a complete
21/// verification of all proofs in the batch using a hierarchical approach:
22///
23/// 1. **STWO Proof Verification**: Verifies the zero-knowledge proof to establish trust
24///    in the MMR roots for execution and beacon chains
25/// 2. **Header Verification**: Verifies all execution and beacon headers using MMR inclusion
26///    proofs against the trusted roots
27/// 3. **Account Verification**: Verifies account proofs using Merkle Patricia Trie proofs
28///    against verified execution headers
29/// 4. **Transaction Verification**: Verifies transaction proofs using MPT proofs against
30///    verified execution headers
31///
32/// # Arguments
33///
34/// * `wrapper` - A `ProofWrapper` containing the STWO block proof and all individual proofs
35///   to verify. This is typically generated by the `bankai-sdk` crate.
36///
37/// # Returns
38///
39/// Returns `BatchResults` containing all verified data:
40/// - Verified execution headers with their block numbers and roots
41/// - Verified beacon headers with their slot numbers
42/// - Verified accounts with balances, nonces, and code hashes
43/// - Verified transactions with their details
44///
45/// # Errors
46///
47/// Returns a `VerifyError` if any verification step fails:
48/// - `InvalidStwoProof`: The STWO zero-knowledge proof is invalid
49/// - `InvalidMmrProof`: An MMR inclusion proof failed
50/// - `InvalidMmrRoot`: MMR root mismatch
51/// - `InvalidHeaderHash`: Header hash doesn't match committed value
52/// - `InvalidAccountProof`: Account MPT proof failed
53/// - `InvalidTxProof`: Transaction MPT proof failed
54/// - `InvalidStateRoot`: State root mismatch
55/// - `InvalidExecutionHeaderProof`: Referenced header not found
56///
57/// # Example
58///
59/// ```no_run
60/// use bankai_verify::verify_batch_proof;
61/// use bankai_types::fetch::ProofWrapper;
62///
63/// # fn example(proof_wrapper: ProofWrapper) -> Result<(), Box<dyn std::error::Error>> {
64/// let results = verify_batch_proof(&proof_wrapper)?;
65///
66/// // Access verified execution headers
67/// println!("Verified {} execution headers", results.evm.execution_header.len());
68/// for header in &results.evm.execution_header {
69///     println!("Block {}: hash {:?}", header.number, header.hash());
70/// }
71///
72/// // Access verified accounts
73/// println!("Verified {} accounts", results.evm.account.len());
74/// for account in &results.evm.account {
75///     println!("Balance: {}", account.balance);
76/// }
77///
78/// // Access verified transactions
79/// println!("Verified {} transactions", results.evm.tx.len());
80/// # Ok(())
81/// # }
82/// ```
83pub fn verify_batch_proof(wrapper: ProofWrapper) -> Result<BatchResults, VerifyError> {
84    let bankai_block = verify_stwo_proof(wrapper.block_proof)?;
85
86    let exec_root = match wrapper.hashing_function {
87        HashingFunctionDto::Keccak => bankai_block.execution.mmr_root_keccak,
88        HashingFunctionDto::Poseidon => bankai_block.execution.mmr_root_poseidon,
89    };
90    let beacon_root = match wrapper.hashing_function {
91        HashingFunctionDto::Keccak => bankai_block.beacon.mmr_root_keccak,
92        HashingFunctionDto::Poseidon => bankai_block.beacon.mmr_root_poseidon,
93    };
94
95    let mut batch_results = BatchResults {
96        evm: EvmResults {
97            execution_header: Vec::new(),
98            beacon_header: Vec::new(),
99            account: Vec::new(),
100            tx: Vec::new(),
101            storage_slot: Vec::new(),
102        },
103    };
104
105    if let Some(evm) = &wrapper.evm_proofs {
106        if let Some(exec_headers) = &evm.execution_header_proof {
107            for proof in exec_headers {
108                let result = ExecutionVerifier::verify_header_proof(proof, exec_root)?;
109                batch_results.evm.execution_header.push(result);
110            }
111        }
112
113        if let Some(beacon_headers) = &evm.beacon_header_proof {
114            for proof in beacon_headers {
115                let result = BeaconVerifier::verify_header_proof(proof, beacon_root)?;
116                batch_results.evm.beacon_header.push(result);
117            }
118        }
119
120        if let Some(accounts) = &evm.account_proof {
121            for account in accounts {
122                let result = ExecutionVerifier::verify_account_proof(
123                    account,
124                    &batch_results.evm.execution_header,
125                )?;
126                batch_results.evm.account.push(result);
127            }
128        }
129
130        if let Some(storage_slots) = &evm.storage_slot_proof {
131            for proof in storage_slots {
132                let result = ExecutionVerifier::verify_storage_slot_proof(
133                    proof,
134                    &batch_results.evm.execution_header,
135                )?;
136                batch_results.evm.storage_slot.push(result);
137            }
138        }
139
140        if let Some(tx_proofs) = &evm.tx_proof {
141            for proof in tx_proofs {
142                let result =
143                    ExecutionVerifier::verify_tx_proof(proof, &batch_results.evm.execution_header)?;
144                batch_results.evm.tx.push(result);
145            }
146        }
147    }
148
149    Ok(batch_results)
150}