mirror of https://github.com/zcash/orchard.git
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.
This commit is contained in:
parent
3b8d07f7b6
commit
e32a075ef0
|
@ -16,7 +16,7 @@ jobs:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions-rs/toolchain@v1
|
- uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
toolchain: 1.51.0
|
toolchain: 1.56.1
|
||||||
override: true
|
override: true
|
||||||
- name: Run benchmark
|
- name: Run benchmark
|
||||||
run: cargo bench -- --output-format bencher | tee output.txt
|
run: cargo bench -- --output-format bencher | tee output.txt
|
||||||
|
|
|
@ -14,7 +14,7 @@ jobs:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions-rs/toolchain@v1
|
- uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
toolchain: 1.51.0
|
toolchain: 1.56.1
|
||||||
override: true
|
override: true
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
|
@ -30,7 +30,7 @@ jobs:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions-rs/toolchain@v1
|
- uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
toolchain: 1.51.0
|
toolchain: 1.56.1
|
||||||
override: true
|
override: true
|
||||||
# Build benchmarks to prevent bitrot
|
# Build benchmarks to prevent bitrot
|
||||||
- name: Build benchmarks
|
- name: Build benchmarks
|
||||||
|
@ -46,7 +46,7 @@ jobs:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions-rs/toolchain@v1
|
- uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
toolchain: 1.51.0
|
toolchain: 1.56.1
|
||||||
override: true
|
override: true
|
||||||
- name: Setup mdBook
|
- name: Setup mdBook
|
||||||
uses: peaceiris/actions-mdbook@v1
|
uses: peaceiris/actions-mdbook@v1
|
||||||
|
@ -89,7 +89,7 @@ jobs:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions-rs/toolchain@v1
|
- uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
toolchain: 1.51.0
|
toolchain: 1.56.1
|
||||||
override: true
|
override: true
|
||||||
- name: cargo fetch
|
- name: cargo fetch
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
|
@ -112,7 +112,7 @@ jobs:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions-rs/toolchain@v1
|
- uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
toolchain: 1.51.0
|
toolchain: 1.56.1
|
||||||
override: true
|
override: true
|
||||||
- run: rustup component add rustfmt
|
- run: rustup component add rustfmt
|
||||||
- uses: actions-rs/cargo@v1
|
- uses: actions-rs/cargo@v1
|
||||||
|
|
|
@ -5,19 +5,19 @@ on: pull_request
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
clippy:
|
clippy:
|
||||||
name: Clippy (1.51.0)
|
name: Clippy (1.56.1)
|
||||||
timeout-minutes: 30
|
timeout-minutes: 30
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions-rs/toolchain@v1
|
- uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
toolchain: 1.51.0
|
toolchain: 1.56.1
|
||||||
components: clippy
|
components: clippy
|
||||||
override: true
|
override: true
|
||||||
- name: Run Clippy
|
- name: Run Clippy
|
||||||
uses: actions-rs/clippy-check@v1
|
uses: actions-rs/clippy-check@v1
|
||||||
with:
|
with:
|
||||||
name: Clippy (1.51.0)
|
name: Clippy (1.56.1)
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
args: --all-features --all-targets -- -D warnings
|
args: --all-features --all-targets -- -D warnings
|
||||||
|
|
|
@ -7,3 +7,6 @@ and this project adheres to Rust's notion of
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
Initial release!
|
Initial release!
|
||||||
|
|
||||||
|
## [Removed]
|
||||||
|
- The `std::hash::Hash` instance for `MerkleHashOrchard` has been removed.
|
||||||
|
|
|
@ -46,6 +46,9 @@ incrementalmerkletree = "0.2"
|
||||||
# Developer tooling dependencies
|
# Developer tooling dependencies
|
||||||
plotters = { version = "0.3.0", optional = true }
|
plotters = { version = "0.3.0", optional = true }
|
||||||
|
|
||||||
|
[patch.crates-io]
|
||||||
|
incrementalmerkletree = { git = "https://github.com/zcash/incrementalmerkletree.git", rev = "23c0370b5414dc2ddd3305c6821bca5ea6fbf812" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
criterion = "0.3"
|
criterion = "0.3"
|
||||||
hex = "0.4"
|
hex = "0.4"
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
1.51.0
|
1.56.1
|
||||||
|
|
|
@ -672,9 +672,9 @@ pub mod testing {
|
||||||
for note in notes.iter() {
|
for note in notes.iter() {
|
||||||
let leaf = MerkleHashOrchard::from_cmx(¬e.commitment().into());
|
let leaf = MerkleHashOrchard::from_cmx(¬e.commitment().into());
|
||||||
tree.append(&leaf);
|
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));
|
notes_and_auth_paths.push((*note, path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
// Temporary until we have more of the crate implemented.
|
// Temporary until we have more of the crate implemented.
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
// Catch documentation errors caused by code changes.
|
// Catch documentation errors caused by code changes.
|
||||||
#![deny(broken_intra_doc_links)]
|
#![deny(rustdoc::broken_intra_doc_links)]
|
||||||
#![deny(missing_debug_implementations)]
|
#![deny(missing_debug_implementations)]
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
#![deny(unsafe_code)]
|
#![deny(unsafe_code)]
|
||||||
|
|
|
@ -11,7 +11,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A unique nullifier for a note.
|
/// 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);
|
pub struct Nullifier(pub(crate) pallas::Base);
|
||||||
|
|
||||||
impl Nullifier {
|
impl Nullifier {
|
||||||
|
|
32
src/tree.rs
32
src/tree.rs
|
@ -18,7 +18,7 @@ use serde::de::{Deserializer, Error};
|
||||||
use serde::ser::Serializer;
|
use serde::ser::Serializer;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
|
use subtle::{Choice, ConditionallySelectable, CtOption};
|
||||||
|
|
||||||
// The uncommitted leaf is defined as pallas::Base(2).
|
// The uncommitted leaf is defined as pallas::Base(2).
|
||||||
// <https://zips.z.cash/protocol/protocol.pdf#thmuncommittedorchard>
|
// <https://zips.z.cash/protocol/protocol.pdf#thmuncommittedorchard>
|
||||||
|
@ -164,7 +164,7 @@ impl MerklePath {
|
||||||
/// can produce a bottom value which needs to be accounted for in
|
/// can produce a bottom value which needs to be accounted for in
|
||||||
/// the production of a Merkle root. Leaf nodes are always wrapped
|
/// the production of a Merkle root. Leaf nodes are always wrapped
|
||||||
/// with the `Some` constructor.
|
/// with the `Some` constructor.
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub struct MerkleHashOrchard(pallas::Base);
|
pub struct MerkleHashOrchard(pallas::Base);
|
||||||
|
|
||||||
impl MerkleHashOrchard {
|
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<H: std::hash::Hasher>(&self, state: &mut H) {
|
|
||||||
<Option<pallas::Base>>::from(self.0)
|
|
||||||
.map(|b| b.to_bytes())
|
|
||||||
.hash(state)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ConditionallySelectable for MerkleHashOrchard {
|
impl ConditionallySelectable for MerkleHashOrchard {
|
||||||
fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
|
fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
|
||||||
MerkleHashOrchard(pallas::Base::conditional_select(&a.0, &b.0, choice))
|
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();
|
let cmx = MerkleHashOrchard::from_bytes(&tv.leaves[i]).unwrap();
|
||||||
tree.append(&cmx);
|
tree.append(&cmx);
|
||||||
tree.witness();
|
tree.witness().unwrap();
|
||||||
|
|
||||||
assert_eq!(tree.root().0, pallas::Base::from_bytes(&tv.root).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 {
|
for j in 0..=i {
|
||||||
let leaf = MerkleHashOrchard::from_bytes(&tv.leaves[j]).unwrap();
|
let leaf = MerkleHashOrchard::from_bytes(&tv.leaves[j]).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tree.authentication_path(&leaf),
|
tree.authentication_path(j.try_into().unwrap(), &leaf),
|
||||||
Some((
|
Some(
|
||||||
j.try_into().unwrap(),
|
|
||||||
tv.paths[j]
|
tv.paths[j]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|v| MerkleHashOrchard::from_bytes(v).unwrap())
|
.map(|v| MerkleHashOrchard::from_bytes(v).unwrap())
|
||||||
.collect()
|
.collect()
|
||||||
))
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,8 +74,8 @@ fn bundle_chain() {
|
||||||
let leaf = MerkleHashOrchard::from_cmx(&cmx);
|
let leaf = MerkleHashOrchard::from_cmx(&cmx);
|
||||||
let mut tree = BridgeTree::<MerkleHashOrchard, 32>::new(0);
|
let mut tree = BridgeTree::<MerkleHashOrchard, 32>::new(0);
|
||||||
tree.append(&leaf);
|
tree.append(&leaf);
|
||||||
tree.witness();
|
let (position, leaf) = tree.witness().unwrap();
|
||||||
let (position, auth_path) = tree.authentication_path(&leaf).unwrap();
|
let auth_path = tree.authentication_path(position, &leaf).unwrap();
|
||||||
let merkle_path = MerklePath::from_parts(
|
let merkle_path = MerklePath::from_parts(
|
||||||
u64::from(position).try_into().unwrap(),
|
u64::from(position).try_into().unwrap(),
|
||||||
auth_path[..].try_into().unwrap(),
|
auth_path[..].try_into().unwrap(),
|
||||||
|
|
Loading…
Reference in New Issue