mirror of
https://github.com/vacp2p/zerokit.git
synced 2026-01-09 13:47:58 -05:00
Compare commits
1 Commits
v0.9.0
...
eyre-remov
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
93f5997544 |
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -2532,7 +2532,6 @@ version = "0.5.2"
|
||||
dependencies = [
|
||||
"ark-bn254",
|
||||
"ark-ff 0.5.0",
|
||||
"color-eyre",
|
||||
"criterion",
|
||||
"hex",
|
||||
"hex-literal",
|
||||
@@ -2541,6 +2540,7 @@ dependencies = [
|
||||
"num-traits",
|
||||
"serde",
|
||||
"sled",
|
||||
"thiserror",
|
||||
"tiny-keccak",
|
||||
"vacp2p_pmtree",
|
||||
]
|
||||
|
||||
@@ -18,7 +18,8 @@ ark-ff = { version = "0.5.0", default-features = false, features = [
|
||||
num-bigint = { version = "0.4.6", default-features = false, features = [
|
||||
"rand",
|
||||
] }
|
||||
color-eyre = "0.6.3"
|
||||
# color-eyre = "0.6.3"
|
||||
thiserror = "2.0.12"
|
||||
pmtree = { package = "vacp2p_pmtree", version = "2.0.2", optional = true }
|
||||
sled = "0.34.7"
|
||||
serde = "1.0"
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
use crate::merkle_tree::{FrOf, Hasher, ZerokitMerkleProof, ZerokitMerkleTree};
|
||||
use color_eyre::{Report, Result};
|
||||
// use color_eyre::{Report, Result};
|
||||
use std::{
|
||||
cmp::max,
|
||||
fmt::Debug,
|
||||
iter::{once, repeat_n, successors},
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
use num_traits::Zero;
|
||||
use crate::ZerokitMerkleTreeError;
|
||||
////////////////////////////////////////////////////////////
|
||||
///// Full Merkle Tree Implementation
|
||||
////////////////////////////////////////////////////////////
|
||||
@@ -14,7 +15,7 @@ use std::{
|
||||
/// Merkle tree with all leaf and intermediate hashes stored
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct FullMerkleTree<H: Hasher> {
|
||||
/// The depth of the tree, i.e. the number of levels from leaf to root
|
||||
/// The depth of the tree, i.e., the number of levels from leaf to root
|
||||
depth: usize,
|
||||
|
||||
/// The nodes cached from the empty part of the tree (where leaves are set to default).
|
||||
@@ -56,9 +57,9 @@ pub struct FullMerkleProof<H: Hasher>(pub Vec<FullMerkleBranch<H>>);
|
||||
pub struct FullMerkleConfig(());
|
||||
|
||||
impl FromStr for FullMerkleConfig {
|
||||
type Err = Report;
|
||||
type Err = ();
|
||||
|
||||
fn from_str(_s: &str) -> Result<Self> {
|
||||
fn from_str(_s: &str) -> Result<Self, ()> {
|
||||
Ok(FullMerkleConfig::default())
|
||||
}
|
||||
}
|
||||
@@ -72,13 +73,13 @@ where
|
||||
type Hasher = H;
|
||||
type Config = FullMerkleConfig;
|
||||
|
||||
fn default(depth: usize) -> Result<Self> {
|
||||
fn default(depth: usize) -> Result<Self, ZerokitMerkleTreeError> {
|
||||
FullMerkleTree::<H>::new(depth, Self::Hasher::default_leaf(), Self::Config::default())
|
||||
}
|
||||
|
||||
/// Creates a new `MerkleTree`
|
||||
/// depth - the height of the tree made only of hash nodes. 2^depth is the maximum number of leaves hash nodes
|
||||
fn new(depth: usize, initial_leaf: FrOf<Self::Hasher>, _config: Self::Config) -> Result<Self> {
|
||||
fn new(depth: usize, initial_leaf: FrOf<Self::Hasher>, _config: Self::Config) -> Result<Self, ZerokitMerkleTreeError> {
|
||||
// Compute cache node values, leaf to root
|
||||
let cached_nodes = successors(Some(initial_leaf), |prev| Some(H::hash(&[*prev, *prev])))
|
||||
.take(depth + 1)
|
||||
@@ -106,7 +107,7 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
fn close_db_connection(&mut self) -> Result<()> {
|
||||
fn close_db_connection(&mut self) -> Result<(), ZerokitMerkleTreeError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -115,7 +116,7 @@ where
|
||||
self.depth
|
||||
}
|
||||
|
||||
// Returns the capacity of the tree, i.e. the maximum number of accumulatable leaves
|
||||
// Returns the capacity of the tree, i.e., the maximum number of accumulatable leaves
|
||||
fn capacity(&self) -> usize {
|
||||
1 << self.depth
|
||||
}
|
||||
@@ -131,26 +132,26 @@ where
|
||||
}
|
||||
|
||||
// Sets a leaf at the specified tree index
|
||||
fn set(&mut self, leaf: usize, hash: FrOf<Self::Hasher>) -> Result<()> {
|
||||
fn set(&mut self, leaf: usize, hash: FrOf<Self::Hasher>) -> Result<(), ZerokitMerkleTreeError> {
|
||||
self.set_range(leaf, once(hash))?;
|
||||
self.next_index = max(self.next_index, leaf + 1);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Get a leaf from the specified tree index
|
||||
fn get(&self, leaf: usize) -> Result<FrOf<Self::Hasher>> {
|
||||
fn get(&self, leaf: usize) -> Result<FrOf<Self::Hasher>, ZerokitMerkleTreeError> {
|
||||
if leaf >= self.capacity() {
|
||||
return Err(Report::msg("leaf index out of bounds"));
|
||||
return Err(ZerokitMerkleTreeError::InvalidLeaf);
|
||||
}
|
||||
Ok(self.nodes[self.capacity() + leaf - 1])
|
||||
}
|
||||
|
||||
fn get_subtree_root(&self, n: usize, index: usize) -> Result<H::Fr> {
|
||||
fn get_subtree_root(&self, n: usize, index: usize) -> Result<H::Fr, ZerokitMerkleTreeError> {
|
||||
if n > self.depth() {
|
||||
return Err(Report::msg("level exceeds depth size"));
|
||||
return Err(ZerokitMerkleTreeError::LevelExceedsDepth);
|
||||
}
|
||||
if index >= self.capacity() {
|
||||
return Err(Report::msg("index exceeds set size"));
|
||||
return Err(ZerokitMerkleTreeError::InvalidLeaf);
|
||||
}
|
||||
if n == 0 {
|
||||
Ok(self.root())
|
||||
@@ -187,14 +188,14 @@ where
|
||||
&mut self,
|
||||
start: usize,
|
||||
hashes: I,
|
||||
) -> Result<()> {
|
||||
) -> Result<(), ZerokitMerkleTreeError> {
|
||||
let index = self.capacity() + start - 1;
|
||||
let mut count = 0;
|
||||
// first count number of hashes, and check that they fit in the tree
|
||||
// first count the number of hashes and check that they fit in the tree
|
||||
// then insert into the tree
|
||||
let hashes = hashes.into_iter().collect::<Vec<_>>();
|
||||
if hashes.len() + start > self.capacity() {
|
||||
return Err(Report::msg("provided hashes do not fit in the tree"));
|
||||
return Err(ZerokitMerkleTreeError::TooManySet);
|
||||
}
|
||||
hashes.into_iter().for_each(|hash| {
|
||||
self.nodes[index + count] = hash;
|
||||
@@ -208,7 +209,7 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn override_range<I, J>(&mut self, start: usize, leaves: I, indices: J) -> Result<()>
|
||||
fn override_range<I, J>(&mut self, start: usize, leaves: I, indices: J) -> Result<(), ZerokitMerkleTreeError>
|
||||
where
|
||||
I: IntoIterator<Item = FrOf<Self::Hasher>>,
|
||||
J: IntoIterator<Item = usize>,
|
||||
@@ -237,17 +238,16 @@ where
|
||||
}
|
||||
|
||||
self.set_range(start, set_values.into_iter())
|
||||
.map_err(|e| Report::msg(e.to_string()))
|
||||
}
|
||||
|
||||
// Sets a leaf at the next available index
|
||||
fn update_next(&mut self, leaf: FrOf<Self::Hasher>) -> Result<()> {
|
||||
fn update_next(&mut self, leaf: FrOf<Self::Hasher>) -> Result<(), ZerokitMerkleTreeError> {
|
||||
self.set(self.next_index, leaf)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Deletes a leaf at a certain index by setting it to its default value (next_index is not updated)
|
||||
fn delete(&mut self, index: usize) -> Result<()> {
|
||||
fn delete(&mut self, index: usize) -> Result<(), ZerokitMerkleTreeError> {
|
||||
// We reset the leaf only if we previously set a leaf at that index
|
||||
if index < self.next_index {
|
||||
self.set(index, H::default_leaf())?;
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
//! * Implement serialization for tree and Merkle proof
|
||||
|
||||
use std::str::FromStr;
|
||||
|
||||
use color_eyre::Result;
|
||||
use num_traits::Zero;
|
||||
// use color_eyre::Result;
|
||||
|
||||
/// In the Hasher trait we define the node type, the default leaf
|
||||
/// and the hash function used to initialize a Merkle Tree implementation
|
||||
@@ -32,6 +32,30 @@ pub trait Hasher {
|
||||
|
||||
pub type FrOf<H> = <H as Hasher>::Fr;
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum ZerokitMerkleTreeError {
|
||||
#[error("Invalid index")]
|
||||
InvalidIndex,
|
||||
// InvalidProof,
|
||||
#[error("Leaf index out of bounds")]
|
||||
InvalidLeaf,
|
||||
|
||||
#[error("Level exceeds tree depth")]
|
||||
LevelExceedsDepth,
|
||||
#[error("Subtree index out of bounds")]
|
||||
InvalidSubTreeIndex,
|
||||
|
||||
#[error("set_range got too many leaves")]
|
||||
TooManySet
|
||||
|
||||
// InvalidConfig,
|
||||
// InvalidMetadata,
|
||||
// InvalidDepth,
|
||||
// InvalidCapacity,
|
||||
// InvalidLeavesSet,
|
||||
// InvalidRoot,
|
||||
}
|
||||
|
||||
/// In the ZerokitMerkleTree trait we define the methods that are required to be implemented by a Merkle tree
|
||||
/// Including, OptimalMerkleTree, FullMerkleTree
|
||||
pub trait ZerokitMerkleTree {
|
||||
@@ -39,35 +63,35 @@ pub trait ZerokitMerkleTree {
|
||||
type Hasher: Hasher;
|
||||
type Config: Default + FromStr;
|
||||
|
||||
fn default(depth: usize) -> Result<Self>
|
||||
fn default(depth: usize) -> Result<Self, ZerokitMerkleTreeError>
|
||||
where
|
||||
Self: Sized;
|
||||
fn new(depth: usize, default_leaf: FrOf<Self::Hasher>, config: Self::Config) -> Result<Self>
|
||||
fn new(depth: usize, default_leaf: FrOf<Self::Hasher>, config: Self::Config) -> Result<Self, ZerokitMerkleTreeError>
|
||||
where
|
||||
Self: Sized;
|
||||
fn depth(&self) -> usize;
|
||||
fn capacity(&self) -> usize;
|
||||
fn leaves_set(&self) -> usize;
|
||||
fn root(&self) -> FrOf<Self::Hasher>;
|
||||
fn compute_root(&mut self) -> Result<FrOf<Self::Hasher>>;
|
||||
fn get_subtree_root(&self, n: usize, index: usize) -> Result<FrOf<Self::Hasher>>;
|
||||
fn set(&mut self, index: usize, leaf: FrOf<Self::Hasher>) -> Result<()>;
|
||||
fn set_range<I>(&mut self, start: usize, leaves: I) -> Result<()>
|
||||
fn compute_root(&mut self) -> Result<FrOf<Self::Hasher>, ZerokitMerkleTreeError>;
|
||||
fn get_subtree_root(&self, n: usize, index: usize) -> Result<FrOf<Self::Hasher>, ZerokitMerkleTreeError>;
|
||||
fn set(&mut self, index: usize, leaf: FrOf<Self::Hasher>) -> Result<(), ZerokitMerkleTreeError>;
|
||||
fn set_range<I>(&mut self, start: usize, leaves: I) -> Result<(), ZerokitMerkleTreeError>
|
||||
where
|
||||
I: ExactSizeIterator<Item = FrOf<Self::Hasher>>;
|
||||
fn get(&self, index: usize) -> Result<FrOf<Self::Hasher>>;
|
||||
fn get(&self, index: usize) -> Result<FrOf<Self::Hasher>, ZerokitMerkleTreeError>;
|
||||
fn get_empty_leaves_indices(&self) -> Vec<usize>;
|
||||
fn override_range<I, J>(&mut self, start: usize, leaves: I, to_remove_indices: J) -> Result<()>
|
||||
fn override_range<I, J>(&mut self, start: usize, leaves: I, to_remove_indices: J) -> Result<(), ZerokitMerkleTreeError>
|
||||
where
|
||||
I: ExactSizeIterator<Item = FrOf<Self::Hasher>>,
|
||||
J: ExactSizeIterator<Item = usize>;
|
||||
fn update_next(&mut self, leaf: FrOf<Self::Hasher>) -> Result<()>;
|
||||
fn delete(&mut self, index: usize) -> Result<()>;
|
||||
fn proof(&self, index: usize) -> Result<Self::Proof>;
|
||||
fn verify(&self, leaf: &FrOf<Self::Hasher>, witness: &Self::Proof) -> Result<bool>;
|
||||
fn set_metadata(&mut self, metadata: &[u8]) -> Result<()>;
|
||||
fn metadata(&self) -> Result<Vec<u8>>;
|
||||
fn close_db_connection(&mut self) -> Result<()>;
|
||||
fn update_next(&mut self, leaf: FrOf<Self::Hasher>) -> Result<(), ZerokitMerkleTreeError>;
|
||||
fn delete(&mut self, index: usize) -> Result<(), ZerokitMerkleTreeError>;
|
||||
fn proof(&self, index: usize) -> Result<Self::Proof, ZerokitMerkleTreeError>;
|
||||
fn verify(&self, leaf: &FrOf<Self::Hasher>, witness: &Self::Proof) -> Result<bool, ZerokitMerkleTreeError>;
|
||||
fn set_metadata(&mut self, metadata: &[u8]) -> Result<(), ZerokitMerkleTreeError>;
|
||||
fn metadata(&self) -> Result<Vec<u8>, ZerokitMerkleTreeError>;
|
||||
fn close_db_connection(&mut self) -> Result<(), ZerokitMerkleTreeError>;
|
||||
}
|
||||
|
||||
pub trait ZerokitMerkleProof {
|
||||
|
||||
Reference in New Issue
Block a user