Skip to content

Commit

Permalink
more clean ups
Browse files Browse the repository at this point in the history
  • Loading branch information
ralexstokes committed Mar 30, 2024
1 parent ea5208a commit 1ebee0b
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 32 deletions.
12 changes: 6 additions & 6 deletions ssz-rs/src/boolean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use crate::{
de::{Deserialize, DeserializeError},
lib::*,
merkleization::{
proofs::{NoChilden, Prove},
GeneralizedIndexable, HashTreeRoot, MerkleizationError, Node,
proofs::Prove, GeneralizedIndexable, HashTreeRoot, MerkleizationError, Node,
BYTES_PER_CHUNK,
},
ser::{Serialize, SerializeError},
Serializable, SimpleSerialize,
Expand Down Expand Up @@ -63,14 +63,14 @@ impl GeneralizedIndexable for bool {
}

impl Prove for bool {
type Child = NoChilden;
type InnerElement = ();

fn chunks(&mut self) -> Result<Vec<u8>, MerkleizationError> {
let mut node = Node::default();
let mut vec = vec![0u8; BYTES_PER_CHUNK];
if *self {
node.as_mut()[0] = 1;
vec[0] = 1;
}
Ok(node.to_vec())
Ok(vec)
}
}

Expand Down
14 changes: 10 additions & 4 deletions ssz-rs/src/merkleization/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub mod proofs;

use crate::{lib::*, ser::SerializeError};
pub use generalized_index::{
get_power_of_two_ceil, GeneralizedIndex, GeneralizedIndexable, Path, PathElement,
get_power_of_two_ceil, log_2, GeneralizedIndex, GeneralizedIndexable, Path, PathElement,
};
pub use merkleize::*;
pub use node::*;
Expand All @@ -31,7 +31,10 @@ pub enum MerkleizationError {
InvalidPath(Vec<PathElement>),
InvalidDepth,
InvalidIndex,
NoChildren,
/// Attempt to prove an inner element for a "basic" type that doesn't have one
NoInnerElement,
/// Attempt to turn an instance of a type in Merkle chunks when this is not supported
NotChunkable,
}

impl From<SerializeError> for MerkleizationError {
Expand All @@ -53,10 +56,13 @@ impl Display for MerkleizationError {
Self::InvalidPath(path) => write!(f, "invalid path {path:?}"),
Self::InvalidDepth => write!(f, "error computing depth for proof"),
Self::InvalidIndex => write!(f, "error computing index for proof"),
Self::NoChildren => write!(
Self::NoInnerElement => write!(

Check warning on line 59 in ssz-rs/src/merkleization/mod.rs

View check run for this annotation

Codecov / codecov/patch

ssz-rs/src/merkleization/mod.rs#L57-L59

Added lines #L57 - L59 were not covered by tests
f,
"requested to compute proof for a child which does not exist for this type"
"requested to compute proof for an inner element which does not exist for this type"
),
Self::NotChunkable => {
write!(f, "requested to compute chunks for a type which does not support this")

Check warning on line 64 in ssz-rs/src/merkleization/mod.rs

View check run for this annotation

Codecov / codecov/patch

ssz-rs/src/merkleization/mod.rs#L64

Added line #L64 was not covered by tests
}
}
}
}
Expand Down
41 changes: 26 additions & 15 deletions ssz-rs/src/merkleization/proofs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ impl Prover {
parent_index / local_generalized_index + 1
};
self.proof.index = child_index;
let child = data.child(local_index)?;
let child = data.inner_element(local_index)?;
self.compute_proof(child)?;
self.proof.index = parent_index;
} else {
Expand Down Expand Up @@ -122,29 +122,40 @@ impl From<GeneralizedIndex> for Prover {
}
}

/// Types that can produce Merkle proofs against themselves given a `GeneralizedIndex`.
/// Required functionality to support computing Merkle proofs.
pub trait Prove: GeneralizedIndexable {
type Child: Prove;
type InnerElement: Prove;

fn chunks(&mut self) -> Result<Vec<u8>, Error>;
/// Compute the "chunks" of this type as required for the SSZ merkle tree computation.
/// Default implementation signals an error. Implementing types should override
/// to provide the correct behavior.
fn chunks(&mut self) -> Result<Vec<u8>, Error> {
Err(Error::NotChunkable)

Check warning on line 133 in ssz-rs/src/merkleization/proofs.rs

View check run for this annotation

Codecov / codecov/patch

ssz-rs/src/merkleization/proofs.rs#L132-L133

Added lines #L132 - L133 were not covered by tests
}

fn child(&mut self, _index: usize) -> Result<&mut Self::Child, Error> {
Err(Error::NoChildren)
/// Provide a reference to a member element of a composite type.
/// Default implementation signals an error. Implementing types should override
/// to provide the correct behavior.
fn inner_element(&mut self, _index: usize) -> Result<&mut Self::InnerElement, Error> {
Err(Error::NoInnerElement)

Check warning on line 140 in ssz-rs/src/merkleization/proofs.rs

View check run for this annotation

Codecov / codecov/patch

ssz-rs/src/merkleization/proofs.rs#L139-L140

Added lines #L139 - L140 were not covered by tests
}
}

pub struct NoChilden;

impl GeneralizedIndexable for NoChilden {}

impl Prove for NoChilden {
type Child = bool;

fn chunks(&mut self) -> Result<Vec<u8>, Error> {
Err(Error::NoChildren)
// Implement `GeneralizedIndexable` for `()` for use as a marker type in `Prove`.
impl GeneralizedIndexable for () {
fn compute_generalized_index(

Check warning on line 146 in ssz-rs/src/merkleization/proofs.rs

View check run for this annotation

Codecov / codecov/patch

ssz-rs/src/merkleization/proofs.rs#L146

Added line #L146 was not covered by tests
_parent: GeneralizedIndex,
path: Path,
) -> Result<GeneralizedIndex, Error> {
Err(Error::InvalidPath(path.to_vec()))

Check warning on line 150 in ssz-rs/src/merkleization/proofs.rs

View check run for this annotation

Codecov / codecov/patch

ssz-rs/src/merkleization/proofs.rs#L150

Added line #L150 was not covered by tests
}
}

// Implement the default `Prove` functionality for use of `()` as a marker type.
impl Prove for () {
type InnerElement = ();
}

/// Produce a Merkle proof (and corresponding witness) for the type `T` at the given `path` relative
/// to `T`.
pub fn prove<T: Prove>(data: &mut T, path: Path) -> Result<ProofAndWitness, Error> {
Expand Down
9 changes: 4 additions & 5 deletions ssz-rs/src/uint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ use crate::{
de::{Deserialize, DeserializeError},
lib::*,
merkleization::{
pack_bytes,
proofs::{NoChilden, Prove},
GeneralizedIndexable, HashTreeRoot, MerkleizationError, Node, BYTES_PER_CHUNK,
pack_bytes, proofs::Prove, GeneralizedIndexable, HashTreeRoot, MerkleizationError, Node,
BYTES_PER_CHUNK,
},
ser::{Serialize, SerializeError},
Serializable, SimpleSerialize, BITS_PER_BYTE,
Expand Down Expand Up @@ -74,7 +73,7 @@ macro_rules! define_uint {
}

impl Prove for $uint {
type Child = NoChilden;
type InnerElement = ();

fn chunks(&mut self) -> Result<Vec<u8>, MerkleizationError> {
let mut root = Vec::with_capacity(BYTES_PER_CHUNK);
Expand Down Expand Up @@ -156,7 +155,7 @@ impl GeneralizedIndexable for U256 {
}

impl Prove for U256 {
type Child = NoChilden;
type InnerElement = ();

fn chunks(&mut self) -> Result<Vec<u8>, MerkleizationError> {
Ok(self.as_le_bytes().to_vec())
Expand Down
7 changes: 5 additions & 2 deletions ssz-rs/src/vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,13 +284,16 @@ impl<T, const N: usize> Prove for Vector<T, N>
where
T: SimpleSerialize + Prove,
{
type Child = T;
type InnerElement = T;

fn chunks(&mut self) -> Result<Vec<u8>, MerkleizationError> {
self.assemble_chunks()
}

fn child(&mut self, index: usize) -> Result<&mut Self::Child, MerkleizationError> {
fn inner_element(
&mut self,
index: usize,
) -> Result<&mut Self::InnerElement, MerkleizationError> {
if index >= N {
Err(MerkleizationError::InvalidIndex)

Check warning on line 298 in ssz-rs/src/vector.rs

View check run for this annotation

Codecov / codecov/patch

ssz-rs/src/vector.rs#L298

Added line #L298 was not covered by tests
} else {
Expand Down

0 comments on commit 1ebee0b

Please sign in to comment.