Merge pull request #1251 from zcash/ci-rework

CI: Rework the test states
This commit is contained in:
Kris Nuttycombe 2024-03-10 13:49:12 -06:00 committed by GitHub
commit 654f116a0a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
27 changed files with 270 additions and 203 deletions

View File

@ -8,27 +8,40 @@ on:
jobs: jobs:
test: test:
name: > name: >
Test on ${{ matrix.os }}${{ Test${{
matrix.extra_flags != 'NOT_A_PUZZLE' && format(' with --features {0}', matrix.extra_flags) || '' matrix.state != 'NOT_A_PUZZLE' && format(' {0}', matrix.state) || ''
}} }} on ${{ matrix.target }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.extra_flags != 'NOT_A_PUZZLE' }} continue-on-error: ${{ matrix.state != 'NOT_A_PUZZLE' }}
strategy: strategy:
matrix: matrix:
os: [ubuntu-latest-8cores, windows-latest-8cores, macOS-latest] target:
extra_flags: - Linux
- macOS
- Windows
state:
- NOT_A_PUZZLE - NOT_A_PUZZLE
- orchard - Orchard
- unstable-nu6 - NU6
- zfuture
include: include:
- extra_flags: orchard - target: Linux
os: ubuntu-latest-8cores
- target: macOS
os: macOS-latest
- target: Windows
os: windows-latest-8cores
- state: Orchard
extra_flags: orchard
rustflags: '--cfg zcash_unstable="orchard"' rustflags: '--cfg zcash_unstable="orchard"'
- state: NU6
rustflags: '--cfg zcash_unstable="nu6"'
exclude: exclude:
- os: macOS-latest - target: macOS
extra_flags: unstable-nu6 state: NU6
- os: macOS-latest
extra_flags: zfuture
env: env:
RUSTFLAGS: ${{ matrix.rustflags }} RUSTFLAGS: ${{ matrix.rustflags }}
RUSTDOCFLAGS: ${{ matrix.rustflags }} RUSTDOCFLAGS: ${{ matrix.rustflags }}
@ -38,7 +51,7 @@ jobs:
- id: prepare - id: prepare
uses: ./.github/actions/prepare uses: ./.github/actions/prepare
with: with:
extra-features: ${{ matrix.extra_flags != 'NOT_A_PUZZLE' && matrix.extra_flags || '' }} extra-features: ${{ matrix.state != 'NOT_A_PUZZLE' && matrix.extra_flags || '' }}
- uses: actions/cache@v4 - uses: actions/cache@v4
with: with:
path: | path: |
@ -64,6 +77,63 @@ jobs:
- name: Verify working directory is clean - name: Verify working directory is clean
run: git diff --exit-code run: git diff --exit-code
# States that we want to ensure can be built, but that we don't actively run tests for.
check-msrv:
name: >
Check${{
matrix.state != 'NOT_A_PUZZLE' && format(' {0}', matrix.state) || ''
}} build on ${{ matrix.target }}
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.state != 'NOT_A_PUZZLE' }}
strategy:
matrix:
target:
- Linux
- macOS
- Windows
state:
- ZFuture
include:
- target: Linux
os: ubuntu-latest
- target: macOS
os: macOS-latest
- target: Windows
os: windows-latest
- state: ZFuture
rustflags: '--cfg zcash_unstable="zfuture"'
env:
RUSTFLAGS: ${{ matrix.rustflags }}
RUSTDOCFLAGS: ${{ matrix.rustflags }}
steps:
- uses: actions/checkout@v4
- id: prepare
uses: ./.github/actions/prepare
with:
extra-features: ${{ matrix.state != 'NOT_A_PUZZLE' && matrix.extra_flags || '' }}
- uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-msrv-${{ hashFiles('**/Cargo.lock') }}
- name: Run check
run: >
cargo check
--release
--workspace
--tests
${{ steps.prepare.outputs.feature-flags }}
- name: Verify working directory is clean
run: git diff --exit-code
build-latest: build-latest:
name: Latest build on ${{ matrix.os }} name: Latest build on ${{ matrix.os }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}

15
Cargo.lock generated
View File

@ -3102,6 +3102,21 @@ dependencies = [
"nonempty", "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]] [[package]]
name = "zcash_history" name = "zcash_history"
version = "0.4.0" version = "0.4.0"

View File

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

View File

@ -11,6 +11,11 @@ and this library adheres to Rust's notion of
- `zcash_protocol::memo`: - `zcash_protocol::memo`:
- `impl TryFrom<&MemoBytes> for 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 ## [0.1.0] - 2024-03-06
The entries below are relative to the `zcash_primitives` crate as of the tag The entries below are relative to the `zcash_primitives` crate as of the tag
`zcash_primitives-0.14.0`. `zcash_primitives-0.14.0`.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -3,5 +3,10 @@
// Catch documentation errors caused by code changes. // Catch documentation errors caused by code changes.
#![deny(rustdoc::broken_intra_doc_links)] #![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; pub mod consensus;
#[cfg(zcash_unstable = "zfuture")]
pub mod transparent; pub mod transparent;

View File

@ -513,7 +513,7 @@ mod tests {
NetworkUpgrade::Heartwood => Some(BlockHeight::from_u32(903_800)), NetworkUpgrade::Heartwood => Some(BlockHeight::from_u32(903_800)),
NetworkUpgrade::Canopy => Some(BlockHeight::from_u32(1_028_500)), NetworkUpgrade::Canopy => Some(BlockHeight::from_u32(1_028_500)),
NetworkUpgrade::Nu5 => Some(BlockHeight::from_u32(1_200_000)), 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::Nu6 => Some(BlockHeight::from_u32(1_300_000)),
NetworkUpgrade::ZFuture => Some(BlockHeight::from_u32(1_400_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` - `impl From<NonNegativeAmount> for orchard::NoteValue`
- The `local_consensus` module and feature flag have been removed; use the module - The `local_consensus` module and feature flag have been removed; use the module
from the `zcash_protocol` crate instead. 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 ## [0.14.0] - 2024-03-01
### Added ### Added

View File

@ -123,16 +123,6 @@ test-dependencies = [
"zcash_protocol/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] [lib]
bench = false bench = false

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -9,7 +9,7 @@ pub mod fixed;
pub mod transparent; pub mod transparent;
pub mod zip317; pub mod zip317;
#[cfg(feature = "zfuture")] #[cfg(zcash_unstable = "zfuture")]
pub mod tze; pub mod tze;
/// A trait that represents the ability to compute the fees that must be paid /// 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 /// 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. /// 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 { pub trait FutureFeeRule: FeeRule {
/// Computes the total fee required for a transaction given the provided inputs and outputs. /// 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}, transaction::fees::{transparent, zip317},
}; };
#[cfg(feature = "zfuture")] #[cfg(zcash_unstable = "zfuture")]
use crate::transaction::fees::tze; use crate::transaction::fees::tze;
/// A fee rule that always returns a fixed fee, irrespective of the structure of /// 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 { impl super::FutureFeeRule for FeeRule {
fn fee_required_zfuture<P: consensus::Parameters>( fn fee_required_zfuture<P: consensus::Parameters>(
&self, &self,

View File

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

View File

@ -11,7 +11,7 @@ use crate::{
sapling::{self, bundle::GrothProofBytes}, sapling::{self, bundle::GrothProofBytes},
}; };
#[cfg(feature = "zfuture")] #[cfg(zcash_unstable = "zfuture")]
use {super::components::Amount, crate::extensions::transparent::Precondition}; use {super::components::Amount, crate::extensions::transparent::Precondition};
pub const SIGHASH_ALL: u8 = 0x01; pub const SIGHASH_ALL: u8 = 0x01;
@ -29,7 +29,7 @@ pub enum SignableInput<'a> {
script_pubkey: &'a Script, script_pubkey: &'a Script,
value: NonNegativeAmount, value: NonNegativeAmount,
}, },
#[cfg(feature = "zfuture")] #[cfg(zcash_unstable = "zfuture")]
Tze { Tze {
index: usize, index: usize,
precondition: &'a Precondition, precondition: &'a Precondition,
@ -42,7 +42,7 @@ impl<'a> SignableInput<'a> {
match self { match self {
SignableInput::Shielded => SIGHASH_ALL, SignableInput::Shielded => SIGHASH_ALL,
SignableInput::Transparent { hash_type, .. } => *hash_type, SignableInput::Transparent { hash_type, .. } => *hash_type,
#[cfg(feature = "zfuture")] #[cfg(zcash_unstable = "zfuture")]
SignableInput::Tze { .. } => SIGHASH_ALL, SignableInput::Tze { .. } => SIGHASH_ALL,
} }
} }
@ -92,7 +92,7 @@ pub fn signature_hash<
TxVersion::Zip225 => v5_signature_hash(tx, signable_input, txid_parts), 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), 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 { .. } => { SignableInput::Tze { .. } => {
panic!("A request has been made to sign a TZE input, but the transaction version is not ZFuture"); 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, Authorization, TransactionData, TransparentDigests, TxDigests,
}; };
#[cfg(feature = "zfuture")] #[cfg(zcash_unstable = "zfuture")]
use byteorder::WriteBytesExt; use {
crate::transaction::{components::tze, TzeDigests},
#[cfg(feature = "zfuture")] byteorder::WriteBytesExt,
use zcash_encoding::{CompactSize, Vector}; zcash_encoding::{CompactSize, Vector},
};
#[cfg(feature = "zfuture")]
use crate::transaction::{components::tze, TzeDigests};
const ZCASH_TRANSPARENT_INPUT_HASH_PERSONALIZATION: &[u8; 16] = b"Zcash___TxInHash"; const ZCASH_TRANSPARENT_INPUT_HASH_PERSONALIZATION: &[u8; 16] = b"Zcash___TxInHash";
const ZCASH_TRANSPARENT_AMOUNTS_HASH_PERSONALIZATION: &[u8; 16] = b"ZTxTrAmountsHash"; const ZCASH_TRANSPARENT_AMOUNTS_HASH_PERSONALIZATION: &[u8; 16] = b"ZTxTrAmountsHash";
const ZCASH_TRANSPARENT_SCRIPTS_HASH_PERSONALIZATION: &[u8; 16] = b"ZTxTrScriptsHash"; 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"; const ZCASH_TZE_INPUT_HASH_PERSONALIZATION: &[u8; 16] = b"Zcash__TzeInHash";
fn hasher(personal: &[u8; 16]) -> State { 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>( fn tze_input_sigdigests<A: tze::Authorization>(
bundle: &tze::Bundle<A>, bundle: &tze::Bundle<A>,
input: &SignableInput<'_>, input: &SignableInput<'_>,
@ -197,7 +195,7 @@ pub fn v5_signature_hash<
), ),
txid_parts.sapling_digest, txid_parts.sapling_digest,
txid_parts.orchard_digest, txid_parts.orchard_digest,
#[cfg(feature = "zfuture")] #[cfg(zcash_unstable = "zfuture")]
tx.tze_bundle tx.tze_bundle
.as_ref() .as_ref()
.zip(txid_parts.tze_digests.as_ref()) .zip(txid_parts.tze_digests.as_ref())

View File

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

View File

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