Replace `unstable-nu6` and `zfuture` feature flags with cfg flags

Neither of these should have been feature flags, as they gate breaking
changes to the Zcash consensus rules (and in some ways are incompatible
with each other), while feature flags should be additive.
This commit is contained in:
Jack Grigg 2024-03-10 18:07:59 +00:00
parent 98c82eb6c6
commit 6898dbf094
27 changed files with 187 additions and 190 deletions

View File

@ -36,7 +36,7 @@ jobs:
extra_flags: orchard
rustflags: '--cfg zcash_unstable="orchard"'
- state: NU6
extra_flags: unstable-nu6
rustflags: '--cfg zcash_unstable="nu6"'
exclude:
- target: macOS
@ -103,7 +103,7 @@ jobs:
os: windows-latest
- state: ZFuture
extra_flags: zfuture
rustflags: '--cfg zcash_unstable="zfuture"'
env:
RUSTFLAGS: ${{ matrix.rustflags }}

15
Cargo.lock generated
View File

@ -3102,6 +3102,21 @@ dependencies = [
"nonempty",
]
[[package]]
name = "zcash_extensions"
version = "0.0.0"
dependencies = [
"blake2b_simd",
"ff",
"jubjub",
"orchard",
"rand_core",
"sapling-crypto",
"zcash_address",
"zcash_primitives",
"zcash_proofs",
]
[[package]]
name = "zcash_history"
version = "0.4.0"

View File

@ -7,8 +7,7 @@ members = [
"components/zcash_protocol",
"zcash_client_backend",
"zcash_client_sqlite",
# Disabled until we replace the `zfutures` feature flag with a compiler flag.
# "zcash_extensions",
"zcash_extensions",
"zcash_history",
"zcash_keys",
"zcash_primitives",

View File

@ -11,6 +11,11 @@ and this library adheres to Rust's notion of
- `zcash_protocol::memo`:
- `impl TryFrom<&MemoBytes> for Memo`
### Removed
- `unstable-nu6` and `zfuture` feature flags (use `--cfg zcash_unstable=\"nu6\"`
or `--cfg zcash_unstable=\"zfuture\"` in `RUSTFLAGS` and `RUSTDOCFLAGS`
instead).
## [0.1.0] - 2024-03-06
The entries below are relative to the `zcash_primitives` crate as of the tag
`zcash_primitives-0.14.0`.

View File

@ -45,14 +45,3 @@ test-dependencies = [
## Exposes support for working with a local consensus (e.g. regtest).
local-consensus = []
#! ### Experimental features
#!
#! ⚠️ Enabling these features will likely make your code incompatible with current Zcash
#! consensus rules!
## Exposes the in-development NU6 features.
unstable-nu6 = []
## Exposes early in-development features that are not yet planned for any network upgrade.
zfuture = []

View File

@ -354,9 +354,9 @@ impl Parameters for MainNetwork {
NetworkUpgrade::Heartwood => Some(BlockHeight(903_000)),
NetworkUpgrade::Canopy => Some(BlockHeight(1_046_400)),
NetworkUpgrade::Nu5 => Some(BlockHeight(1_687_104)),
#[cfg(feature = "unstable-nu6")]
#[cfg(zcash_unstable = "nu6")]
NetworkUpgrade::Nu6 => None,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
NetworkUpgrade::ZFuture => None,
}
}
@ -384,9 +384,9 @@ impl Parameters for TestNetwork {
NetworkUpgrade::Heartwood => Some(BlockHeight(903_800)),
NetworkUpgrade::Canopy => Some(BlockHeight(1_028_500)),
NetworkUpgrade::Nu5 => Some(BlockHeight(1_842_420)),
#[cfg(feature = "unstable-nu6")]
#[cfg(zcash_unstable = "nu6")]
NetworkUpgrade::Nu6 => None,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
NetworkUpgrade::ZFuture => None,
}
}
@ -452,14 +452,14 @@ pub enum NetworkUpgrade {
/// The [Nu6] network upgrade.
///
/// [Nu6]: https://z.cash/upgrade/nu6/
#[cfg(feature = "unstable-nu6")]
#[cfg(zcash_unstable = "nu6")]
Nu6,
/// The ZFUTURE network upgrade.
///
/// This upgrade is expected never to activate on mainnet;
/// it is intended for use in integration testing of functionality
/// that is a candidate for integration in a future network upgrade.
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
ZFuture,
}
@ -474,9 +474,9 @@ impl fmt::Display for NetworkUpgrade {
NetworkUpgrade::Heartwood => write!(f, "Heartwood"),
NetworkUpgrade::Canopy => write!(f, "Canopy"),
NetworkUpgrade::Nu5 => write!(f, "Nu5"),
#[cfg(feature = "unstable-nu6")]
#[cfg(zcash_unstable = "nu6")]
NetworkUpgrade::Nu6 => write!(f, "Nu6"),
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
NetworkUpgrade::ZFuture => write!(f, "ZFUTURE"),
}
}
@ -491,9 +491,9 @@ impl NetworkUpgrade {
NetworkUpgrade::Heartwood => BranchId::Heartwood,
NetworkUpgrade::Canopy => BranchId::Canopy,
NetworkUpgrade::Nu5 => BranchId::Nu5,
#[cfg(feature = "unstable-nu6")]
#[cfg(zcash_unstable = "nu6")]
NetworkUpgrade::Nu6 => BranchId::Nu6,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
NetworkUpgrade::ZFuture => BranchId::ZFuture,
}
}
@ -510,7 +510,7 @@ const UPGRADES_IN_ORDER: &[NetworkUpgrade] = &[
NetworkUpgrade::Heartwood,
NetworkUpgrade::Canopy,
NetworkUpgrade::Nu5,
#[cfg(feature = "unstable-nu6")]
#[cfg(zcash_unstable = "nu6")]
NetworkUpgrade::Nu6,
];
@ -549,11 +549,11 @@ pub enum BranchId {
/// The consensus rules deployed by [`NetworkUpgrade::Nu5`].
Nu5,
/// The consensus rules deployed by [`NetworkUpgrade::Nu6`].
#[cfg(feature = "unstable-nu6")]
#[cfg(zcash_unstable = "nu6")]
Nu6,
/// Candidates for future consensus rules; this branch will never
/// activate on mainnet.
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
ZFuture,
}
@ -571,9 +571,9 @@ impl TryFrom<u32> for BranchId {
0xf5b9_230b => Ok(BranchId::Heartwood),
0xe9ff_75a6 => Ok(BranchId::Canopy),
0xc2d6_d0b4 => Ok(BranchId::Nu5),
#[cfg(feature = "unstable-nu6")]
#[cfg(zcash_unstable = "nu6")]
0xc8e7_1055 => Ok(BranchId::Nu6),
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
0xffff_ffff => Ok(BranchId::ZFuture),
_ => Err("Unknown consensus branch ID"),
}
@ -590,9 +590,9 @@ impl From<BranchId> for u32 {
BranchId::Heartwood => 0xf5b9_230b,
BranchId::Canopy => 0xe9ff_75a6,
BranchId::Nu5 => 0xc2d6_d0b4,
#[cfg(feature = "unstable-nu6")]
#[cfg(zcash_unstable = "nu6")]
BranchId::Nu6 => 0xc8e7_1055,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
BranchId::ZFuture => 0xffff_ffff,
}
}
@ -658,15 +658,15 @@ impl BranchId {
.activation_height(NetworkUpgrade::Canopy)
.map(|lower| (lower, params.activation_height(NetworkUpgrade::Nu5))),
BranchId::Nu5 => params.activation_height(NetworkUpgrade::Nu5).map(|lower| {
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
let upper = params.activation_height(NetworkUpgrade::ZFuture);
#[cfg(not(feature = "zfuture"))]
#[cfg(not(zcash_unstable = "zfuture"))]
let upper = None;
(lower, upper)
}),
#[cfg(feature = "unstable-nu6")]
#[cfg(zcash_unstable = "nu6")]
BranchId::Nu6 => None,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
BranchId::ZFuture => params
.activation_height(NetworkUpgrade::ZFuture)
.map(|lower| (lower, None)),
@ -694,9 +694,9 @@ pub mod testing {
BranchId::Heartwood,
BranchId::Canopy,
BranchId::Nu5,
#[cfg(feature = "unstable-nu6")]
#[cfg(zcash_unstable = "nu6")]
BranchId::Nu6,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
BranchId::ZFuture,
])
}

View File

@ -26,10 +26,6 @@ use crate::consensus::{BlockHeight, NetworkType, NetworkUpgrade, Parameters};
/// heartwood: Some(BlockHeight::from_u32(1)),
/// canopy: Some(BlockHeight::from_u32(1)),
/// nu5: Some(BlockHeight::from_u32(1)),
/// #[cfg(feature = "unstable-nu6")]
/// nu6: Some(BlockHeight::from_u32(1)),
/// #[cfg(feature = "zfuture")]
/// z_future: Some(BlockHeight::from_u32(1)),
/// };
/// ```
///
@ -41,9 +37,9 @@ pub struct LocalNetwork {
pub heartwood: Option<BlockHeight>,
pub canopy: Option<BlockHeight>,
pub nu5: Option<BlockHeight>,
#[cfg(feature = "unstable-nu6")]
#[cfg(zcash_unstable = "nu6")]
pub nu6: Option<BlockHeight>,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
pub z_future: Option<BlockHeight>,
}
@ -61,9 +57,9 @@ impl Parameters for LocalNetwork {
NetworkUpgrade::Heartwood => self.heartwood,
NetworkUpgrade::Canopy => self.canopy,
NetworkUpgrade::Nu5 => self.nu5,
#[cfg(feature = "unstable-nu6")]
#[cfg(zcash_unstable = "nu6")]
NetworkUpgrade::Nu6 => self.nu6,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
NetworkUpgrade::ZFuture => self.z_future,
}
}
@ -85,9 +81,9 @@ mod tests {
let expected_heartwood = BlockHeight::from_u32(4);
let expected_canopy = BlockHeight::from_u32(5);
let expected_nu5 = BlockHeight::from_u32(6);
#[cfg(feature = "unstable-nu6")]
#[cfg(zcash_unstable = "nu6")]
let expected_nu6 = BlockHeight::from_u32(7);
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
let expected_z_future = BlockHeight::from_u32(7);
let regtest = LocalNetwork {
@ -97,9 +93,9 @@ mod tests {
heartwood: Some(expected_heartwood),
canopy: Some(expected_canopy),
nu5: Some(expected_nu5),
#[cfg(feature = "unstable-nu6")]
#[cfg(zcash_unstable = "nu6")]
nu6: Some(expected_nu6),
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
z_future: Some(expected_z_future),
};
@ -109,9 +105,9 @@ mod tests {
assert!(regtest.is_nu_active(NetworkUpgrade::Heartwood, expected_heartwood));
assert!(regtest.is_nu_active(NetworkUpgrade::Canopy, expected_canopy));
assert!(regtest.is_nu_active(NetworkUpgrade::Nu5, expected_nu5));
#[cfg(feature = "unstable-nu6")]
#[cfg(zcash_unstable = "nu6")]
assert!(regtest.is_nu_active(NetworkUpgrade::Nu6, expected_nu6));
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
assert!(!regtest.is_nu_active(NetworkUpgrade::ZFuture, expected_nu5));
}
@ -123,9 +119,9 @@ mod tests {
let expected_heartwood = BlockHeight::from_u32(4);
let expected_canopy = BlockHeight::from_u32(5);
let expected_nu5 = BlockHeight::from_u32(6);
#[cfg(feature = "unstable-nu6")]
#[cfg(zcash_unstable = "nu6")]
let expected_nu6 = BlockHeight::from_u32(7);
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
let expected_z_future = BlockHeight::from_u32(7);
let regtest = LocalNetwork {
@ -135,9 +131,9 @@ mod tests {
heartwood: Some(expected_heartwood),
canopy: Some(expected_canopy),
nu5: Some(expected_nu5),
#[cfg(feature = "unstable-nu6")]
#[cfg(zcash_unstable = "nu6")]
nu6: Some(expected_nu6),
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
z_future: Some(expected_z_future),
};
@ -165,7 +161,7 @@ mod tests {
regtest.activation_height(NetworkUpgrade::Nu5),
Some(expected_nu5)
);
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
assert_eq!(
regtest.activation_height(NetworkUpgrade::ZFuture),
Some(expected_z_future)
@ -180,9 +176,9 @@ mod tests {
let expected_heartwood = BlockHeight::from_u32(4);
let expected_canopy = BlockHeight::from_u32(5);
let expected_nu5 = BlockHeight::from_u32(6);
#[cfg(feature = "unstable-nu6")]
#[cfg(zcash_unstable = "nu6")]
let expected_nu6 = BlockHeight::from_u32(7);
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
let expected_z_future = BlockHeight::from_u32(7);
let regtest = LocalNetwork {
@ -192,9 +188,9 @@ mod tests {
heartwood: Some(expected_heartwood),
canopy: Some(expected_canopy),
nu5: Some(expected_nu5),
#[cfg(feature = "unstable-nu6")]
#[cfg(zcash_unstable = "nu6")]
nu6: Some(expected_nu6),
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
z_future: Some(expected_z_future),
};

View File

@ -97,8 +97,6 @@ zcash_address = { workspace = true, features = ["test-dependencies"] }
[features]
default = ["multicore"]
unstable-nu6 = ["zcash_primitives/unstable-nu6"]
zfuture = ["zcash_primitives/zfuture"]
## Enables multithreading support for creating proofs and building subtrees.
multicore = ["maybe-rayon/threads", "zcash_primitives/multicore"]

View File

@ -119,9 +119,9 @@ impl TestBuilder<()> {
heartwood: Some(BlockHeight::from_u32(100_000)),
canopy: Some(BlockHeight::from_u32(100_000)),
nu5: Some(BlockHeight::from_u32(100_000)),
#[cfg(feature = "unstable-nu6")]
#[cfg(zcash_unstable = "nu6")]
nu6: None,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
z_future: None,
},
cache: (),

View File

@ -16,7 +16,7 @@ rustdoc-args = ["--cfg", "docsrs"]
[dependencies]
blake2b_simd.workspace = true
zcash_primitives = { workspace = true, features = ["zfuture" ] }
zcash_primitives.workspace = true
[dev-dependencies]
ff.workspace = true
@ -29,7 +29,6 @@ zcash_proofs.workspace = true
[features]
transparent-inputs = []
unstable-nu6 = ["zcash_primitives/unstable-nu6"]
[lib]
bench = false

View File

@ -3,5 +3,10 @@
// Catch documentation errors caused by code changes.
#![deny(rustdoc::broken_intra_doc_links)]
// For workspace compilation reasons, we have this crate in the workspace and just leave
// it empty if `zfuture` is not enabled.
#[cfg(zcash_unstable = "zfuture")]
pub mod consensus;
#[cfg(zcash_unstable = "zfuture")]
pub mod transparent;

View File

@ -513,7 +513,7 @@ mod tests {
NetworkUpgrade::Heartwood => Some(BlockHeight::from_u32(903_800)),
NetworkUpgrade::Canopy => Some(BlockHeight::from_u32(1_028_500)),
NetworkUpgrade::Nu5 => Some(BlockHeight::from_u32(1_200_000)),
#[cfg(feature = "unstable-nu6")]
#[cfg(zcash_unstable = "nu6")]
NetworkUpgrade::Nu6 => Some(BlockHeight::from_u32(1_300_000)),
NetworkUpgrade::ZFuture => Some(BlockHeight::from_u32(1_400_000)),
}

View File

@ -33,6 +33,9 @@ and this library adheres to Rust's notion of
- `impl From<NonNegativeAmount> for orchard::NoteValue`
- The `local_consensus` module and feature flag have been removed; use the module
from the `zcash_protocol` crate instead.
- `unstable-nu6` and `zfuture` feature flags (use `--cfg zcash_unstable=\"nu6\"`
or `--cfg zcash_unstable=\"zfuture\"` in `RUSTFLAGS` and `RUSTDOCFLAGS`
instead).
## [0.14.0] - 2024-03-01
### Added

View File

@ -123,16 +123,6 @@ test-dependencies = [
"zcash_protocol/test-dependencies",
]
#! ### Experimental features
#!
#! ⚠️ Enabling these features will likely make your code incompatible with current Zcash
#! consensus rules!
## Exposes the in-development NU6 features.
unstable-nu6 = ["zcash_protocol/unstable-nu6"]
## Exposes early in-development features that are not yet planned for any network upgrade.
zfuture = ["zcash_protocol/zfuture"]
[lib]
bench = false

View File

@ -26,6 +26,6 @@ pub mod merkle_tree;
use sapling;
pub mod transaction;
pub use zip32;
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
pub mod extensions;
pub mod zip339;

View File

@ -35,7 +35,7 @@ use crate::transaction::components::transparent::builder::TransparentInputInfo;
#[cfg(not(feature = "transparent-inputs"))]
use std::convert::Infallible;
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
use crate::{
extensions::transparent::{ExtensionTxBuilder, ToPayload},
transaction::{
@ -100,7 +100,7 @@ pub enum Error<FE> {
/// spend or output was added.
OrchardBuilderNotAvailable,
/// An error occurred in constructing the TZE parts of a transaction.
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
TzeBuild(tze::builder::Error),
}
@ -132,7 +132,7 @@ impl<FE: fmt::Display> fmt::Display for Error<FE> {
f,
"Cannot create Orchard transactions without an Orchard anchor, or before NU5 activation"
),
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
Error::TzeBuild(err) => err.fmt(f),
}
}
@ -284,9 +284,9 @@ pub struct Builder<'a, P, U: sapling::builder::ProverProgress> {
// derivatives for proving and signing to complete transaction creation.
sapling_asks: Vec<sapling::keys::SpendAuthorizingKey>,
orchard_saks: Vec<orchard::keys::SpendAuthorizingKey>,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
tze_builder: TzeBuilder<'a, TransactionData<Unauthorized>>,
#[cfg(not(feature = "zfuture"))]
#[cfg(not(zcash_unstable = "zfuture"))]
tze_builder: std::marker::PhantomData<&'a ()>,
progress_notifier: U,
}
@ -369,9 +369,9 @@ impl<'a, P: consensus::Parameters> Builder<'a, P, ()> {
orchard_builder,
sapling_asks: vec![],
orchard_saks: Vec::new(),
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
tze_builder: TzeBuilder::empty(),
#[cfg(not(feature = "zfuture"))]
#[cfg(not(zcash_unstable = "zfuture"))]
tze_builder: std::marker::PhantomData,
progress_notifier: (),
}
@ -521,7 +521,7 @@ impl<'a, P: consensus::Parameters, U: sapling::builder::ProverProgress> Builder<
.map_err(|_| BalanceError::Overflow)
},
)?,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
self.tze_builder.value_balance()?,
];
@ -577,7 +577,7 @@ impl<'a, P: consensus::Parameters, U: sapling::builder::ProverProgress> Builder<
.map_err(FeeError::FeeRule)
}
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
pub fn get_fee_zfuture<FR: FeeRule + FutureFeeRule>(
&self,
fee_rule: &FR,
@ -641,7 +641,7 @@ impl<'a, P: consensus::Parameters, U: sapling::builder::ProverProgress> Builder<
///
/// Upon success, returns a tuple containing the final transaction, and the
/// [`SaplingMetadata`] generated during the build process.
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
pub fn build_zfuture<
R: RngCore + CryptoRng,
SP: SpendProver,
@ -734,7 +734,7 @@ impl<'a, P: consensus::Parameters, U: sapling::builder::ProverProgress> Builder<
None => (None, orchard::builder::BundleMetadata::empty()),
};
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
let (tze_bundle, tze_signers) = self.tze_builder.build();
let unauthed_tx: TransactionData<Unauthorized> = TransactionData {
@ -746,7 +746,7 @@ impl<'a, P: consensus::Parameters, U: sapling::builder::ProverProgress> Builder<
sprout_bundle: None,
sapling_bundle,
orchard_bundle,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
tze_bundle,
};
@ -764,7 +764,7 @@ impl<'a, P: consensus::Parameters, U: sapling::builder::ProverProgress> Builder<
)
});
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
let tze_bundle = unauthed_tx
.tze_bundle
.clone()
@ -814,7 +814,7 @@ impl<'a, P: consensus::Parameters, U: sapling::builder::ProverProgress> Builder<
sprout_bundle: unauthed_tx.sprout_bundle,
sapling_bundle,
orchard_bundle,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
tze_bundle,
};
@ -828,7 +828,7 @@ impl<'a, P: consensus::Parameters, U: sapling::builder::ProverProgress> Builder<
}
}
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
impl<'a, P: consensus::Parameters, U: sapling::builder::ProverProgress> ExtensionTxBuilder<'a>
for Builder<'a, P, U>
{
@ -934,7 +934,7 @@ mod tests {
use super::{Builder, Error};
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
#[cfg(feature = "transparent-inputs")]
use super::TzeBuilder;
@ -969,9 +969,9 @@ mod tests {
expiry_height: sapling_activation_height + DEFAULT_TX_EXPIRY_DELTA,
transparent_builder: TransparentBuilder::empty(),
sapling_builder: None,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
tze_builder: TzeBuilder::empty(),
#[cfg(not(feature = "zfuture"))]
#[cfg(not(zcash_unstable = "zfuture"))]
tze_builder: std::marker::PhantomData,
progress_notifier: (),
orchard_builder: None,

View File

@ -16,6 +16,7 @@ pub mod orchard;
pub mod sapling;
pub mod sprout;
pub mod transparent;
#[cfg(zcash_unstable = "zfuture")]
pub mod tze;
pub use self::{
@ -25,7 +26,7 @@ pub use self::{
};
pub use crate::sapling::bundle::{OutputDescription, SpendDescription};
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
pub use self::tze::{TzeIn, TzeOut};
// π_A + π_B + π_C

View File

@ -1,5 +1,4 @@
//! Structs representing the TZE components within Zcash transactions.
#![cfg(feature = "zfuture")]
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use std::convert::TryFrom;

View File

@ -1,5 +1,4 @@
//! Types and functions for building TZE transaction components
#![cfg(feature = "zfuture")]
use std::fmt;

View File

@ -9,7 +9,7 @@ pub mod fixed;
pub mod transparent;
pub mod zip317;
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
pub mod tze;
/// A trait that represents the ability to compute the fees that must be paid
@ -37,7 +37,7 @@ pub trait FeeRule {
/// A trait that represents the ability to compute the fees that must be paid by a transaction
/// having a specified set of inputs and outputs, for use when experimenting with the TZE feature.
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
pub trait FutureFeeRule: FeeRule {
/// Computes the total fee required for a transaction given the provided inputs and outputs.
///

View File

@ -4,7 +4,7 @@ use crate::{
transaction::fees::{transparent, zip317},
};
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
use crate::transaction::fees::tze;
/// A fee rule that always returns a fixed fee, irrespective of the structure of
@ -62,7 +62,7 @@ impl super::FeeRule for FeeRule {
}
}
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
impl super::FutureFeeRule for FeeRule {
fn fee_required_zfuture<P: consensus::Parameters>(
&self,

View File

@ -38,7 +38,7 @@ use self::{
util::sha256d::{HashReader, HashWriter},
};
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
use self::components::tze::{self, TzeIn, TzeOut};
const OVERWINTER_VERSION_GROUP_ID: u32 = 0x03C48270;
@ -55,9 +55,9 @@ const V5_VERSION_GROUP_ID: u32 = 0x26A7270A;
/// using these constants should be inspected, and use of these constants
/// should be removed as appropriate in favor of the new consensus
/// transaction version and group.
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
const ZFUTURE_VERSION_GROUP_ID: u32 = 0xFFFFFFFF;
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
const ZFUTURE_TX_VERSION: u32 = 0x0000FFFF;
/// The identifier for a Zcash transaction.
@ -131,7 +131,7 @@ pub enum TxVersion {
Overwinter,
Sapling,
Zip225,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
ZFuture,
}
@ -146,7 +146,7 @@ impl TxVersion {
(OVERWINTER_TX_VERSION, OVERWINTER_VERSION_GROUP_ID) => Ok(TxVersion::Overwinter),
(SAPLING_TX_VERSION, SAPLING_VERSION_GROUP_ID) => Ok(TxVersion::Sapling),
(V5_TX_VERSION, V5_VERSION_GROUP_ID) => Ok(TxVersion::Zip225),
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
(ZFUTURE_TX_VERSION, ZFUTURE_VERSION_GROUP_ID) => Ok(TxVersion::ZFuture),
_ => Err(io::Error::new(
io::ErrorKind::InvalidInput,
@ -176,7 +176,7 @@ impl TxVersion {
TxVersion::Overwinter => OVERWINTER_TX_VERSION,
TxVersion::Sapling => SAPLING_TX_VERSION,
TxVersion::Zip225 => V5_TX_VERSION,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
TxVersion::ZFuture => ZFUTURE_TX_VERSION,
}
}
@ -187,7 +187,7 @@ impl TxVersion {
TxVersion::Overwinter => OVERWINTER_VERSION_GROUP_ID,
TxVersion::Sapling => SAPLING_VERSION_GROUP_ID,
TxVersion::Zip225 => V5_VERSION_GROUP_ID,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
TxVersion::ZFuture => ZFUTURE_VERSION_GROUP_ID,
}
}
@ -206,7 +206,7 @@ impl TxVersion {
TxVersion::Sprout(v) => *v >= 2u32,
TxVersion::Overwinter | TxVersion::Sapling => true,
TxVersion::Zip225 => false,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
TxVersion::ZFuture => true,
}
}
@ -221,7 +221,7 @@ impl TxVersion {
TxVersion::Sprout(_) | TxVersion::Overwinter => false,
TxVersion::Sapling => true,
TxVersion::Zip225 => true,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
TxVersion::ZFuture => true,
}
}
@ -231,12 +231,12 @@ impl TxVersion {
match self {
TxVersion::Sprout(_) | TxVersion::Overwinter | TxVersion::Sapling => false,
TxVersion::Zip225 => true,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
TxVersion::ZFuture => true,
}
}
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
pub fn has_tze(&self) -> bool {
matches!(self, TxVersion::ZFuture)
}
@ -250,9 +250,9 @@ impl TxVersion {
TxVersion::Sapling
}
BranchId::Nu5 => TxVersion::Zip225,
#[cfg(feature = "unstable-nu6")]
#[cfg(zcash_unstable = "nu6")]
BranchId::Nu6 => TxVersion::Zip225,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
BranchId::ZFuture => TxVersion::ZFuture,
}
}
@ -264,7 +264,7 @@ pub trait Authorization {
type SaplingAuth: sapling::bundle::Authorization;
type OrchardAuth: orchard::bundle::Authorization;
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
type TzeAuth: tze::Authorization;
}
@ -277,7 +277,7 @@ impl Authorization for Authorized {
type SaplingAuth = sapling::bundle::Authorized;
type OrchardAuth = orchard::bundle::Authorized;
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
type TzeAuth = tze::Authorized;
}
@ -294,7 +294,7 @@ impl Authorization for Unauthorized {
type OrchardAuth =
orchard::builder::InProgress<orchard::builder::Unproven, orchard::builder::Unauthorized>;
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
type TzeAuth = tze::builder::Unauthorized;
}
@ -330,7 +330,7 @@ pub struct TransactionData<A: Authorization> {
sprout_bundle: Option<sprout::Bundle>,
sapling_bundle: Option<sapling::Bundle<A::SaplingAuth, Amount>>,
orchard_bundle: Option<orchard::bundle::Bundle<A::OrchardAuth, Amount>>,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
tze_bundle: Option<tze::Bundle<A::TzeAuth>>,
}
@ -356,14 +356,14 @@ impl<A: Authorization> TransactionData<A> {
sprout_bundle,
sapling_bundle,
orchard_bundle,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
tze_bundle: None,
}
}
/// Constructs a `TransactionData` from its constituent parts, including speculative
/// future parts that are not in the current Zcash consensus rules.
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
#[allow(clippy::too_many_arguments)]
pub fn from_parts_zfuture(
version: TxVersion,
@ -423,7 +423,7 @@ impl<A: Authorization> TransactionData<A> {
self.orchard_bundle.as_ref()
}
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
pub fn tze_bundle(&self) -> Option<&tze::Bundle<A::TzeAuth>> {
self.tze_bundle.as_ref()
}
@ -469,7 +469,7 @@ impl<A: Authorization> TransactionData<A> {
digester.digest_transparent(self.transparent_bundle.as_ref()),
digester.digest_sapling(self.sapling_bundle.as_ref()),
digester.digest_orchard(self.orchard_bundle.as_ref()),
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
digester.digest_tze(self.tze_bundle.as_ref()),
)
}
@ -489,9 +489,10 @@ impl<A: Authorization> TransactionData<A> {
f_orchard: impl FnOnce(
Option<orchard::bundle::Bundle<A::OrchardAuth, Amount>>,
) -> Option<orchard::bundle::Bundle<B::OrchardAuth, Amount>>,
#[cfg(feature = "zfuture")] f_tze: impl FnOnce(
#[cfg(zcash_unstable = "zfuture")] f_tze: impl FnOnce(
Option<tze::Bundle<A::TzeAuth>>,
) -> Option<tze::Bundle<B::TzeAuth>>,
)
-> Option<tze::Bundle<B::TzeAuth>>,
) -> TransactionData<B> {
TransactionData {
version: self.version,
@ -502,7 +503,7 @@ impl<A: Authorization> TransactionData<A> {
sprout_bundle: self.sprout_bundle,
sapling_bundle: f_sapling(self.sapling_bundle),
orchard_bundle: f_orchard(self.orchard_bundle),
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
tze_bundle: f_tze(self.tze_bundle),
}
}
@ -512,7 +513,7 @@ impl<A: Authorization> TransactionData<A> {
f_transparent: impl transparent::MapAuth<A::TransparentAuth, B::TransparentAuth>,
mut f_sapling: impl sapling_serialization::MapAuth<A::SaplingAuth, B::SaplingAuth>,
mut f_orchard: impl orchard_serialization::MapAuth<A::OrchardAuth, B::OrchardAuth>,
#[cfg(feature = "zfuture")] f_tze: impl tze::MapAuth<A::TzeAuth, B::TzeAuth>,
#[cfg(zcash_unstable = "zfuture")] f_tze: impl tze::MapAuth<A::TzeAuth, B::TzeAuth>,
) -> TransactionData<B> {
TransactionData {
version: self.version,
@ -539,7 +540,7 @@ impl<A: Authorization> TransactionData<A> {
|f, a| f.map_authorization(a),
)
}),
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
tze_bundle: self.tze_bundle.map(|b| b.map_authorization(f_tze)),
}
}
@ -566,7 +567,7 @@ impl Transaction {
Self::from_data_v4(data)
}
TxVersion::Zip225 => Ok(Self::from_data_v5(data)),
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
TxVersion::ZFuture => Ok(Self::from_data_v5(data)),
}
}
@ -609,7 +610,7 @@ impl Transaction {
Self::read_v4(reader, version, consensus_branch_id)
}
TxVersion::Zip225 => Self::read_v5(reader.into_base_reader(), version),
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
TxVersion::ZFuture => Self::read_v5(reader.into_base_reader(), version),
}
}
@ -685,7 +686,7 @@ impl Transaction {
)
}),
orchard_bundle: None,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
tze_bundle: None,
},
})
@ -721,7 +722,7 @@ impl Transaction {
let sapling_bundle = sapling_serialization::read_v5_bundle(&mut reader)?;
let orchard_bundle = orchard_serialization::read_v5_bundle(&mut reader)?;
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
let tze_bundle = if version.has_tze() {
Self::read_tze(&mut reader)?
} else {
@ -737,7 +738,7 @@ impl Transaction {
sprout_bundle: None,
sapling_bundle,
orchard_bundle,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
tze_bundle,
};
@ -765,7 +766,7 @@ impl Transaction {
sapling_serialization::read_v5_bundle(reader)
}
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
fn read_tze<R: Read>(mut reader: &mut R) -> io::Result<Option<tze::Bundle<tze::Authorized>>> {
let vin = Vector::read(&mut reader, TzeIn::read)?;
let vout = Vector::read(&mut reader, TzeOut::read)?;
@ -786,7 +787,7 @@ impl Transaction {
self.write_v4(writer)
}
TxVersion::Zip225 => self.write_v5(writer),
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
TxVersion::ZFuture => self.write_v5(writer),
}
}
@ -855,7 +856,7 @@ impl Transaction {
self.write_transparent(&mut writer)?;
self.write_v5_sapling(&mut writer)?;
orchard_serialization::write_v5_bundle(self.orchard_bundle.as_ref(), &mut writer)?;
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
self.write_tze(&mut writer)?;
Ok(())
}
@ -880,7 +881,7 @@ impl Transaction {
sapling_serialization::write_v5_bundle(writer, self.sapling_bundle.as_ref())
}
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
pub fn write_tze<W: Write>(&self, mut writer: W) -> io::Result<()> {
if let Some(bundle) = &self.tze_bundle {
Vector::write(&mut writer, &bundle.vin, |w, e| e.write(w))?;
@ -919,7 +920,7 @@ pub struct TxDigests<A> {
pub transparent_digests: Option<TransparentDigests<A>>,
pub sapling_digest: Option<A>,
pub orchard_digest: Option<A>,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
pub tze_digests: Option<TzeDigests<A>>,
}
@ -929,7 +930,7 @@ pub trait TransactionDigest<A: Authorization> {
type SaplingDigest;
type OrchardDigest;
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
type TzeDigest;
type Digest;
@ -957,7 +958,7 @@ pub trait TransactionDigest<A: Authorization> {
orchard_bundle: Option<&orchard::Bundle<A::OrchardAuth, Amount>>,
) -> Self::OrchardDigest;
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
fn digest_tze(&self, tze_bundle: Option<&tze::Bundle<A::TzeAuth>>) -> Self::TzeDigest;
fn combine(
@ -966,7 +967,7 @@ pub trait TransactionDigest<A: Authorization> {
transparent_digest: Self::TransparentDigest,
sapling_digest: Self::SaplingDigest,
orchard_digest: Self::OrchardDigest,
#[cfg(feature = "zfuture")] tze_digest: Self::TzeDigest,
#[cfg(zcash_unstable = "zfuture")] tze_digest: Self::TzeDigest,
) -> Self::Digest;
}
@ -989,7 +990,7 @@ pub mod testing {
Authorized, Transaction, TransactionData, TxId, TxVersion,
};
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
use super::components::tze::testing::{self as tze};
pub fn arb_txid() -> impl Strategy<Value = TxId> {
@ -1004,14 +1005,14 @@ pub mod testing {
Just(TxVersion::Sapling).boxed()
}
BranchId::Nu5 => Just(TxVersion::Zip225).boxed(),
#[cfg(feature = "unstable-nu6")]
#[cfg(zcash_unstable = "nu6")]
BranchId::Nu6 => Just(TxVersion::Zip225).boxed(),
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
BranchId::ZFuture => Just(TxVersion::ZFuture).boxed(),
}
}
#[cfg(not(feature = "zfuture"))]
#[cfg(not(zcash_unstable = "zfuture"))]
prop_compose! {
pub fn arb_txdata(consensus_branch_id: BranchId)(
version in arb_tx_version(consensus_branch_id),
@ -1036,7 +1037,7 @@ pub mod testing {
}
}
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
prop_compose! {
pub fn arb_txdata(consensus_branch_id: BranchId)(
version in arb_tx_version(consensus_branch_id),

View File

@ -11,7 +11,7 @@ use crate::{
sapling::{self, bundle::GrothProofBytes},
};
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
use {super::components::Amount, crate::extensions::transparent::Precondition};
pub const SIGHASH_ALL: u8 = 0x01;
@ -29,7 +29,7 @@ pub enum SignableInput<'a> {
script_pubkey: &'a Script,
value: NonNegativeAmount,
},
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
Tze {
index: usize,
precondition: &'a Precondition,
@ -42,7 +42,7 @@ impl<'a> SignableInput<'a> {
match self {
SignableInput::Shielded => SIGHASH_ALL,
SignableInput::Transparent { hash_type, .. } => *hash_type,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
SignableInput::Tze { .. } => SIGHASH_ALL,
}
}
@ -92,7 +92,7 @@ pub fn signature_hash<
TxVersion::Zip225 => v5_signature_hash(tx, signable_input, txid_parts),
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
TxVersion::ZFuture => v5_signature_hash(tx, signable_input, txid_parts),
})
}

View File

@ -255,7 +255,7 @@ pub fn v4_signature_hash<
}
}
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
SignableInput::Tze { .. } => {
panic!("A request has been made to sign a TZE input, but the transaction version is not ZFuture");
}

View File

@ -16,20 +16,18 @@ use crate::transaction::{
Authorization, TransactionData, TransparentDigests, TxDigests,
};
#[cfg(feature = "zfuture")]
use byteorder::WriteBytesExt;
#[cfg(feature = "zfuture")]
use zcash_encoding::{CompactSize, Vector};
#[cfg(feature = "zfuture")]
use crate::transaction::{components::tze, TzeDigests};
#[cfg(zcash_unstable = "zfuture")]
use {
crate::transaction::{components::tze, TzeDigests},
byteorder::WriteBytesExt,
zcash_encoding::{CompactSize, Vector},
};
const ZCASH_TRANSPARENT_INPUT_HASH_PERSONALIZATION: &[u8; 16] = b"Zcash___TxInHash";
const ZCASH_TRANSPARENT_AMOUNTS_HASH_PERSONALIZATION: &[u8; 16] = b"ZTxTrAmountsHash";
const ZCASH_TRANSPARENT_SCRIPTS_HASH_PERSONALIZATION: &[u8; 16] = b"ZTxTrScriptsHash";
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
const ZCASH_TZE_INPUT_HASH_PERSONALIZATION: &[u8; 16] = b"Zcash__TzeInHash";
fn hasher(personal: &[u8; 16]) -> State {
@ -140,7 +138,7 @@ fn transparent_sig_digest<A: TransparentAuthorizingContext>(
}
}
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
fn tze_input_sigdigests<A: tze::Authorization>(
bundle: &tze::Bundle<A>,
input: &SignableInput<'_>,
@ -197,7 +195,7 @@ pub fn v5_signature_hash<
),
txid_parts.sapling_digest,
txid_parts.orchard_digest,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
tx.tze_bundle
.as_ref()
.zip(txid_parts.tze_digests.as_ref())

View File

@ -21,7 +21,7 @@ use super::{
Authorization, Transaction, TransactionData, TxDigests, TxIn,
};
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
use super::components::tze;
#[test]
@ -44,7 +44,7 @@ fn check_roundtrip(tx: Transaction) -> Result<(), TestCaseError> {
let txo = Transaction::read(&txn_bytes[..], tx.consensus_branch_id).unwrap();
prop_assert_eq!(tx.version, txo.version);
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
prop_assert_eq!(tx.tze_bundle.as_ref(), txo.tze_bundle.as_ref());
prop_assert_eq!(tx.lock_time, txo.lock_time);
prop_assert_eq!(
@ -115,7 +115,7 @@ proptest! {
}
}
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
proptest! {
#[test]
#[ignore]
@ -196,7 +196,7 @@ impl Authorization for TestUnauthorized {
type SaplingAuth = sapling::bundle::Authorized;
type OrchardAuth = orchard::bundle::Authorized;
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
type TzeAuth = tze::Authorized;
}
@ -246,7 +246,7 @@ fn zip_0244() {
},
});
#[cfg(not(feature = "zfuture"))]
#[cfg(not(zcash_unstable = "zfuture"))]
let tdata = TransactionData::from_parts(
txdata.version(),
txdata.consensus_branch_id(),
@ -257,7 +257,7 @@ fn zip_0244() {
txdata.sapling_bundle().cloned(),
txdata.orchard_bundle().cloned(),
);
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
let tdata = TransactionData::from_parts_zfuture(
txdata.version(),
txdata.consensus_branch_id(),

View File

@ -23,7 +23,7 @@ use super::{
Authorization, Authorized, TransactionDigest, TransparentDigests, TxDigests, TxId, TxVersion,
};
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
use super::{
components::tze::{self, TzeIn, TzeOut},
TzeDigests,
@ -36,7 +36,7 @@ const ZCASH_TX_PERSONALIZATION_PREFIX: &[u8; 12] = b"ZcashTxHash_";
const ZCASH_HEADERS_HASH_PERSONALIZATION: &[u8; 16] = b"ZTxIdHeadersHash";
pub(crate) const ZCASH_TRANSPARENT_HASH_PERSONALIZATION: &[u8; 16] = b"ZTxIdTranspaHash";
const ZCASH_SAPLING_HASH_PERSONALIZATION: &[u8; 16] = b"ZTxIdSaplingHash";
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
const ZCASH_TZE_HASH_PERSONALIZATION: &[u8; 16] = b"ZTxIdTZE____Hash";
// TxId transparent level 2 node personalization
@ -45,9 +45,9 @@ const ZCASH_SEQUENCE_HASH_PERSONALIZATION: &[u8; 16] = b"ZTxIdSequencHash";
const ZCASH_OUTPUTS_HASH_PERSONALIZATION: &[u8; 16] = b"ZTxIdOutputsHash";
// TxId tze level 2 node personalization
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
const ZCASH_TZE_INPUTS_HASH_PERSONALIZATION: &[u8; 16] = b"ZTxIdTZEIns_Hash";
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
const ZCASH_TZE_OUTPUTS_HASH_PERSONALIZATION: &[u8; 16] = b"ZTxIdTZEOutsHash";
// TxId sapling level 2 node personalization
@ -63,7 +63,7 @@ const ZCASH_SAPLING_OUTPUTS_NONCOMPACT_HASH_PERSONALIZATION: &[u8; 16] = b"ZTxId
const ZCASH_AUTH_PERSONALIZATION_PREFIX: &[u8; 12] = b"ZTxAuthHash_";
const ZCASH_TRANSPARENT_SCRIPTS_HASH_PERSONALIZATION: &[u8; 16] = b"ZTxAuthTransHash";
const ZCASH_SAPLING_SIGS_HASH_PERSONALIZATION: &[u8; 16] = b"ZTxAuthSapliHash";
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
const ZCASH_TZE_WITNESSES_HASH_PERSONALIZATION: &[u8; 16] = b"ZTxAuthTZE__Hash";
fn hasher(personal: &[u8; 16]) -> State {
@ -112,7 +112,7 @@ pub(crate) fn transparent_outputs_hash<T: Borrow<TxOut>>(vout: &[T]) -> Blake2bH
/// witness data, to a hash personalized by ZCASH_TZE_INPUTS_HASH_PERSONALIZATION.
/// In the case that no inputs are provided, this produces a default
/// hash from just the personalization string.
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
pub(crate) fn hash_tze_inputs<A>(tze_inputs: &[TzeIn<A>]) -> Blake2bHash {
let mut h = hasher(ZCASH_TZE_INPUTS_HASH_PERSONALIZATION);
for tzein in tze_inputs {
@ -125,7 +125,7 @@ pub(crate) fn hash_tze_inputs<A>(tze_inputs: &[TzeIn<A>]) -> Blake2bHash {
/// to a hash personalized by ZCASH_TZE_OUTPUTS_HASH_PERSONALIZATION.
/// In the case that no outputs are provided, this produces a default
/// hash from just the personalization string.
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
pub(crate) fn hash_tze_outputs(tze_outputs: &[TzeOut]) -> Blake2bHash {
let mut h = hasher(ZCASH_TZE_OUTPUTS_HASH_PERSONALIZATION);
for tzeout in tze_outputs {
@ -210,7 +210,7 @@ fn transparent_digests<A: transparent::Authorization>(
}
}
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
fn tze_digests<A: tze::Authorization>(bundle: &tze::Bundle<A>) -> TzeDigests<Blake2bHash> {
// The txid commits to the hash for all outputs.
TzeDigests {
@ -276,7 +276,7 @@ fn hash_sapling_txid_empty() -> Blake2bHash {
hasher(ZCASH_SAPLING_HASH_PERSONALIZATION).finalize()
}
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
fn hash_tze_txid_data(tze_digests: Option<&TzeDigests<Blake2bHash>>) -> Blake2bHash {
let mut h = hasher(ZCASH_TZE_HASH_PERSONALIZATION);
if let Some(d) = tze_digests {
@ -304,7 +304,7 @@ impl<A: Authorization> TransactionDigest<A> for TxIdDigester {
type SaplingDigest = Option<Blake2bHash>;
type OrchardDigest = Option<Blake2bHash>;
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
type TzeDigest = Option<TzeDigests<Blake2bHash>>;
type Digest = TxDigests<Blake2bHash>;
@ -340,7 +340,7 @@ impl<A: Authorization> TransactionDigest<A> for TxIdDigester {
orchard_bundle.map(|b| b.commitment().0)
}
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
fn digest_tze(&self, tze_bundle: Option<&tze::Bundle<A::TzeAuth>>) -> Self::TzeDigest {
tze_bundle.map(tze_digests)
}
@ -351,14 +351,14 @@ impl<A: Authorization> TransactionDigest<A> for TxIdDigester {
transparent_digests: Self::TransparentDigest,
sapling_digest: Self::SaplingDigest,
orchard_digest: Self::OrchardDigest,
#[cfg(feature = "zfuture")] tze_digests: Self::TzeDigest,
#[cfg(zcash_unstable = "zfuture")] tze_digests: Self::TzeDigest,
) -> Self::Digest {
TxDigests {
header_digest,
transparent_digests,
sapling_digest,
orchard_digest,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
tze_digests,
}
}
@ -371,7 +371,7 @@ pub(crate) fn to_hash(
transparent_digest: Blake2bHash,
sapling_digest: Option<Blake2bHash>,
orchard_digest: Option<Blake2bHash>,
#[cfg(feature = "zfuture")] tze_digests: Option<&TzeDigests<Blake2bHash>>,
#[cfg(zcash_unstable = "zfuture")] tze_digests: Option<&TzeDigests<Blake2bHash>>,
) -> Blake2bHash {
let mut personal = [0; 16];
personal[..12].copy_from_slice(ZCASH_TX_PERSONALIZATION_PREFIX);
@ -395,7 +395,7 @@ pub(crate) fn to_hash(
)
.unwrap();
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
if _txversion.has_tze() {
h.write_all(hash_tze_txid_data(tze_digests).as_bytes())
.unwrap();
@ -416,7 +416,7 @@ pub fn to_txid(
hash_transparent_txid_data(digests.transparent_digests.as_ref()),
digests.sapling_digest,
digests.orchard_digest,
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
digests.tze_digests.as_ref(),
);
@ -437,7 +437,7 @@ impl TransactionDigest<Authorized> for BlockTxCommitmentDigester {
type SaplingDigest = Blake2bHash;
type OrchardDigest = Blake2bHash;
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
type TzeDigest = Blake2bHash;
type Digest = Blake2bHash;
@ -499,7 +499,7 @@ impl TransactionDigest<Authorized> for BlockTxCommitmentDigester {
})
}
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
fn digest_tze(&self, tze_bundle: Option<&tze::Bundle<tze::Authorized>>) -> Blake2bHash {
let mut h = hasher(ZCASH_TZE_WITNESSES_HASH_PERSONALIZATION);
if let Some(bundle) = tze_bundle {
@ -516,7 +516,7 @@ impl TransactionDigest<Authorized> for BlockTxCommitmentDigester {
transparent_digest: Self::TransparentDigest,
sapling_digest: Self::SaplingDigest,
orchard_digest: Self::OrchardDigest,
#[cfg(feature = "zfuture")] tze_digest: Self::TzeDigest,
#[cfg(zcash_unstable = "zfuture")] tze_digest: Self::TzeDigest,
) -> Self::Digest {
let digests = [transparent_digest, sapling_digest, orchard_digest];
@ -531,7 +531,7 @@ impl TransactionDigest<Authorized> for BlockTxCommitmentDigester {
h.write_all(digest.as_bytes()).unwrap();
}
#[cfg(feature = "zfuture")]
#[cfg(zcash_unstable = "zfuture")]
if TxVersion::suggested_for_branch(consensus_branch_id).has_tze() {
h.write_all(tze_digest.as_bytes()).unwrap();
}