Skip to content

Commit

Permalink
Allow no_std use of incrementalmerkletree
Browse files Browse the repository at this point in the history
  • Loading branch information
nuttycom committed Dec 16, 2024
1 parent d663a8f commit 676d9f7
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 23 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions incrementalmerkletree/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ and this project adheres to Rust's notion of

## Unreleased

### Added
- `no-std` support, via a default-enabled `std` feature flag.

## [0.7.0] - 2024-09-25

### Changed
Expand Down
6 changes: 4 additions & 2 deletions incrementalmerkletree/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ all-features = true
rustdoc-args = ["--cfg", "docsrs"]

[dependencies]
either = "1.8"
either = { version = "1.13", default-features = false }
proptest = { workspace = true, optional = true }
rand = { version = "0.8", optional = true }
rand_core = { version = "0.6", optional = true }
Expand All @@ -30,10 +30,12 @@ rand_core = "0.6"
rand_chacha = "0.3"

[features]
default = ["std"]
std = []
# The legacy-api feature guards types and functions that were previously
# part of the `zcash_primitives` crate. Those types were removed in the
# `zcash_primitives` 0.12 release and are now maintained here.
legacy-api = []
# The test-dependencies feature guards types and functions that are
# useful for testing incremental Merkle trees and Merkle tree frontiers.
test-dependencies = ["dep:proptest", "dep:rand", "dep:rand_core"]
test-dependencies = ["dep:proptest", "dep:rand", "dep:rand_core", "std"]
18 changes: 10 additions & 8 deletions incrementalmerkletree/src/frontier.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
use std::mem::size_of;
use alloc::vec::Vec;
use core::mem::size_of;

use crate::{Address, Hashable, Level, MerklePath, Position, Source};

#[cfg(feature = "legacy-api")]
use {std::collections::VecDeque, std::iter::repeat};
use {alloc::collections::VecDeque, core::iter::repeat};

#[cfg(any(test, feature = "test-dependencies"))]
use {
core::num::{NonZeroU64, NonZeroU8},
rand::{
distributions::{Distribution, Standard},
Rng, RngCore,
},
std::num::{NonZeroU64, NonZeroU8},
};

/// Validation errors that can occur during reconstruction of a Merkle frontier from
Expand Down Expand Up @@ -195,7 +196,7 @@ where
NonEmptyFrontier::from_parts(
position,
rng.gen(),
std::iter::repeat_with(|| rng.gen())
core::iter::repeat_with(|| rng.gen())
.take(position.past_ommer_count().into())
.collect(),
)
Expand All @@ -209,7 +210,7 @@ where
) -> (Vec<H>, Self) {
let prior_subtree_count: u64 = u64::from(tree_size) >> u8::from(subtree_depth);
if prior_subtree_count > 0 {
let prior_roots: Vec<H> = std::iter::repeat_with(|| rng.gen())
let prior_roots: Vec<H> = core::iter::repeat_with(|| rng.gen())
.take(prior_subtree_count as usize)
.collect();

Expand Down Expand Up @@ -673,12 +674,13 @@ impl<H: Hashable + Clone, const DEPTH: u8> CommitmentTree<H, DEPTH> {
}
}

#[cfg(any(test, feature = "test-dependencies"))]
#[cfg(any(all(test, feature = "std"), feature = "test-dependencies"))]
pub mod testing {
use core::fmt::Debug;
use proptest::collection::vec;
use proptest::prelude::*;
use rand::{distributions::Standard, prelude::Distribution};

use std::collections::hash_map::DefaultHasher;
use std::hash::Hasher;

Expand Down Expand Up @@ -762,9 +764,9 @@ pub mod testing {
}
}

#[cfg(test)]
#[cfg(all(test, feature = "std"))]
mod tests {

use alloc::string::{String, ToString};
use rand::SeedableRng;
use rand_chacha::ChaChaRng;

Expand Down
28 changes: 19 additions & 9 deletions incrementalmerkletree/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,21 @@
//! context `ommers` refers to the node's ommer, plus each ancestor's ommer.
#![cfg_attr(docsrs, feature(doc_cfg))]
#![no_std]

#[cfg(feature = "std")]
extern crate std;

#[macro_use]
extern crate alloc;
use alloc::vec::Vec;

use core::cmp::Ordering;
use core::convert::{TryFrom, TryInto};
use core::fmt;
use core::num::TryFromIntError;
use core::ops::{Add, AddAssign, Range, Sub};
use either::Either;
use std::cmp::Ordering;
use std::convert::{TryFrom, TryInto};
use std::fmt;
use std::num::TryFromIntError;
use std::ops::{Add, AddAssign, Range, Sub};

pub mod frontier;

Expand Down Expand Up @@ -445,7 +453,7 @@ impl Address {
let level_delta = (u64::BITS - index_delta.leading_zeros()) as u8;
Address {
level: higher.level + level_delta,
index: std::cmp::max(higher.index, lower_ancestor_idx) >> level_delta,
index: core::cmp::max(higher.index, lower_ancestor_idx) >> level_delta,
}
}

Expand Down Expand Up @@ -672,12 +680,14 @@ pub trait Hashable: fmt::Debug {

#[cfg(test)]
pub(crate) mod tests {
use crate::MerklePath;

use super::{Address, Level, Position, Source};
use alloc::string::{String, ToString};
use alloc::vec::Vec;
use core::ops::Range;
use either::Either;

use super::{Address, Level, Position, Source};
use crate::MerklePath;

#[test]
fn position_is_complete_subtree() {
assert!(Position(0).is_complete_subtree(Level(0)));
Expand Down
1 change: 1 addition & 0 deletions incrementalmerkletree/src/testing.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::{Hashable, Level};
use alloc::string::{String, ToString};

/// A possibly-empty incremental Merkle frontier.
pub trait Frontier<H> {
Expand Down
4 changes: 2 additions & 2 deletions incrementalmerkletree/src/witness.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::convert::TryInto;
use std::iter::repeat;
use core::convert::TryInto;
use core::iter::repeat;

use crate::{
frontier::{CommitmentTree, PathFiller},
Expand Down

0 comments on commit 676d9f7

Please sign in to comment.