Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse ConsensusBranchId into NetworkUpgrade for transaction v5 #2075

Merged
merged 13 commits into from
Apr 29, 2021
8 changes: 7 additions & 1 deletion zebra-chain/src/parameters/network_upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ pub(crate) const 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, Eq, Hash, PartialEq)]
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
oxarbitrage marked this conversation as resolved.
Show resolved Hide resolved
pub struct ConsensusBranchId(u32);

impl From<ConsensusBranchId> for u32 {
Expand All @@ -85,6 +85,12 @@ impl From<ConsensusBranchId> for u32 {
}
}

impl From<u32> for ConsensusBranchId {
fn from(branch_id: u32) -> ConsensusBranchId {
ConsensusBranchId(branch_id)
}
}

/// Network Upgrade Consensus Branch Ids.
///
/// Branch ids are the same for mainnet and testnet. If there is a testnet
Expand Down
4 changes: 3 additions & 1 deletion zebra-chain/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub use sighash::HashType;

use crate::{
block,
parameters::NetworkUpgrade,
parameters::{ConsensusBranchId, NetworkUpgrade},
primitives::{Bctv14Proof, Groth16Proof},
sapling, sprout, transparent,
};
Expand Down Expand Up @@ -97,6 +97,8 @@ pub enum Transaction {
},
/// A `version = 5` transaction, which supports `Sapling` and `Orchard`.
V5 {
/// The Consensus branch ID for this transaction.
oxarbitrage marked this conversation as resolved.
Show resolved Hide resolved
consensus_branch_id: ConsensusBranchId,
oxarbitrage marked this conversation as resolved.
Show resolved Hide resolved
/// The earliest time or block height that this transaction can be added to the
/// chain.
lock_time: LockTime,
Expand Down
23 changes: 21 additions & 2 deletions zebra-chain/src/transaction/arbitrary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use proptest::{arbitrary::any, array, collection::vec, option, prelude::*};
use crate::{
amount::Amount,
block,
parameters::NetworkUpgrade,
parameters::{ConsensusBranchId, NetworkUpgrade},
primitives::{Bctv14Proof, Groth16Proof, ZkSnarkProof},
sapling, sprout, transparent, LedgerState,
};
Expand Down Expand Up @@ -103,15 +103,24 @@ impl Transaction {
/// Generate a proptest strategy for V5 Transactions
pub fn v5_strategy(ledger_state: LedgerState) -> BoxedStrategy<Self> {
(
any::<ConsensusBranchId>(),
any::<LockTime>(),
any::<block::Height>(),
transparent::Input::vec_strategy(ledger_state, 10),
vec(any::<transparent::Output>(), 0..10),
option::of(any::<sapling::ShieldedData<sapling::SharedAnchor>>()),
)
.prop_map(
|(lock_time, expiry_height, inputs, outputs, sapling_shielded_data)| {
|(
consensus_branch_id,
lock_time,
expiry_height,
inputs,
outputs,
sapling_shielded_data,
)| {
Transaction::V5 {
consensus_branch_id,
lock_time,
expiry_height,
inputs,
Expand Down Expand Up @@ -177,6 +186,16 @@ impl Arbitrary for LockTime {
type Strategy = BoxedStrategy<Self>;
}

impl Arbitrary for ConsensusBranchId {
oxarbitrage marked this conversation as resolved.
Show resolved Hide resolved
type Parameters = ();

fn arbitrary_with(_args: ()) -> Self::Strategy {
(any::<u32>()).prop_map(ConsensusBranchId::from).boxed()
}

type Strategy = BoxedStrategy<Self>;
}

impl<P: ZkSnarkProof + Arbitrary + 'static> Arbitrary for JoinSplitData<P> {
type Parameters = ();

Expand Down
7 changes: 7 additions & 0 deletions zebra-chain/src/transaction/serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ impl ZcashSerialize for Transaction {
}

Transaction::V5 {
consensus_branch_id,
lock_time,
expiry_height,
inputs,
Expand All @@ -356,6 +357,9 @@ impl ZcashSerialize for Transaction {
writer.write_u32::<LittleEndian>(5 | (1 << 31))?;
writer.write_u32::<LittleEndian>(TX_V5_VERSION_GROUP_ID)?;

// header: Write the nConsensusBranchId
writer.write_u32::<LittleEndian>(u32::from(*consensus_branch_id))?;
oxarbitrage marked this conversation as resolved.
Show resolved Hide resolved

// transaction validity time and height limits
lock_time.zcash_serialize(&mut writer)?;
writer.write_u32::<LittleEndian>(expiry_height.0)?;
Expand Down Expand Up @@ -491,6 +495,8 @@ impl ZcashDeserialize for Transaction {
if id != TX_V5_VERSION_GROUP_ID {
return Err(SerializationError::Parse("expected TX_V5_VERSION_GROUP_ID"));
}
let consensus_branch_id =
ConsensusBranchId::from(reader.read_u32::<LittleEndian>()?);
oxarbitrage marked this conversation as resolved.
Show resolved Hide resolved

// transaction validity time and height limits
let lock_time = LockTime::zcash_deserialize(&mut reader)?;
Expand All @@ -514,6 +520,7 @@ impl ZcashDeserialize for Transaction {
}

Ok(Transaction::V5 {
consensus_branch_id,
lock_time,
expiry_height,
inputs,
Expand Down
6 changes: 6 additions & 0 deletions zebra-chain/src/transaction/tests/vectors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use super::super::*;

use crate::{
block::{Block, MAX_BLOCK_BYTES},
parameters::NetworkUpgrade::Nu5,
sapling::{PerSpendAnchor, SharedAnchor},
serialization::{ZcashDeserialize, ZcashDeserializeInto, ZcashSerialize},
};
Expand Down Expand Up @@ -105,6 +106,7 @@ fn empty_v5_round_trip() {
zebra_test::init();

let tx = Transaction::V5 {
consensus_branch_id: Nu5.branch_id().expect("nu5 has a branch id"),
oxarbitrage marked this conversation as resolved.
Show resolved Hide resolved
lock_time: LockTime::min_lock_time(),
expiry_height: block::Height(0),
inputs: Vec::new(),
Expand Down Expand Up @@ -278,6 +280,7 @@ fn transaction_to_fake_v5(trans: &Transaction) -> Transaction {
outputs,
lock_time,
} => V5 {
consensus_branch_id: Nu5.branch_id().expect("nu5 has a branch id"),
inputs: inputs.to_vec(),
outputs: outputs.to_vec(),
lock_time: *lock_time,
Expand All @@ -290,6 +293,7 @@ fn transaction_to_fake_v5(trans: &Transaction) -> Transaction {
lock_time,
..
} => V5 {
consensus_branch_id: Nu5.branch_id().expect("nu5 has a branch id"),
inputs: inputs.to_vec(),
outputs: outputs.to_vec(),
lock_time: *lock_time,
Expand All @@ -303,6 +307,7 @@ fn transaction_to_fake_v5(trans: &Transaction) -> Transaction {
expiry_height,
..
} => V5 {
consensus_branch_id: Nu5.branch_id().expect("nu5 has a branch id"),
inputs: inputs.to_vec(),
outputs: outputs.to_vec(),
lock_time: *lock_time,
Expand All @@ -317,6 +322,7 @@ fn transaction_to_fake_v5(trans: &Transaction) -> Transaction {
sapling_shielded_data,
..
} => V5 {
consensus_branch_id: Nu5.branch_id().expect("nu5 has a branch id"),
inputs: inputs.to_vec(),
outputs: outputs.to_vec(),
lock_time: *lock_time,
Expand Down