Merge pull request #99 from nuttycom/random_frontier

Add `Frontier::random_of_size` to facilitate testing.
This commit is contained in:
Kris Nuttycombe 2024-03-18 08:54:32 -06:00 committed by GitHub
commit 2411de7cec
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 36 additions and 1 deletions

2
Cargo.lock generated
View File

@ -115,6 +115,8 @@ version = "0.5.0"
dependencies = [
"either",
"proptest",
"rand",
"rand_core",
]
[[package]]

View File

@ -20,9 +20,13 @@ rustdoc-args = ["--cfg", "docsrs"]
[dependencies]
either = "1.8"
proptest = { version = "1.0.0", optional = true }
rand = { version = "0.8", optional = true }
rand_core = { version = "0.6", optional = true }
[dev-dependencies]
proptest = "1.0.0"
rand = "0.8"
rand_core = "0.6"
[features]
# The legacy-api feature guards types and functions that were previously
@ -31,4 +35,4 @@ proptest = "1.0.0"
legacy-api = []
# The test-dependencies feature guards types and functions that are
# useful for testing incremental Merkle trees and Merkle tree frontiers.
test-dependencies = ["proptest"]
test-dependencies = ["dep:proptest", "dep:rand", "dep:rand_core"]

View File

@ -6,6 +6,12 @@ use crate::{Address, Hashable, Level, MerklePath, Position, Source};
#[cfg(feature = "legacy-api")]
use {std::collections::VecDeque, std::iter::repeat};
#[cfg(any(test, feature = "test-dependencies"))]
use rand::{
distributions::{Distribution, Standard},
Rng, RngCore,
};
/// Validation errors that can occur during reconstruction of a Merkle frontier from
/// its constituent parts.
#[derive(Clone, Debug, PartialEq, Eq)]
@ -287,6 +293,29 @@ impl<H: Hashable + Clone, const DEPTH: u8> Frontier<H, DEPTH> {
}
}
#[cfg(any(test, feature = "test-dependencies"))]
impl<H: Hashable + Clone, const DEPTH: u8> Frontier<H, DEPTH>
where
Standard: Distribution<H>,
{
/// Generates a random frontier of a Merkle tree having the specified size.
pub fn random_of_size<R: RngCore>(rng: &mut R, tree_size: u64) -> Self {
if tree_size == 0 {
Frontier::empty()
} else {
let position = (tree_size - 1).into();
Frontier::from_parts(
position,
rng.gen(),
std::iter::repeat_with(|| rng.gen())
.take(position.past_ommer_count().into())
.collect(),
)
.unwrap()
}
}
}
#[cfg(feature = "legacy-api")]
#[cfg_attr(docsrs, doc(cfg(feature = "legacy-api")))]
pub struct PathFiller<H> {