From 65f3e6ec3274a5c2fa0c3477adc873c9674498c4 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Mon, 21 Feb 2022 14:41:47 +0000 Subject: [PATCH 1/5] Add `FullViewingKey::derive_internal` This is identical to the changes introduced in zcash/orchard#270, except that the output is non-optional (since the derivation is non-fallible). --- src/keys.rs | 26 +++++++++++++++++++++++++- src/spec/prf_expand.rs | 2 ++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/keys.rs b/src/keys.rs index 8b028edb..66232108 100644 --- a/src/keys.rs +++ b/src/keys.rs @@ -7,7 +7,11 @@ use std::mem; use aes::Aes256; use blake2b_simd::{Hash as Blake2bHash, Params}; use fpe::ff1::{BinaryNumeralString, FF1}; -use group::{ff::Field, prime::PrimeCurveAffine, Curve, GroupEncoding}; +use group::{ + ff::{Field, PrimeField}, + prime::PrimeCurveAffine, + Curve, GroupEncoding, +}; use halo2::arithmetic::FieldExt; use pasta_curves::pallas; use rand::RngCore; @@ -320,6 +324,15 @@ impl FullViewingKey { &self.rivk } + pub(crate) fn rivk_internal(&self) -> CommitIvkRandomness { + let k = self.rivk.0.to_repr(); + let ak = self.ak.to_bytes(); + let nk = self.nk.to_bytes(); + CommitIvkRandomness(to_scalar( + PrfExpand::OrchardRivkInternal.with_ad_slices(&k, &[&ak, &nk]), + )) + } + /// Defined in [Zcash Protocol Spec ยง 4.2.3: Orchard Key Components][orchardkeycomponents]. /// /// [orchardkeycomponents]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents @@ -391,6 +404,17 @@ impl FullViewingKey { Some(FullViewingKey { ak, nk, rivk }) } + + /// Derives an internal full viewing key from a full viewing key, as specified in [ZIP32][orchardinternalfullviewingkey] + /// + /// [orchardinternalfullviewingkey]: https://zips.z.cash/zip-0032#orchard-internal-key-derivation + pub fn derive_internal(&self) -> Self { + FullViewingKey { + ak: self.ak.clone(), + nk: self.nk, + rivk: self.rivk_internal(), + } + } } /// A key that provides the capability to derive a sequence of diversifiers. diff --git a/src/spec/prf_expand.rs b/src/spec/prf_expand.rs index d00c5610..e2f95e7f 100644 --- a/src/spec/prf_expand.rs +++ b/src/spec/prf_expand.rs @@ -12,6 +12,7 @@ pub(crate) enum PrfExpand { Psi, OrchardZip32Child, OrchardDkOvk, + OrchardRivkInternal, } impl PrfExpand { @@ -25,6 +26,7 @@ impl PrfExpand { Self::Psi => 0x09, Self::OrchardZip32Child => 0x81, Self::OrchardDkOvk => 0x82, + Self::OrchardRivkInternal => 0x83, } } From 1cf828fe7b1bbf239fba856889274e4caa704139 Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Wed, 23 Feb 2022 18:29:07 -0700 Subject: [PATCH 2/5] Update the incremental merkle tree version and the Rust toolchain. Use derived equality and ordering (which delegate to constant-time versions) for note::nullifier::Nullifier and tree::MerkleHashOrchard so that these types can be used as map keys in wallets. --- .github/workflows/bench.yml | 2 +- .github/workflows/ci.yml | 10 +++++----- .github/workflows/lints-stable.yml | 6 +++--- CHANGELOG.md | 3 +++ Cargo.toml | 3 +++ rust-toolchain | 2 +- src/builder.rs | 4 ++-- src/lib.rs | 2 +- src/note/nullifier.rs | 2 +- src/tree.rs | 32 ++++++------------------------ tests/builder.rs | 4 ++-- 11 files changed, 28 insertions(+), 42 deletions(-) diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index 4830b3e4..e8e26384 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - toolchain: 1.51.0 + toolchain: 1.56.1 override: true - name: Run benchmark run: cargo bench -- --output-format bencher | tee output.txt diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9c9d7a47..966cc8da 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - toolchain: 1.51.0 + toolchain: 1.56.1 override: true - name: Run tests uses: actions-rs/cargo@v1 @@ -30,7 +30,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - toolchain: 1.51.0 + toolchain: 1.56.1 override: true # Build benchmarks to prevent bitrot - name: Build benchmarks @@ -46,7 +46,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - toolchain: 1.51.0 + toolchain: 1.56.1 override: true - name: Setup mdBook uses: peaceiris/actions-mdbook@v1 @@ -89,7 +89,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - toolchain: 1.51.0 + toolchain: 1.56.1 override: true - name: cargo fetch uses: actions-rs/cargo@v1 @@ -112,7 +112,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - toolchain: 1.51.0 + toolchain: 1.56.1 override: true - run: rustup component add rustfmt - uses: actions-rs/cargo@v1 diff --git a/.github/workflows/lints-stable.yml b/.github/workflows/lints-stable.yml index d9d6c3e6..242041e8 100644 --- a/.github/workflows/lints-stable.yml +++ b/.github/workflows/lints-stable.yml @@ -5,19 +5,19 @@ on: pull_request jobs: clippy: - name: Clippy (1.51.0) + name: Clippy (1.56.1) timeout-minutes: 30 runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - toolchain: 1.51.0 + toolchain: 1.56.1 components: clippy override: true - name: Run Clippy uses: actions-rs/clippy-check@v1 with: - name: Clippy (1.51.0) + name: Clippy (1.56.1) token: ${{ secrets.GITHUB_TOKEN }} args: --all-features --all-targets -- -D warnings diff --git a/CHANGELOG.md b/CHANGELOG.md index bafd9c53..03a94302 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,3 +7,6 @@ and this project adheres to Rust's notion of ## [Unreleased] Initial release! + +## [Removed] +- The `std::hash::Hash` instance for `MerkleHashOrchard` has been removed. diff --git a/Cargo.toml b/Cargo.toml index ac0265c7..a9a7a26d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,6 +46,9 @@ incrementalmerkletree = "0.2" # Developer tooling dependencies plotters = { version = "0.3.0", optional = true } +[patch.crates-io] +incrementalmerkletree = { git = "https://github.com/zcash/incrementalmerkletree.git", rev = "ec530f7ca6234abde4e43e96f0083643c75264e4" } + [dev-dependencies] criterion = "0.3" hex = "0.4" diff --git a/rust-toolchain b/rust-toolchain index ba0a7191..43c989b5 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -1.51.0 +1.56.1 diff --git a/src/builder.rs b/src/builder.rs index c5752ed8..c46c5481 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -672,9 +672,9 @@ pub mod testing { for note in notes.iter() { let leaf = MerkleHashOrchard::from_cmx(¬e.commitment().into()); tree.append(&leaf); - tree.witness(); + let (position, leaf) = tree.witness().unwrap(); - let path = tree.authentication_path(&leaf).unwrap().into(); + let path = MerklePath::from((position, tree.authentication_path(position, &leaf).unwrap())); notes_and_auth_paths.push((*note, path)); } diff --git a/src/lib.rs b/src/lib.rs index d0078466..b3579899 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,7 +11,7 @@ // Temporary until we have more of the crate implemented. #![allow(dead_code)] // Catch documentation errors caused by code changes. -#![deny(broken_intra_doc_links)] +#![deny(rustdoc::broken_intra_doc_links)] #![deny(missing_debug_implementations)] #![deny(missing_docs)] #![deny(unsafe_code)] diff --git a/src/note/nullifier.rs b/src/note/nullifier.rs index a0ede6fb..800a0c74 100644 --- a/src/note/nullifier.rs +++ b/src/note/nullifier.rs @@ -11,7 +11,7 @@ use crate::{ }; /// A unique nullifier for a note. -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] pub struct Nullifier(pub(crate) pallas::Base); impl Nullifier { diff --git a/src/tree.rs b/src/tree.rs index 754ccf27..73431b68 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -18,7 +18,7 @@ use serde::de::{Deserializer, Error}; use serde::ser::Serializer; use serde::{Deserialize, Serialize}; use std::iter; -use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; +use subtle::{Choice, ConditionallySelectable, CtOption}; // The uncommitted leaf is defined as pallas::Base(2). // @@ -164,7 +164,7 @@ impl MerklePath { /// can produce a bottom value which needs to be accounted for in /// the production of a Merkle root. Leaf nodes are always wrapped /// with the `Some` constructor. -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub struct MerkleHashOrchard(pallas::Base); impl MerkleHashOrchard { @@ -194,25 +194,6 @@ impl MerkleHashOrchard { } } -/// This instance should only be used for hash table key comparisons. -impl std::cmp::PartialEq for MerkleHashOrchard { - fn eq(&self, other: &Self) -> bool { - self.0.ct_eq(&other.0).into() - } -} - -/// This instance should only be used for hash table key comparisons. -impl std::cmp::Eq for MerkleHashOrchard {} - -/// This instance should only be used for hash table key hashing. -impl std::hash::Hash for MerkleHashOrchard { - fn hash(&self, state: &mut H) { - >::from(self.0) - .map(|b| b.to_bytes()) - .hash(state) - } -} - impl ConditionallySelectable for MerkleHashOrchard { fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { MerkleHashOrchard(pallas::Base::conditional_select(&a.0, &b.0, choice)) @@ -304,7 +285,7 @@ pub mod testing { { let cmx = MerkleHashOrchard::from_bytes(&tv.leaves[i]).unwrap(); tree.append(&cmx); - tree.witness(); + tree.witness().unwrap(); assert_eq!(tree.root().0, pallas::Base::from_bytes(&tv.root).unwrap()); @@ -314,14 +295,13 @@ pub mod testing { for j in 0..=i { let leaf = MerkleHashOrchard::from_bytes(&tv.leaves[j]).unwrap(); assert_eq!( - tree.authentication_path(&leaf), - Some(( - j.try_into().unwrap(), + tree.authentication_path(j.try_into().unwrap(), &leaf), + Some( tv.paths[j] .iter() .map(|v| MerkleHashOrchard::from_bytes(v).unwrap()) .collect() - )) + ) ); } } diff --git a/tests/builder.rs b/tests/builder.rs index 0c375da7..5c2d1f56 100644 --- a/tests/builder.rs +++ b/tests/builder.rs @@ -74,8 +74,8 @@ fn bundle_chain() { let leaf = MerkleHashOrchard::from_cmx(&cmx); let mut tree = BridgeTree::::new(0); tree.append(&leaf); - tree.witness(); - let (position, auth_path) = tree.authentication_path(&leaf).unwrap(); + let (position, leaf) = tree.witness().unwrap(); + let auth_path = tree.authentication_path(position, &leaf).unwrap(); let merkle_path = MerklePath::from_parts( u64::from(position).try_into().unwrap(), auth_path[..].try_into().unwrap(), From e32a075ef0af627632734a55828b74efcdf1065a Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Wed, 23 Feb 2022 18:29:07 -0700 Subject: [PATCH 3/5] Update the incremental merkle tree version and the Rust toolchain. Use derived equality and ordering (which delegate to constant-time versions) for note::nullifier::Nullifier and tree::MerkleHashOrchard so that these types can be used as map keys in wallets. --- .github/workflows/bench.yml | 2 +- .github/workflows/ci.yml | 10 +++++----- .github/workflows/lints-stable.yml | 6 +++--- CHANGELOG.md | 3 +++ Cargo.toml | 3 +++ rust-toolchain | 2 +- src/builder.rs | 4 ++-- src/lib.rs | 2 +- src/note/nullifier.rs | 2 +- src/tree.rs | 32 ++++++------------------------ tests/builder.rs | 4 ++-- 11 files changed, 28 insertions(+), 42 deletions(-) diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index 4830b3e4..e8e26384 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - toolchain: 1.51.0 + toolchain: 1.56.1 override: true - name: Run benchmark run: cargo bench -- --output-format bencher | tee output.txt diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9c9d7a47..966cc8da 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - toolchain: 1.51.0 + toolchain: 1.56.1 override: true - name: Run tests uses: actions-rs/cargo@v1 @@ -30,7 +30,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - toolchain: 1.51.0 + toolchain: 1.56.1 override: true # Build benchmarks to prevent bitrot - name: Build benchmarks @@ -46,7 +46,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - toolchain: 1.51.0 + toolchain: 1.56.1 override: true - name: Setup mdBook uses: peaceiris/actions-mdbook@v1 @@ -89,7 +89,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - toolchain: 1.51.0 + toolchain: 1.56.1 override: true - name: cargo fetch uses: actions-rs/cargo@v1 @@ -112,7 +112,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - toolchain: 1.51.0 + toolchain: 1.56.1 override: true - run: rustup component add rustfmt - uses: actions-rs/cargo@v1 diff --git a/.github/workflows/lints-stable.yml b/.github/workflows/lints-stable.yml index d9d6c3e6..242041e8 100644 --- a/.github/workflows/lints-stable.yml +++ b/.github/workflows/lints-stable.yml @@ -5,19 +5,19 @@ on: pull_request jobs: clippy: - name: Clippy (1.51.0) + name: Clippy (1.56.1) timeout-minutes: 30 runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - toolchain: 1.51.0 + toolchain: 1.56.1 components: clippy override: true - name: Run Clippy uses: actions-rs/clippy-check@v1 with: - name: Clippy (1.51.0) + name: Clippy (1.56.1) token: ${{ secrets.GITHUB_TOKEN }} args: --all-features --all-targets -- -D warnings diff --git a/CHANGELOG.md b/CHANGELOG.md index bafd9c53..03a94302 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,3 +7,6 @@ and this project adheres to Rust's notion of ## [Unreleased] Initial release! + +## [Removed] +- The `std::hash::Hash` instance for `MerkleHashOrchard` has been removed. diff --git a/Cargo.toml b/Cargo.toml index ac0265c7..b3f10ab6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,6 +46,9 @@ incrementalmerkletree = "0.2" # Developer tooling dependencies plotters = { version = "0.3.0", optional = true } +[patch.crates-io] +incrementalmerkletree = { git = "https://github.com/zcash/incrementalmerkletree.git", rev = "23c0370b5414dc2ddd3305c6821bca5ea6fbf812" } + [dev-dependencies] criterion = "0.3" hex = "0.4" diff --git a/rust-toolchain b/rust-toolchain index ba0a7191..43c989b5 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -1.51.0 +1.56.1 diff --git a/src/builder.rs b/src/builder.rs index c5752ed8..c46c5481 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -672,9 +672,9 @@ pub mod testing { for note in notes.iter() { let leaf = MerkleHashOrchard::from_cmx(¬e.commitment().into()); tree.append(&leaf); - tree.witness(); + let (position, leaf) = tree.witness().unwrap(); - let path = tree.authentication_path(&leaf).unwrap().into(); + let path = MerklePath::from((position, tree.authentication_path(position, &leaf).unwrap())); notes_and_auth_paths.push((*note, path)); } diff --git a/src/lib.rs b/src/lib.rs index d0078466..b3579899 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,7 +11,7 @@ // Temporary until we have more of the crate implemented. #![allow(dead_code)] // Catch documentation errors caused by code changes. -#![deny(broken_intra_doc_links)] +#![deny(rustdoc::broken_intra_doc_links)] #![deny(missing_debug_implementations)] #![deny(missing_docs)] #![deny(unsafe_code)] diff --git a/src/note/nullifier.rs b/src/note/nullifier.rs index a0ede6fb..800a0c74 100644 --- a/src/note/nullifier.rs +++ b/src/note/nullifier.rs @@ -11,7 +11,7 @@ use crate::{ }; /// A unique nullifier for a note. -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] pub struct Nullifier(pub(crate) pallas::Base); impl Nullifier { diff --git a/src/tree.rs b/src/tree.rs index 754ccf27..73431b68 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -18,7 +18,7 @@ use serde::de::{Deserializer, Error}; use serde::ser::Serializer; use serde::{Deserialize, Serialize}; use std::iter; -use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; +use subtle::{Choice, ConditionallySelectable, CtOption}; // The uncommitted leaf is defined as pallas::Base(2). // @@ -164,7 +164,7 @@ impl MerklePath { /// can produce a bottom value which needs to be accounted for in /// the production of a Merkle root. Leaf nodes are always wrapped /// with the `Some` constructor. -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub struct MerkleHashOrchard(pallas::Base); impl MerkleHashOrchard { @@ -194,25 +194,6 @@ impl MerkleHashOrchard { } } -/// This instance should only be used for hash table key comparisons. -impl std::cmp::PartialEq for MerkleHashOrchard { - fn eq(&self, other: &Self) -> bool { - self.0.ct_eq(&other.0).into() - } -} - -/// This instance should only be used for hash table key comparisons. -impl std::cmp::Eq for MerkleHashOrchard {} - -/// This instance should only be used for hash table key hashing. -impl std::hash::Hash for MerkleHashOrchard { - fn hash(&self, state: &mut H) { - >::from(self.0) - .map(|b| b.to_bytes()) - .hash(state) - } -} - impl ConditionallySelectable for MerkleHashOrchard { fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { MerkleHashOrchard(pallas::Base::conditional_select(&a.0, &b.0, choice)) @@ -304,7 +285,7 @@ pub mod testing { { let cmx = MerkleHashOrchard::from_bytes(&tv.leaves[i]).unwrap(); tree.append(&cmx); - tree.witness(); + tree.witness().unwrap(); assert_eq!(tree.root().0, pallas::Base::from_bytes(&tv.root).unwrap()); @@ -314,14 +295,13 @@ pub mod testing { for j in 0..=i { let leaf = MerkleHashOrchard::from_bytes(&tv.leaves[j]).unwrap(); assert_eq!( - tree.authentication_path(&leaf), - Some(( - j.try_into().unwrap(), + tree.authentication_path(j.try_into().unwrap(), &leaf), + Some( tv.paths[j] .iter() .map(|v| MerkleHashOrchard::from_bytes(v).unwrap()) .collect() - )) + ) ); } } diff --git a/tests/builder.rs b/tests/builder.rs index 0c375da7..5c2d1f56 100644 --- a/tests/builder.rs +++ b/tests/builder.rs @@ -74,8 +74,8 @@ fn bundle_chain() { let leaf = MerkleHashOrchard::from_cmx(&cmx); let mut tree = BridgeTree::::new(0); tree.append(&leaf); - tree.witness(); - let (position, auth_path) = tree.authentication_path(&leaf).unwrap(); + let (position, leaf) = tree.witness().unwrap(); + let auth_path = tree.authentication_path(position, &leaf).unwrap(); let merkle_path = MerklePath::from_parts( u64::from(position).try_into().unwrap(), auth_path[..].try_into().unwrap(), From 273662c00bdde33d7a92b7964ec8cb59c9d02e0b Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Thu, 24 Feb 2022 09:16:39 -0700 Subject: [PATCH 4/5] Apply suggestions from code review Co-authored-by: str4d --- CHANGELOG.md | 2 +- src/builder.rs | 4 ++-- src/tree.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 03a94302..12fcae4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,4 +9,4 @@ and this project adheres to Rust's notion of Initial release! ## [Removed] -- The `std::hash::Hash` instance for `MerkleHashOrchard` has been removed. +- `impl std::hash::Hash for MerkleHashOrchard` (use `BTreeMap` instead of `HashMap`). diff --git a/src/builder.rs b/src/builder.rs index c46c5481..1f6257c2 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -672,9 +672,9 @@ pub mod testing { for note in notes.iter() { let leaf = MerkleHashOrchard::from_cmx(¬e.commitment().into()); tree.append(&leaf); - let (position, leaf) = tree.witness().unwrap(); + let (position, leaf) = tree.witness().expect("tree is not empty"); - let path = MerklePath::from((position, tree.authentication_path(position, &leaf).unwrap())); + let path = MerklePath::from((position, tree.authentication_path(position, &leaf).expect("we just witnessed the path"))); notes_and_auth_paths.push((*note, path)); } diff --git a/src/tree.rs b/src/tree.rs index 73431b68..d0a5f962 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -285,7 +285,7 @@ pub mod testing { { let cmx = MerkleHashOrchard::from_bytes(&tv.leaves[i]).unwrap(); tree.append(&cmx); - tree.witness().unwrap(); + tree.witness().expect("tree is not empty"); assert_eq!(tree.root().0, pallas::Base::from_bytes(&tv.root).unwrap()); From def4d4d9ae9027a220b270c7c0720b3864956cc1 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Mon, 28 Feb 2022 20:01:21 +0000 Subject: [PATCH 5/5] Add missing `Debug` trait bounds for `Builder` components All relevant types have `Debug` impls, but some of the trait and method impls were lacking `Debug` bounds on their generic types. This prevented `Debug` impls being used on the overall partially-constructed `Bundle` types. --- src/builder.rs | 11 ++++++----- src/bundle.rs | 5 +++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 1f6257c2..8b5f50f2 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1,6 +1,7 @@ //! Logic for building Orchard components of transactions. use std::convert::TryFrom; +use std::fmt; use std::iter; use ff::Field; @@ -361,9 +362,9 @@ impl Builder { } /// Marker trait representing bundle signatures in the process of being created. -pub trait InProgressSignatures { +pub trait InProgressSignatures: fmt::Debug { /// The authorization type of an Orchard action in the process of being authorized. - type SpendAuth; + type SpendAuth: fmt::Debug; } /// Marker for a bundle in the process of being built. @@ -373,7 +374,7 @@ pub struct InProgress { sigs: S, } -impl Authorization for InProgress { +impl Authorization for InProgress { type SpendAuth = S::SpendAuth; } @@ -481,7 +482,7 @@ impl MaybeSigned { } } -impl Bundle, V> { +impl Bundle, V> { /// Loads the sighash into this bundle, preparing it for signing. /// /// This API ensures that all signatures are created over the same sighash. @@ -527,7 +528,7 @@ impl Bundle, V> { } } -impl Bundle, V> { +impl Bundle, V> { /// Signs this bundle with the given [`SpendAuthorizingKey`]. /// /// This will apply signatures for all notes controlled by this spending key. diff --git a/src/bundle.rs b/src/bundle.rs index 2df9d239..57f91f09 100644 --- a/src/bundle.rs +++ b/src/bundle.rs @@ -3,6 +3,7 @@ pub mod commitments; use std::convert::TryInto; +use std::fmt; use std::io; use blake2b_simd::Hash as Blake2bHash; @@ -230,9 +231,9 @@ impl Flags { } /// Defines the authorization type of an Orchard bundle. -pub trait Authorization { +pub trait Authorization: fmt::Debug { /// The authorization type of an Orchard action. - type SpendAuth; + type SpendAuth: fmt::Debug; } /// A bundle of actions to be applied to the ledger.