Skip to content

Commit

Permalink
zebra_script: change to use new zcash_script callback API
Browse files Browse the repository at this point in the history
  • Loading branch information
conradoplg committed May 29, 2024
1 parent af821b6 commit b8bee9b
Show file tree
Hide file tree
Showing 12 changed files with 659 additions and 669 deletions.
803 changes: 351 additions & 452 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion zebra-chain/src/parameters/network_upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ const FAKE_TESTNET_ACTIVATION_HEIGHTS: &[(block::Height, NetworkUpgrade)] = &[
/// The Consensus Branch Id, used to bind transactions and blocks to a
/// particular network upgrade.
#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct ConsensusBranchId(u32);
pub struct ConsensusBranchId(pub(crate) u32);

impl ConsensusBranchId {
/// Return the hash bytes in big-endian byte-order suitable for printing out byte by byte.
Expand Down
9 changes: 7 additions & 2 deletions zebra-chain/src/primitives/zcash_note_encryption.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,13 @@ use crate::{
/// 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_tx = convert_tx_to_librustzcash(
transaction,
network_upgrade
.branch_id()
.expect("should have a branch ID"),
)
.expect("zcash_primitives and Zebra transaction formats must be compatible");

let null_sapling_ovk = sapling::keys::OutgoingViewingKey([0u8; 32]);

Expand Down
32 changes: 18 additions & 14 deletions zebra-chain/src/primitives/zcash_primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use zcash_primitives::transaction as zp_tx;

use crate::{
amount::{Amount, NonNegative},
parameters::{Network, NetworkUpgrade},
parameters::{ConsensusBranchId, Network},
serialization::ZcashSerialize,
transaction::{AuthDigest, HashType, SigHash, Transaction},
transparent::{self, Script},
Expand Down Expand Up @@ -127,6 +127,7 @@ impl zp_tx::components::orchard::MapAuth<orchard::bundle::Authorized, orchard::b
}
}

#[derive(Debug)]
struct PrecomputedAuth<'a> {
_phantom: std::marker::PhantomData<&'a ()>,
}
Expand Down Expand Up @@ -159,19 +160,19 @@ impl TryFrom<&Transaction> for zp_tx::Transaction {
| Transaction::V4 { .. } => panic!("Zebra only uses librustzcash for V5 transactions"),
};

convert_tx_to_librustzcash(trans, *network_upgrade)
convert_tx_to_librustzcash(
trans,
network_upgrade.branch_id().expect("V5 txs have branch IDs"),
)
}
}

pub(crate) fn convert_tx_to_librustzcash(
trans: &Transaction,
network_upgrade: NetworkUpgrade,
branch_id: ConsensusBranchId,
) -> Result<zp_tx::Transaction, io::Error> {
let serialized_tx = trans.zcash_serialize_to_vec()?;
let branch_id: u32 = network_upgrade
.branch_id()
.expect("Network upgrade must have a Branch ID")
.into();
let branch_id: u32 = branch_id.into();
// We've already parsed this transaction, so its network upgrade must be valid.
let branch_id: zcash_primitives::consensus::BranchId = branch_id
.try_into()
Expand Down Expand Up @@ -244,23 +245,26 @@ impl From<Script> for zcash_primitives::legacy::Script {
pub(crate) fn sighash(
trans: &Transaction,
hash_type: HashType,
network_upgrade: NetworkUpgrade,
branch_id: ConsensusBranchId,
all_previous_outputs: &[transparent::Output],
input_index: Option<usize>,
script_code: Option<Vec<u8>>,
) -> SigHash {
let alt_tx = convert_tx_to_librustzcash(trans, network_upgrade)
let alt_tx = convert_tx_to_librustzcash(trans, branch_id)
.expect("zcash_primitives and Zebra transaction formats must be compatible");

let script: zcash_primitives::legacy::Script;
let lock_script: zcash_primitives::legacy::Script;
let unlock_script: zcash_primitives::legacy::Script;
let signable_input = match input_index {
Some(input_index) => {
let output = all_previous_outputs[input_index].clone();
script = output.lock_script.into();
let output = &all_previous_outputs[input_index];
lock_script = output.lock_script.clone().into();
unlock_script = zcash_primitives::legacy::Script(script_code.unwrap());
zp_tx::sighash::SignableInput::Transparent {
hash_type: hash_type.bits() as _,
index: input_index,
script_code: &script,
script_pubkey: &script,
script_code: &unlock_script,
script_pubkey: &lock_script,
value: output
.value
.try_into()
Expand Down
32 changes: 28 additions & 4 deletions zebra-chain/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@ pub use unmined::{
use crate::{
amount::{Amount, Error as AmountError, NegativeAllowed, NonNegative},
block, orchard,
parameters::NetworkUpgrade,
parameters::{ConsensusBranchId, NetworkUpgrade},
primitives::{ed25519, Bctv14Proof, Groth16Proof},
sapling, sprout,
sapling,
serialization::ZcashSerialize,
sprout,
transparent::{
self, outputs_from_utxos,
CoinbaseSpendRestriction::{self, *},
Expand Down Expand Up @@ -209,17 +211,19 @@ impl Transaction {
/// - if the input index is out of bounds for self.inputs()
pub fn sighash(
&self,
network_upgrade: NetworkUpgrade,
branch_id: ConsensusBranchId,
hash_type: sighash::HashType,
all_previous_outputs: &[transparent::Output],
input: Option<usize>,
script_code: Option<Vec<u8>>,
) -> SigHash {
sighash::SigHasher::new(
self,
hash_type,
network_upgrade,
branch_id,
all_previous_outputs,
input,
script_code,
)
.sighash()
}
Expand Down Expand Up @@ -371,6 +375,26 @@ impl Transaction {
}
}

/// Get the raw lock time value.
pub fn raw_lock_time(&self) -> u32 {
let lock_time = match self {
Transaction::V1 { lock_time, .. }
| Transaction::V2 { lock_time, .. }
| Transaction::V3 { lock_time, .. }
| Transaction::V4 { lock_time, .. }
| Transaction::V5 { lock_time, .. } => *lock_time,
};
let mut lock_time_bytes = Vec::new();
lock_time
.zcash_serialize(&mut lock_time_bytes)
.expect("lock_time should serialize");
u32::from_le_bytes(
lock_time_bytes
.try_into()
.expect("should serialize as 4 bytes"),
)
}

/// Returns `true` if this transaction's `lock_time` is a [`LockTime::Time`].
/// Returns `false` if it is a [`LockTime::Height`] (locked or unlocked), is unlocked,
/// or if the transparent input sequence numbers have disabled lock times.
Expand Down
26 changes: 11 additions & 15 deletions zebra-chain/src/transaction/sighash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@

use super::Transaction;

use crate::{parameters::NetworkUpgrade, transparent};
use crate::parameters::ConsensusBranchId;
use crate::transparent;

use crate::primitives::zcash_primitives::sighash;

static ZIP143_EXPLANATION: &str = "Invalid transaction version: after Overwinter activation transaction versions 1 and 2 are rejected";

bitflags::bitflags! {
/// The different SigHash types, as defined in <https://zips.z.cash/zip-0143>
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
Expand Down Expand Up @@ -43,47 +42,44 @@ impl AsRef<[u8]> for SigHash {
pub(super) struct SigHasher<'a> {
trans: &'a Transaction,
hash_type: HashType,
network_upgrade: NetworkUpgrade,
branch_id: ConsensusBranchId,
all_previous_outputs: &'a [transparent::Output],
input_index: Option<usize>,
script_code: Option<Vec<u8>>,
}

impl<'a> SigHasher<'a> {
pub fn new(
trans: &'a Transaction,
hash_type: HashType,
network_upgrade: NetworkUpgrade,
branch_id: ConsensusBranchId,
all_previous_outputs: &'a [transparent::Output],
input_index: Option<usize>,
script_code: Option<Vec<u8>>,
) -> Self {
SigHasher {
trans,
hash_type,
network_upgrade,
branch_id,
all_previous_outputs,
input_index,
script_code,
}
}

pub(super) fn sighash(self) -> SigHash {
use NetworkUpgrade::*;

match self.network_upgrade {
Genesis | BeforeOverwinter => unreachable!("{}", ZIP143_EXPLANATION),
Overwinter | Sapling | Blossom | Heartwood | Canopy | Nu5 => {
self.hash_sighash_librustzcash()
}
}
self.hash_sighash_librustzcash()
}

/// Compute a signature hash using librustzcash.
fn hash_sighash_librustzcash(&self) -> SigHash {
sighash(
self.trans,
self.hash_type,
self.network_upgrade,
self.branch_id,
self.all_previous_outputs,
self.input_index,
self.script_code.clone(),
)
}
}
Loading

0 comments on commit b8bee9b

Please sign in to comment.