From 383f83e5d9fce61ba924a5d443799e7c134dcfdf Mon Sep 17 00:00:00 2001 From: teor Date: Thu, 7 Jul 2022 00:11:09 +1000 Subject: [PATCH] fix(verify): Only verify halo2 proofs once per transaction (#4752) * Only verify halo2 proofs once per transaction (rather than once per action) * Update comments on how there is one aggregate Halo2 proof instead of one per Action Co-authored-by: Marek * cargo +stable fmt --all Co-authored-by: Deirdre Connolly Co-authored-by: Marek --- zebra-consensus/src/transaction.rs | 34 +++++++++++++++--------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/zebra-consensus/src/transaction.rs b/zebra-consensus/src/transaction.rs index c13b9e665..c9bf3030e 100644 --- a/zebra-consensus/src/transaction.rs +++ b/zebra-consensus/src/transaction.rs @@ -909,26 +909,26 @@ where let mut async_checks = AsyncChecks::new(); if let Some(orchard_shielded_data) = orchard_shielded_data { + // # Consensus + // + // > The proof 𝜋 MUST be valid given a primary input (cv, rt^{Orchard}, + // > nf, rk, cm_x, enableSpends, enableOutputs) + // + // https://zips.z.cash/protocol/protocol.pdf#actiondesc + // + // Unlike Sapling, Orchard shielded transactions have a single + // aggregated Halo2 proof per transaction, even with multiple + // Actions in one transaction. So we queue it for verification + // only once instead of queuing it up for every Action description. + async_checks.push( + primitives::halo2::VERIFIER + .clone() + .oneshot(primitives::halo2::Item::from(orchard_shielded_data)), + ); + for authorized_action in orchard_shielded_data.actions.iter().cloned() { let (action, spend_auth_sig) = authorized_action.into_parts(); - // # Consensus - // - // > The proof 𝜋 MUST be valid given a primary input (cv, rt^{Orchard}, - // > nf, rk, cm_x, enableSpends, enableOutputs) - // - // https://zips.z.cash/protocol/protocol.pdf#actiondesc - // - // Queue the verification of the Halo2 proof for each Action - // description while adding the resulting future to our - // collection of async checks that (at a minimum) must pass for - // the transaction to verify. - async_checks.push( - primitives::halo2::VERIFIER - .clone() - .oneshot(primitives::halo2::Item::from(orchard_shielded_data)), - ); - // # Consensus // // > - Let SigHash be the SIGHASH transaction hash of this transaction, not