zebra/zebra-chain/src/transaction/tests/vectors.rs

994 lines
31 KiB
Rust
Raw Normal View History

//! Fixed test vectors for transactions.
use chrono::{DateTime, NaiveDateTime, Utc};
use color_eyre::eyre::Result;
use lazy_static::lazy_static;
use crate::{
amount::Amount,
block::{Block, Height, MAX_BLOCK_BYTES},
parameters::{Network, NetworkUpgrade},
Move the check in `transaction::check::sapling_balances_match` to `V4` deserialization (#2234) * Implement `PartialEq<i64>` for `Amount` Allows to compare an `Amount` instance directly to an integer. * Add `SerializationError::BadTransactionBalance` Error variant representing deserialization of a transaction that doesn't conform to the Sapling consensus rule where the balance MUST be zero if there aren't any shielded spends and outputs. * Validate consensus rule when deserializing Return an error if the deserialized V4 transaction has a non-zero value balance but doesn't have any Sapling shielded spends nor outputs. * Add consensus rule link to field documentation Describe how the consensus rule is validated structurally by `ShieldedData`. * Clarify that `value_balance` is zero Make the description more concise and objective. Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Update field documentation Include information about how the consensus rule is guaranteed during serialization. Co-authored-by: teor <teor@riseup.net> * Remove `check::sapling_balances_match` function The check is redundant because the respective consensus rule is validated structurally by `ShieldedData`. * Test deserialization of invalid V4 transaction A transaction with no Sapling shielded spends and no outputs but with a non-zero balance value should fail to deserialize. * Change least-significant byte of the value balance State how the byte index is calculated, and change the least significant-byte to be non-zero. Co-authored-by: teor <teor@riseup.net>
2021-06-03 15:53:00 -07:00
serialization::{SerializationError, ZcashDeserialize, ZcashDeserializeInto, ZcashSerialize},
transaction::{hash::WtxId, sighash::SigHasher, txid::TxIdBuilder, Transaction},
transparent::Script,
};
use zebra_test::{
vectors::{ZIP143_1, ZIP143_2, ZIP243_1, ZIP243_2, ZIP243_3},
zip0143, zip0243, zip0244,
};
use super::super::*;
lazy_static! {
pub static ref EMPTY_V5_TX: Transaction = Transaction::V5 {
network_upgrade: NetworkUpgrade::Nu5,
lock_time: LockTime::min_lock_time_timestamp(),
expiry_height: block::Height(0),
inputs: Vec::new(),
outputs: Vec::new(),
sapling_shielded_data: None,
orchard_shielded_data: None,
};
}
/// Build a mock output list for pre-V5 transactions, with (index+1)
/// copies of `output`, which is used to computed the sighash.
///
/// Pre-V5, the entire output list is not used; only the output for the
/// given index is read. Therefore, we just need a list where `array[index]`
/// is the given `output`.
fn mock_pre_v5_output_list(output: transparent::Output, index: usize) -> Vec<transparent::Output> {
iter::repeat(output).take(index + 1).collect()
}
#[test]
fn transactionhash_struct_from_str_roundtrip() {
let _init_guard = zebra_test::init();
let hash: Hash = "3166411bd5343e0b284a108f39a929fbbb62619784f8c6dafe520703b5b446bf"
.parse()
.unwrap();
assert_eq!(
format!("{hash:?}"),
r#"transaction::Hash("3166411bd5343e0b284a108f39a929fbbb62619784f8c6dafe520703b5b446bf")"#
);
assert_eq!(
hash.to_string(),
"3166411bd5343e0b284a108f39a929fbbb62619784f8c6dafe520703b5b446bf"
);
}
#[test]
fn auth_digest_struct_from_str_roundtrip() {
let _init_guard = zebra_test::init();
let digest: AuthDigest = "3166411bd5343e0b284a108f39a929fbbb62619784f8c6dafe520703b5b446bf"
.parse()
.unwrap();
assert_eq!(
format!("{digest:?}"),
r#"AuthDigest("3166411bd5343e0b284a108f39a929fbbb62619784f8c6dafe520703b5b446bf")"#
);
assert_eq!(
digest.to_string(),
"3166411bd5343e0b284a108f39a929fbbb62619784f8c6dafe520703b5b446bf"
);
}
#[test]
fn wtx_id_struct_from_str_roundtrip() {
let _init_guard = zebra_test::init();
let wtx_id: WtxId = "3166411bd5343e0b284a108f39a929fbbb62619784f8c6dafe520703b5b446bf0000000000000000000000000000000000000000000000000000000000000001"
.parse()
.unwrap();
assert_eq!(
format!("{wtx_id:?}"),
r#"WtxId { id: transaction::Hash("3166411bd5343e0b284a108f39a929fbbb62619784f8c6dafe520703b5b446bf"), auth_digest: AuthDigest("0000000000000000000000000000000000000000000000000000000000000001") }"#
);
assert_eq!(
wtx_id.to_string(),
"3166411bd5343e0b284a108f39a929fbbb62619784f8c6dafe520703b5b446bf0000000000000000000000000000000000000000000000000000000000000001"
);
}
#[test]
fn librustzcash_tx_deserialize_and_round_trip() {
let _init_guard = zebra_test::init();
let tx = Transaction::zcash_deserialize(&zebra_test::vectors::GENERIC_TESTNET_TX[..])
.expect("transaction test vector from librustzcash should deserialize");
let mut data2 = Vec::new();
tx.zcash_serialize(&mut data2).expect("tx should serialize");
assert_eq!(&zebra_test::vectors::GENERIC_TESTNET_TX[..], &data2[..]);
}
2020-09-04 13:37:43 -07:00
#[test]
fn librustzcash_tx_hash() {
let _init_guard = zebra_test::init();
2020-09-04 13:37:43 -07:00
let tx = Transaction::zcash_deserialize(&zebra_test::vectors::GENERIC_TESTNET_TX[..])
.expect("transaction test vector from librustzcash should deserialize");
// TxID taken from comment in zebra_test::vectors
let hash = tx.hash();
let expected = "64f0bd7fe30ce23753358fe3a2dc835b8fba9c0274c4e2c54a6f73114cb55639"
2020-09-04 13:37:43 -07:00
.parse::<Hash>()
.expect("hash should parse correctly");
assert_eq!(hash, expected);
}
Move the check in `transaction::check::sapling_balances_match` to `V4` deserialization (#2234) * Implement `PartialEq<i64>` for `Amount` Allows to compare an `Amount` instance directly to an integer. * Add `SerializationError::BadTransactionBalance` Error variant representing deserialization of a transaction that doesn't conform to the Sapling consensus rule where the balance MUST be zero if there aren't any shielded spends and outputs. * Validate consensus rule when deserializing Return an error if the deserialized V4 transaction has a non-zero value balance but doesn't have any Sapling shielded spends nor outputs. * Add consensus rule link to field documentation Describe how the consensus rule is validated structurally by `ShieldedData`. * Clarify that `value_balance` is zero Make the description more concise and objective. Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Update field documentation Include information about how the consensus rule is guaranteed during serialization. Co-authored-by: teor <teor@riseup.net> * Remove `check::sapling_balances_match` function The check is redundant because the respective consensus rule is validated structurally by `ShieldedData`. * Test deserialization of invalid V4 transaction A transaction with no Sapling shielded spends and no outputs but with a non-zero balance value should fail to deserialize. * Change least-significant byte of the value balance State how the byte index is calculated, and change the least significant-byte to be non-zero. Co-authored-by: teor <teor@riseup.net>
2021-06-03 15:53:00 -07:00
#[test]
fn doesnt_deserialize_transaction_with_invalid_value_balance() {
let _init_guard = zebra_test::init();
Move the check in `transaction::check::sapling_balances_match` to `V4` deserialization (#2234) * Implement `PartialEq<i64>` for `Amount` Allows to compare an `Amount` instance directly to an integer. * Add `SerializationError::BadTransactionBalance` Error variant representing deserialization of a transaction that doesn't conform to the Sapling consensus rule where the balance MUST be zero if there aren't any shielded spends and outputs. * Validate consensus rule when deserializing Return an error if the deserialized V4 transaction has a non-zero value balance but doesn't have any Sapling shielded spends nor outputs. * Add consensus rule link to field documentation Describe how the consensus rule is validated structurally by `ShieldedData`. * Clarify that `value_balance` is zero Make the description more concise and objective. Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> * Update field documentation Include information about how the consensus rule is guaranteed during serialization. Co-authored-by: teor <teor@riseup.net> * Remove `check::sapling_balances_match` function The check is redundant because the respective consensus rule is validated structurally by `ShieldedData`. * Test deserialization of invalid V4 transaction A transaction with no Sapling shielded spends and no outputs but with a non-zero balance value should fail to deserialize. * Change least-significant byte of the value balance State how the byte index is calculated, and change the least significant-byte to be non-zero. Co-authored-by: teor <teor@riseup.net>
2021-06-03 15:53:00 -07:00
let dummy_transaction = Transaction::V4 {
inputs: vec![],
outputs: vec![],
lock_time: LockTime::Height(Height(1)),
expiry_height: Height(10),
joinsplit_data: None,
sapling_shielded_data: None,
};
let mut input_bytes = Vec::new();
dummy_transaction
.zcash_serialize(&mut input_bytes)
.expect("dummy transaction should serialize");
// Set value balance to non-zero
// There are 4 * 4 byte fields and 2 * 1 byte compact sizes = 18 bytes before the 8 byte amount
// (Zcash is little-endian unless otherwise specified:
// https://zips.z.cash/protocol/nu5.pdf#endian)
input_bytes[18] = 1;
let result = Transaction::zcash_deserialize(&input_bytes[..]);
assert!(matches!(
result,
Err(SerializationError::BadTransactionBalance)
));
}
#[test]
fn zip143_deserialize_and_round_trip() {
let _init_guard = zebra_test::init();
let tx1 = Transaction::zcash_deserialize(&zebra_test::vectors::ZIP143_1[..])
.expect("transaction test vector from ZIP143 should deserialize");
let mut data1 = Vec::new();
tx1.zcash_serialize(&mut data1)
.expect("tx should serialize");
assert_eq!(&zebra_test::vectors::ZIP143_1[..], &data1[..]);
let tx2 = Transaction::zcash_deserialize(&zebra_test::vectors::ZIP143_2[..])
.expect("transaction test vector from ZIP143 should deserialize");
let mut data2 = Vec::new();
tx2.zcash_serialize(&mut data2)
.expect("tx should serialize");
assert_eq!(&zebra_test::vectors::ZIP143_2[..], &data2[..]);
}
#[test]
fn zip243_deserialize_and_round_trip() {
let _init_guard = zebra_test::init();
let tx1 = Transaction::zcash_deserialize(&zebra_test::vectors::ZIP243_1[..])
.expect("transaction test vector from ZIP243 should deserialize");
let mut data1 = Vec::new();
tx1.zcash_serialize(&mut data1)
.expect("tx should serialize");
assert_eq!(&zebra_test::vectors::ZIP243_1[..], &data1[..]);
let tx2 = Transaction::zcash_deserialize(&zebra_test::vectors::ZIP243_2[..])
.expect("transaction test vector from ZIP243 should deserialize");
let mut data2 = Vec::new();
tx2.zcash_serialize(&mut data2)
.expect("tx should serialize");
assert_eq!(&zebra_test::vectors::ZIP243_2[..], &data2[..]);
let tx3 = Transaction::zcash_deserialize(&zebra_test::vectors::ZIP243_3[..])
.expect("transaction test vector from ZIP243 should deserialize");
let mut data3 = Vec::new();
tx3.zcash_serialize(&mut data3)
.expect("tx should serialize");
assert_eq!(&zebra_test::vectors::ZIP243_3[..], &data3[..]);
}
#[test]
fn deserialize_large_transaction() {
let _init_guard = zebra_test::init();
// Create a dummy input and output.
let input =
transparent::Input::zcash_deserialize(&zebra_test::vectors::DUMMY_INPUT1[..]).unwrap();
let output =
transparent::Output::zcash_deserialize(&zebra_test::vectors::DUMMY_OUTPUT1[..]).unwrap();
// Create a lock time.
let lock_time = LockTime::Time(DateTime::<Utc>::from_naive_utc_and_offset(
NaiveDateTime::from_timestamp_opt(61, 0)
.expect("in-range number of seconds and valid nanosecond"),
Utc,
));
// Serialize the input so that we can determine its serialized size.
let mut input_data = Vec::new();
input
.zcash_serialize(&mut input_data)
.expect("input should serialize");
// Calculate the number of inputs that fit into the transaction size limit.
let tx_inputs_num = MAX_BLOCK_BYTES as usize / input_data.len();
// Set the precalculated amount of inputs and a single output.
let inputs = std::iter::repeat(input)
.take(tx_inputs_num)
.collect::<Vec<_>>();
let outputs = vec![output];
// Create an oversized transaction. Adding the output and lock time causes
// the transaction to overflow the threshold.
let oversized_tx = Transaction::V1 {
inputs,
outputs,
lock_time,
};
// Serialize the transaction.
let mut tx_data = Vec::new();
oversized_tx
.zcash_serialize(&mut tx_data)
.expect("transaction should serialize");
// Check that the transaction is oversized.
assert!(tx_data.len() > MAX_BLOCK_BYTES as usize);
// The deserialization should fail because the transaction is too big.
Transaction::zcash_deserialize(&tx_data[..])
.expect_err("transaction should not deserialize due to its size");
}
// Transaction V5 test vectors
/// An empty transaction v5, with no Orchard, Sapling, or Transparent data
///
/// empty transaction are invalid, but Zebra only checks this rule in
/// zebra_consensus::transaction::Verifier
#[test]
fn empty_v5_round_trip() {
let _init_guard = zebra_test::init();
let tx: &Transaction = &EMPTY_V5_TX;
let data = tx.zcash_serialize_to_vec().expect("tx should serialize");
let tx2: &Transaction = &data
.zcash_deserialize_into()
.expect("tx should deserialize");
assert_eq!(tx, tx2);
let data2 = tx2
.zcash_serialize_to_vec()
.expect("vec serialization is infallible");
assert_eq!(data, data2, "data must be equal if structs are equal");
}
/// An empty transaction v4, with no Sapling, Sprout, or Transparent data
///
/// empty transaction are invalid, but Zebra only checks this rule in
/// zebra_consensus::transaction::Verifier
#[test]
fn empty_v4_round_trip() {
let _init_guard = zebra_test::init();
let tx = Transaction::V4 {
inputs: Vec::new(),
outputs: Vec::new(),
lock_time: LockTime::min_lock_time_timestamp(),
expiry_height: block::Height(0),
joinsplit_data: None,
sapling_shielded_data: None,
};
let data = tx.zcash_serialize_to_vec().expect("tx should serialize");
let tx2 = data
.zcash_deserialize_into()
.expect("tx should deserialize");
assert_eq!(tx, tx2);
let data2 = tx2
.zcash_serialize_to_vec()
.expect("vec serialization is infallible");
assert_eq!(data, data2, "data must be equal if structs are equal");
}
/// Check if an empty V5 transaction can be deserialized by librustzcash too.
#[test]
fn empty_v5_librustzcash_round_trip() {
let _init_guard = zebra_test::init();
let tx: &Transaction = &EMPTY_V5_TX;
let _alt_tx: zcash_primitives::transaction::Transaction = tx.try_into().expect(
"librustzcash deserialization might work for empty zebra serialized transactions. \
Hint: if empty transactions fail, but other transactions work, delete this test",
);
}
/// Do a round-trip test on fake v5 transactions created from v4 transactions
/// in the block test vectors.
///
/// Covers Sapling only, Transparent only, and Sapling/Transparent v5
/// transactions.
#[test]
fn fake_v5_round_trip() {
let _init_guard = zebra_test::init();
fake_v5_round_trip_for_network(Network::Mainnet);
fake_v5_round_trip_for_network(Network::Testnet);
}
fn fake_v5_round_trip_for_network(network: Network) {
let block_iter = network.block_iter();
let overwinter_activation_height = NetworkUpgrade::Overwinter
.activation_height(network)
.expect("a valid height")
.0;
// skip blocks that are before overwinter as they will not have a valid consensus branch id
let blocks_after_overwinter =
block_iter.skip_while(|(height, _)| **height < overwinter_activation_height);
for (height, original_bytes) in blocks_after_overwinter {
let original_block = original_bytes
.zcash_deserialize_into::<Block>()
.expect("block is structurally valid");
// skip this block if it only contains v5 transactions,
// the block round-trip test covers it already
if original_block
.transactions
.iter()
.all(|trans| matches!(trans.as_ref(), &Transaction::V5 { .. }))
{
continue;
}
let mut fake_block = original_block.clone();
fake_block.transactions = fake_block
.transactions
.iter()
.map(AsRef::as_ref)
.map(|t| arbitrary::transaction_to_fake_v5(t, network, Height(*height)))
.map(Into::into)
.collect();
// test each transaction
for (original_tx, fake_tx) in original_block
.transactions
.iter()
.zip(fake_block.transactions.iter())
{
assert_ne!(
&original_tx, &fake_tx,
"v1-v4 transactions must change when converted to fake v5"
);
let fake_bytes = fake_tx
.zcash_serialize_to_vec()
.expect("vec serialization is infallible");
assert_ne!(
&original_bytes[..],
fake_bytes,
"v1-v4 transaction data must change when converted to fake v5"
);
let fake_tx2 = fake_bytes
.zcash_deserialize_into::<Transaction>()
.expect("tx is structurally valid");
assert_eq!(fake_tx.as_ref(), &fake_tx2);
let fake_bytes2 = fake_tx2
.zcash_serialize_to_vec()
.expect("vec serialization is infallible");
assert_eq!(
fake_bytes, fake_bytes2,
"data must be equal if structs are equal"
);
}
// test full blocks
assert_ne!(
&original_block, &fake_block,
"v1-v4 transactions must change when converted to fake v5"
);
let fake_bytes = fake_block
.zcash_serialize_to_vec()
.expect("vec serialization is infallible");
assert_ne!(
&original_bytes[..],
fake_bytes,
"v1-v4 transaction data must change when converted to fake v5"
);
// skip fake blocks which exceed the block size limit
if fake_bytes.len() > MAX_BLOCK_BYTES.try_into().unwrap() {
continue;
}
let fake_block2 = fake_bytes
.zcash_deserialize_into::<Block>()
.expect("block is structurally valid");
assert_eq!(fake_block, fake_block2);
let fake_bytes2 = fake_block2
.zcash_serialize_to_vec()
.expect("vec serialization is infallible");
assert_eq!(
fake_bytes, fake_bytes2,
"data must be equal if structs are equal"
);
}
}
#[test]
fn invalid_orchard_nullifier() {
let _init_guard = zebra_test::init();
use std::convert::TryFrom;
// generated by proptest using something as:
// ```rust
// ...
// array::uniform32(any::<u8>()).prop_map(|x| Self::try_from(x).unwrap()).boxed()
// ...
// ```
let invalid_nullifier_bytes = [
62, 157, 27, 63, 100, 228, 1, 82, 140, 16, 238, 78, 68, 19, 221, 184, 189, 207, 230, 95,
194, 216, 165, 24, 110, 221, 139, 195, 106, 98, 192, 71,
];
assert_eq!(
orchard::Nullifier::try_from(invalid_nullifier_bytes)
.err()
.unwrap()
.to_string(),
SerializationError::Parse("Invalid pallas::Base value for orchard Nullifier").to_string()
);
}
/// Do a round-trip test via librustzcash on fake v5 transactions created from v4 transactions
/// in the block test vectors.
/// Makes sure that zebra-serialized transactions can be deserialized by librustzcash.
#[test]
fn fake_v5_librustzcash_round_trip() {
let _init_guard = zebra_test::init();
fake_v5_librustzcash_round_trip_for_network(Network::Mainnet);
fake_v5_librustzcash_round_trip_for_network(Network::Testnet);
}
fn fake_v5_librustzcash_round_trip_for_network(network: Network) {
let block_iter = network.block_iter();
let overwinter_activation_height = NetworkUpgrade::Overwinter
.activation_height(network)
.expect("a valid height")
.0;
let nu5_activation_height = NetworkUpgrade::Nu5
.activation_height(network)
.unwrap_or(Height::MAX_EXPIRY_HEIGHT)
.0;
// skip blocks that are before overwinter as they will not have a valid consensus branch id
// skip blocks equal or greater Nu5 activation as they are already v5 transactions
let blocks_after_overwinter_and_before_nu5 = block_iter
.skip_while(|(height, _)| **height < overwinter_activation_height)
.take_while(|(height, _)| **height < nu5_activation_height);
for (height, original_bytes) in blocks_after_overwinter_and_before_nu5 {
let original_block = original_bytes
.zcash_deserialize_into::<Block>()
.expect("block is structurally valid");
let mut fake_block = original_block.clone();
fake_block.transactions = fake_block
.transactions
.iter()
.map(AsRef::as_ref)
.map(|t| arbitrary::transaction_to_fake_v5(t, network, Height(*height)))
.map(Into::into)
.collect();
// test each transaction
for (original_tx, fake_tx) in original_block
.transactions
.iter()
.zip(fake_block.transactions.iter())
{
assert_ne!(
&original_tx, &fake_tx,
"v1-v4 transactions must change when converted to fake v5"
);
let fake_bytes = fake_tx
.zcash_serialize_to_vec()
.expect("vec serialization is infallible");
assert_ne!(
&original_bytes[..],
fake_bytes,
"v1-v4 transaction data must change when converted to fake v5"
);
let _alt_tx: zcash_primitives::transaction::Transaction = fake_tx
.as_ref()
.try_into()
.expect("librustzcash deserialization must work for zebra serialized transactions");
}
}
}
#[test]
fn zip244_round_trip() -> Result<()> {
let _init_guard = zebra_test::init();
for test in zip0244::TEST_VECTORS.iter() {
let transaction = test.tx.zcash_deserialize_into::<Transaction>()?;
let reencoded = transaction.zcash_serialize_to_vec()?;
assert_eq!(test.tx, reencoded);
// The borrow is actually needed to call the correct trait impl
#[allow(clippy::needless_borrow)]
let _alt_tx: zcash_primitives::transaction::Transaction = (&transaction)
.try_into()
.expect("librustzcash deserialization must work for zebra serialized transactions");
}
Ok(())
}
#[test]
fn zip244_txid() -> Result<()> {
let _init_guard = zebra_test::init();
for test in zip0244::TEST_VECTORS.iter() {
let transaction = test.tx.zcash_deserialize_into::<Transaction>()?;
let hasher = TxIdBuilder::new(&transaction);
let txid = hasher.txid()?;
assert_eq!(txid.0, test.txid);
}
Ok(())
}
#[test]
fn zip244_auth_digest() -> Result<()> {
let _init_guard = zebra_test::init();
for test in zip0244::TEST_VECTORS.iter() {
let transaction = test.tx.zcash_deserialize_into::<Transaction>()?;
let auth_digest = transaction.auth_digest();
assert_eq!(
auth_digest
.expect("must have auth_digest since it must be a V5 transaction")
.0,
test.auth_digest
);
}
Ok(())
}
#[test]
fn test_vec143_1() -> Result<()> {
let _init_guard = zebra_test::init();
let transaction = ZIP143_1.zcash_deserialize_into::<Transaction>()?;
let hasher = SigHasher::new(
&transaction,
HashType::ALL,
NetworkUpgrade::Overwinter,
&[],
None,
);
let hash = hasher.sighash();
let expected = "a1f1a4e5cd9bd522322d661edd2af1bf2a7019cfab94ece18f4ba935b0a19073";
let result = hex::encode(hash);
let span = tracing::span!(
tracing::Level::ERROR,
"compare_final",
expected.len = expected.len(),
buf.len = result.len()
);
let _guard = span.enter();
assert_eq!(expected, result);
Ok(())
}
#[test]
fn test_vec143_2() -> Result<()> {
let _init_guard = zebra_test::init();
let transaction = ZIP143_2.zcash_deserialize_into::<Transaction>()?;
let value = hex::decode("2f6e04963b4c0100")?.zcash_deserialize_into::<Amount<_>>()?;
let lock_script = Script::new(&hex::decode("53")?);
let input_ind = 1;
let output = transparent::Output { value, lock_script };
let all_previous_outputs = mock_pre_v5_output_list(output, input_ind);
let hasher = SigHasher::new(
&transaction,
HashType::SINGLE,
NetworkUpgrade::Overwinter,
&all_previous_outputs,
Some(input_ind),
);
let hash = hasher.sighash();
let expected = "23652e76cb13b85a0e3363bb5fca061fa791c40c533eccee899364e6e60bb4f7";
let result: &[u8] = hash.as_ref();
let result = hex::encode(result);
let span = tracing::span!(
tracing::Level::ERROR,
"compare_final",
expected.len = expected.len(),
buf.len = result.len()
);
let _guard = span.enter();
assert_eq!(expected, result);
Ok(())
}
#[test]
fn test_vec243_1() -> Result<()> {
let _init_guard = zebra_test::init();
let transaction = ZIP243_1.zcash_deserialize_into::<Transaction>()?;
let hasher = SigHasher::new(
&transaction,
HashType::ALL,
NetworkUpgrade::Sapling,
&[],
None,
);
let hash = hasher.sighash();
let expected = "63d18534de5f2d1c9e169b73f9c783718adbef5c8a7d55b5e7a37affa1dd3ff3";
let result = hex::encode(hash);
let span = tracing::span!(
tracing::Level::ERROR,
"compare_final",
expected.len = expected.len(),
buf.len = result.len()
);
let _guard = span.enter();
assert_eq!(expected, result);
let alt_sighash = crate::primitives::zcash_primitives::sighash(
&transaction,
HashType::ALL,
NetworkUpgrade::Sapling,
&[],
None,
);
let result = hex::encode(alt_sighash);
assert_eq!(expected, result);
Ok(())
}
#[test]
fn test_vec243_2() -> Result<()> {
let _init_guard = zebra_test::init();
let transaction = ZIP243_2.zcash_deserialize_into::<Transaction>()?;
let value = hex::decode("adedf02996510200")?.zcash_deserialize_into::<Amount<_>>()?;
let lock_script = Script::new(&[]);
let input_ind = 1;
let output = transparent::Output { value, lock_script };
let all_previous_outputs = mock_pre_v5_output_list(output, input_ind);
let hasher = SigHasher::new(
&transaction,
HashType::NONE,
NetworkUpgrade::Sapling,
&all_previous_outputs,
Some(input_ind),
);
let hash = hasher.sighash();
let expected = "bbe6d84f57c56b29b914c694baaccb891297e961de3eb46c68e3c89c47b1a1db";
let result = hex::encode(hash);
let span = tracing::span!(
tracing::Level::ERROR,
"compare_final",
expected.len = expected.len(),
buf.len = result.len()
);
let _guard = span.enter();
assert_eq!(expected, result);
let lock_script = Script::new(&[]);
let prevout = transparent::Output { value, lock_script };
let index = input_ind;
let all_previous_outputs = mock_pre_v5_output_list(prevout, input_ind);
let alt_sighash = crate::primitives::zcash_primitives::sighash(
&transaction,
HashType::NONE,
NetworkUpgrade::Sapling,
&all_previous_outputs,
Some(index),
);
let result = hex::encode(alt_sighash);
assert_eq!(expected, result);
Ok(())
}
#[test]
fn test_vec243_3() -> Result<()> {
let _init_guard = zebra_test::init();
let transaction = ZIP243_3.zcash_deserialize_into::<Transaction>()?;
let value = hex::decode("80f0fa0200000000")?.zcash_deserialize_into::<Amount<_>>()?;
let lock_script = Script::new(&hex::decode(
"76a914507173527b4c3318a2aecd793bf1cfed705950cf88ac",
)?);
let input_ind = 0;
let all_previous_outputs = vec![transparent::Output { value, lock_script }];
let hasher = SigHasher::new(
&transaction,
HashType::ALL,
NetworkUpgrade::Sapling,
&all_previous_outputs,
Some(input_ind),
);
let hash = hasher.sighash();
let expected = "f3148f80dfab5e573d5edfe7a850f5fd39234f80b5429d3a57edcc11e34c585b";
let result = hex::encode(hash);
let span = tracing::span!(
tracing::Level::ERROR,
"compare_final",
expected.len = expected.len(),
buf.len = result.len()
);
let _guard = span.enter();
assert_eq!(expected, result);
let lock_script = Script::new(&hex::decode(
"76a914507173527b4c3318a2aecd793bf1cfed705950cf88ac",
)?);
let prevout = transparent::Output { value, lock_script };
let index = input_ind;
let alt_sighash = crate::primitives::zcash_primitives::sighash(
&transaction,
HashType::ALL,
NetworkUpgrade::Sapling,
&[prevout],
Some(index),
);
let result = hex::encode(alt_sighash);
assert_eq!(expected, result);
Ok(())
}
#[test]
fn zip143_sighash() -> Result<()> {
let _init_guard = zebra_test::init();
for (i, test) in zip0143::TEST_VECTORS.iter().enumerate() {
let transaction = test.tx.zcash_deserialize_into::<Transaction>()?;
let (input_index, output) = match test.transparent_input {
Some(transparent_input) => (
Some(transparent_input as usize),
Some(transparent::Output {
value: test.amount.try_into()?,
lock_script: transparent::Script::new(test.script_code.as_ref()),
}),
),
None => (None, None),
};
let all_previous_outputs: Vec<_> = match output {
Some(output) => mock_pre_v5_output_list(output, input_index.unwrap()),
None => vec![],
};
let result = hex::encode(
transaction.sighash(
NetworkUpgrade::from_branch_id(test.consensus_branch_id)
.expect("must be a valid branch ID"),
HashType::from_bits(test.hash_type).expect("must be a valid HashType"),
&all_previous_outputs,
input_index,
),
);
let expected = hex::encode(test.sighash);
assert_eq!(expected, result, "test #{i}: sighash does not match");
}
Ok(())
}
#[test]
fn zip243_sighash() -> Result<()> {
let _init_guard = zebra_test::init();
for (i, test) in zip0243::TEST_VECTORS.iter().enumerate() {
let transaction = test.tx.zcash_deserialize_into::<Transaction>()?;
let (input_index, output) = match test.transparent_input {
Some(transparent_input) => (
Some(transparent_input as usize),
Some(transparent::Output {
value: test.amount.try_into()?,
lock_script: transparent::Script::new(test.script_code.as_ref()),
}),
),
None => (None, None),
};
let all_previous_outputs: Vec<_> = match output {
Some(output) => mock_pre_v5_output_list(output, input_index.unwrap()),
None => vec![],
};
let result = hex::encode(
transaction.sighash(
NetworkUpgrade::from_branch_id(test.consensus_branch_id)
.expect("must be a valid branch ID"),
HashType::from_bits(test.hash_type).expect("must be a valid HashType"),
&all_previous_outputs,
input_index,
),
);
let expected = hex::encode(test.sighash);
assert_eq!(expected, result, "test #{i}: sighash does not match");
}
Ok(())
}
#[test]
fn zip244_sighash() -> Result<()> {
let _init_guard = zebra_test::init();
for (i, test) in zip0244::TEST_VECTORS.iter().enumerate() {
let transaction = test.tx.zcash_deserialize_into::<Transaction>()?;
change(nu5): use new V5 transaction script verification API (#3799) * update librustzcash; adapt to new API * add ticket reference for removing zcash_proofs duplicated dependencies * update to new zcash_script V5 API * use zp_tx shorthand * update to Zcash 4.7.0 dependencies * update protocol versions * feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * Make sync error logs more user-friendly (#3944) - use info level, there is nothing the user needs to do, particularly for a single error - explain that the errors are temporary - hide backtraces, because they look like crashes * Update test.patch.yml with lightwalletd job (#3970) * Update test.patch.yml with lightwalletd job * Remove a workflow condition that will always be false In general, patch workflows need the opposite conditions to the original workflow. But in this case, we know the result of the condition will always be true, so we can just delete it. Co-authored-by: teor <teor@riseup.net> * fix(doc): Fix bugs in the lightwalletd database design (#3964) * Re-order column families in design in dependency order * Minor RFC design tweaks and fixes Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * Repoint zebra image links to our new zfnd.org site for now (#3949) * Repoint zebra image links to our new zfnd.org site for now * Remove images/ Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * Fix typos (#3956) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: teor <teor@riseup.net> * bump database version to trigger testnet rollback * reduce minimum protocol version for now (will be changed later) * update dependencies * Apply suggestions from code review Co-authored-by: teor <teor@riseup.net> * update versions to match zcash 4.7.0 * deny.toml: update 'darling' Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> Co-authored-by: Dimitris Apostolou <dimitris.apostolou@icloud.com>
2022-04-18 17:14:16 -07:00
let all_previous_outputs: Vec<_> = test
.amounts
.iter()
.zip(test.script_pubkeys.iter())
.map(|(amount, script_pubkey)| transparent::Output {
value: (*amount).try_into().unwrap(),
lock_script: transparent::Script::new(script_pubkey.as_ref()),
})
.collect();
let result = hex::encode(transaction.sighash(
NetworkUpgrade::Nu5,
HashType::ALL,
&all_previous_outputs,
change(nu5): use new V5 transaction script verification API (#3799) * update librustzcash; adapt to new API * add ticket reference for removing zcash_proofs duplicated dependencies * update to new zcash_script V5 API * use zp_tx shorthand * update to Zcash 4.7.0 dependencies * update protocol versions * feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * Make sync error logs more user-friendly (#3944) - use info level, there is nothing the user needs to do, particularly for a single error - explain that the errors are temporary - hide backtraces, because they look like crashes * Update test.patch.yml with lightwalletd job (#3970) * Update test.patch.yml with lightwalletd job * Remove a workflow condition that will always be false In general, patch workflows need the opposite conditions to the original workflow. But in this case, we know the result of the condition will always be true, so we can just delete it. Co-authored-by: teor <teor@riseup.net> * fix(doc): Fix bugs in the lightwalletd database design (#3964) * Re-order column families in design in dependency order * Minor RFC design tweaks and fixes Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * Repoint zebra image links to our new zfnd.org site for now (#3949) * Repoint zebra image links to our new zfnd.org site for now * Remove images/ Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * Fix typos (#3956) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: teor <teor@riseup.net> * bump database version to trigger testnet rollback * reduce minimum protocol version for now (will be changed later) * update dependencies * Apply suggestions from code review Co-authored-by: teor <teor@riseup.net> * update versions to match zcash 4.7.0 * deny.toml: update 'darling' Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> Co-authored-by: Dimitris Apostolou <dimitris.apostolou@icloud.com>
2022-04-18 17:14:16 -07:00
None,
));
change(nu5): use new V5 transaction script verification API (#3799) * update librustzcash; adapt to new API * add ticket reference for removing zcash_proofs duplicated dependencies * update to new zcash_script V5 API * use zp_tx shorthand * update to Zcash 4.7.0 dependencies * update protocol versions * feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * Make sync error logs more user-friendly (#3944) - use info level, there is nothing the user needs to do, particularly for a single error - explain that the errors are temporary - hide backtraces, because they look like crashes * Update test.patch.yml with lightwalletd job (#3970) * Update test.patch.yml with lightwalletd job * Remove a workflow condition that will always be false In general, patch workflows need the opposite conditions to the original workflow. But in this case, we know the result of the condition will always be true, so we can just delete it. Co-authored-by: teor <teor@riseup.net> * fix(doc): Fix bugs in the lightwalletd database design (#3964) * Re-order column families in design in dependency order * Minor RFC design tweaks and fixes Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * Repoint zebra image links to our new zfnd.org site for now (#3949) * Repoint zebra image links to our new zfnd.org site for now * Remove images/ Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * Fix typos (#3956) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: teor <teor@riseup.net> * bump database version to trigger testnet rollback * reduce minimum protocol version for now (will be changed later) * update dependencies * Apply suggestions from code review Co-authored-by: teor <teor@riseup.net> * update versions to match zcash 4.7.0 * deny.toml: update 'darling' Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> Co-authored-by: Dimitris Apostolou <dimitris.apostolou@icloud.com>
2022-04-18 17:14:16 -07:00
let expected = hex::encode(test.sighash_shielded);
assert_eq!(expected, result, "test #{i}: sighash does not match");
change(nu5): use new V5 transaction script verification API (#3799) * update librustzcash; adapt to new API * add ticket reference for removing zcash_proofs duplicated dependencies * update to new zcash_script V5 API * use zp_tx shorthand * update to Zcash 4.7.0 dependencies * update protocol versions * feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * Make sync error logs more user-friendly (#3944) - use info level, there is nothing the user needs to do, particularly for a single error - explain that the errors are temporary - hide backtraces, because they look like crashes * Update test.patch.yml with lightwalletd job (#3970) * Update test.patch.yml with lightwalletd job * Remove a workflow condition that will always be false In general, patch workflows need the opposite conditions to the original workflow. But in this case, we know the result of the condition will always be true, so we can just delete it. Co-authored-by: teor <teor@riseup.net> * fix(doc): Fix bugs in the lightwalletd database design (#3964) * Re-order column families in design in dependency order * Minor RFC design tweaks and fixes Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * Repoint zebra image links to our new zfnd.org site for now (#3949) * Repoint zebra image links to our new zfnd.org site for now * Remove images/ Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * Fix typos (#3956) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: teor <teor@riseup.net> * bump database version to trigger testnet rollback * reduce minimum protocol version for now (will be changed later) * update dependencies * Apply suggestions from code review Co-authored-by: teor <teor@riseup.net> * update versions to match zcash 4.7.0 * deny.toml: update 'darling' Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> Co-authored-by: Dimitris Apostolou <dimitris.apostolou@icloud.com>
2022-04-18 17:14:16 -07:00
if let Some(sighash_all) = test.sighash_all {
let result = hex::encode(transaction.sighash(
NetworkUpgrade::Nu5,
HashType::ALL,
&all_previous_outputs,
test.transparent_input.map(|idx| idx as _),
));
let expected = hex::encode(sighash_all);
assert_eq!(expected, result, "test #{i}: sighash does not match");
change(nu5): use new V5 transaction script verification API (#3799) * update librustzcash; adapt to new API * add ticket reference for removing zcash_proofs duplicated dependencies * update to new zcash_script V5 API * use zp_tx shorthand * update to Zcash 4.7.0 dependencies * update protocol versions * feat(rpc): Implement `getblockchaininfo` RPC method (#3891) * Implement `getblockchaininfo` RPC method * add a test for `get_blockchain_info` * fix tohex/fromhex * move comment * Update lightwalletd acceptance test for getblockchaininfo RPC (#3914) * change(rpc): Return getblockchaininfo network upgrades in height order (#3915) * Update lightwalletd acceptance test for getblockchaininfo RPC * Update some doc comments for network upgrades * List network upgrades in order in the getblockchaininfo RPC Also: - Use a constant for the "missing consensus branch ID" RPC value - Simplify fetching consensus branch IDs - Make RPC type derives consistent - Update RPC type documentation * Make RPC type derives consistent * Fix a confusing test comment * get hashand height at the same time * fix estimated_height * fix lint * add extra check Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix typo Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * split test Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * fix(rpc): ignore an expected error in the RPC acceptance tests (#3961) * Add ignored regexes to test command failure regex methods * Ignore empty chain error in getblockchaininfo We expect this error when zebrad starts up with an empty state. Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * Make sync error logs more user-friendly (#3944) - use info level, there is nothing the user needs to do, particularly for a single error - explain that the errors are temporary - hide backtraces, because they look like crashes * Update test.patch.yml with lightwalletd job (#3970) * Update test.patch.yml with lightwalletd job * Remove a workflow condition that will always be false In general, patch workflows need the opposite conditions to the original workflow. But in this case, we know the result of the condition will always be true, so we can just delete it. Co-authored-by: teor <teor@riseup.net> * fix(doc): Fix bugs in the lightwalletd database design (#3964) * Re-order column families in design in dependency order * Minor RFC design tweaks and fixes Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * Repoint zebra image links to our new zfnd.org site for now (#3949) * Repoint zebra image links to our new zfnd.org site for now * Remove images/ Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * Fix typos (#3956) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: teor <teor@riseup.net> * bump database version to trigger testnet rollback * reduce minimum protocol version for now (will be changed later) * update dependencies * Apply suggestions from code review Co-authored-by: teor <teor@riseup.net> * update versions to match zcash 4.7.0 * deny.toml: update 'darling' Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com> Co-authored-by: teor <teor@riseup.net> Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> Co-authored-by: Dimitris Apostolou <dimitris.apostolou@icloud.com>
2022-04-18 17:14:16 -07:00
}
}
Ok(())
}
#[test]
fn binding_signatures() {
let _init_guard = zebra_test::init();
binding_signatures_for_network(Network::Mainnet);
binding_signatures_for_network(Network::Testnet);
}
fn binding_signatures_for_network(network: Network) {
let block_iter = network.block_iter();
for (height, bytes) in block_iter {
let upgrade = NetworkUpgrade::current(network, Height(*height));
let block = bytes
.zcash_deserialize_into::<Block>()
.expect("a valid block");
for tx in block.transactions {
match &*tx {
Transaction::V1 { .. } | Transaction::V2 { .. } | Transaction::V3 { .. } => (),
Transaction::V4 {
sapling_shielded_data,
..
} => {
if let Some(sapling_shielded_data) = sapling_shielded_data {
let shielded_sighash = tx.sighash(upgrade, HashType::ALL, &[], None);
let bvk = redjubjub::VerificationKey::try_from(
sapling_shielded_data.binding_verification_key(),
)
.expect("a valid redjubjub::VerificationKey");
bvk.verify(
shielded_sighash.as_ref(),
&sapling_shielded_data.binding_sig,
)
.expect("must pass verification");
}
}
Transaction::V5 {
sapling_shielded_data,
..
} => {
if let Some(sapling_shielded_data) = sapling_shielded_data {
let shielded_sighash = tx.sighash(upgrade, HashType::ALL, &[], None);
let bvk = redjubjub::VerificationKey::try_from(
sapling_shielded_data.binding_verification_key(),
)
.expect("a valid redjubjub::VerificationKey");
bvk.verify(
shielded_sighash.as_ref(),
&sapling_shielded_data.binding_sig,
)
.expect("must pass verification");
}
}
}
}
}
}