2021-11-11 14:18:37 -08:00
|
|
|
//! Contains code that interfaces with the zcash_note_encryption crate from
|
|
|
|
//! librustzcash.
|
2023-02-06 07:23:13 -08:00
|
|
|
|
2021-11-11 14:18:37 -08:00
|
|
|
use crate::{
|
|
|
|
block::Height,
|
|
|
|
parameters::{Network, NetworkUpgrade},
|
|
|
|
primitives::zcash_primitives::convert_tx_to_librustzcash,
|
|
|
|
transaction::Transaction,
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Returns true if all Sapling or Orchard outputs, if any, decrypt successfully with
|
|
|
|
/// an all-zeroes outgoing viewing key.
|
|
|
|
///
|
|
|
|
/// # Panics
|
|
|
|
///
|
|
|
|
/// If passed a network/height without matching consensus branch ID (pre-Overwinter),
|
|
|
|
/// since `librustzcash` won't be able to parse it.
|
|
|
|
pub fn decrypts_successfully(transaction: &Transaction, network: Network, height: Height) -> bool {
|
|
|
|
let network_upgrade = NetworkUpgrade::current(network, height);
|
|
|
|
let alt_tx = convert_tx_to_librustzcash(transaction, network_upgrade)
|
|
|
|
.expect("zcash_primitives and Zebra transaction formats must be compatible");
|
|
|
|
|
|
|
|
let alt_height = height.0.into();
|
2022-04-18 17:14:16 -07:00
|
|
|
let null_sapling_ovk = zcash_primitives::keys::OutgoingViewingKey([0u8; 32]);
|
2021-11-11 14:18:37 -08:00
|
|
|
|
|
|
|
if let Some(bundle) = alt_tx.sapling_bundle() {
|
2023-02-06 07:23:13 -08:00
|
|
|
for output in bundle.shielded_outputs().iter() {
|
2024-03-12 14:41:44 -07:00
|
|
|
let recovery = zcash_primitives::sapling::note_encryption::try_sapling_output_recovery(
|
|
|
|
&<zcash_primitives::consensus::Network>::from(network),
|
|
|
|
alt_height,
|
|
|
|
&null_sapling_ovk,
|
|
|
|
output,
|
|
|
|
);
|
2021-11-11 14:18:37 -08:00
|
|
|
if recovery.is_none() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(bundle) = alt_tx.orchard_bundle() {
|
|
|
|
for act in bundle.actions() {
|
|
|
|
if zcash_note_encryption::try_output_recovery_with_ovk(
|
|
|
|
&orchard::note_encryption::OrchardDomain::for_action(act),
|
|
|
|
&orchard::keys::OutgoingViewingKey::from([0u8; 32]),
|
|
|
|
act,
|
|
|
|
act.cv_net(),
|
|
|
|
&act.encrypted_note().out_ciphertext,
|
|
|
|
)
|
|
|
|
.is_none()
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
true
|
|
|
|
}
|