Skip to content

Commit

Permalink
Merge pull request #125 from ralexstokes/even-more-gi
Browse files Browse the repository at this point in the history
Some more generalized index functionality
  • Loading branch information
ralexstokes authored Feb 19, 2024
2 parents e671bd5 + 76e42e2 commit 6329986
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 10 deletions.
3 changes: 3 additions & 0 deletions ssz-rs/src/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ where
if let Some((next, rest)) = path.split_first() {
match next {
PathElement::Index(i) => {
if *i >= N {
return Err(MerkleizationError::InvalidPathElement(next.clone()))
}
let chunk_position = i * T::item_length() / 32;
let child =
parent * get_power_of_two_ceil(Self::chunk_count()) + chunk_position;
Expand Down
30 changes: 25 additions & 5 deletions ssz-rs/src/bitlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,31 @@ impl<const N: usize> Merkleized for Bitlist<N> {
}

impl<const N: usize> Indexed for Bitlist<N> {
fn generalized_index(_path: Path) -> Result<GeneralizedIndex, MerkleizationError>
where
Self: Sized,
{
unimplemented!()
fn chunk_count() -> usize {
Self::chunk_count()
}

fn compute_generalized_index(
parent: GeneralizedIndex,
path: Path,
) -> Result<GeneralizedIndex, MerkleizationError> {
if let Some((next, rest)) = path.split_first() {
match next {
PathElement::Index(i) => {
if *i >= N {
return Err(MerkleizationError::InvalidPathElement(next.clone()))
}
let chunk_position = i / 256;
let child = parent * get_power_of_two_ceil(<Self as Indexed>::chunk_count()) +
chunk_position;
// NOTE: use `bool` as effective type of element
bool::compute_generalized_index(child, rest)
}
elem => Err(MerkleizationError::InvalidPathElement(elem.clone())),
}
} else {
Ok(parent)
}
}
}

Expand Down
30 changes: 25 additions & 5 deletions ssz-rs/src/bitvector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,31 @@ impl<const N: usize> Merkleized for Bitvector<N> {
}

impl<const N: usize> Indexed for Bitvector<N> {
fn generalized_index(_path: Path) -> Result<GeneralizedIndex, MerkleizationError>
where
Self: Sized,
{
unimplemented!()
fn chunk_count() -> usize {
Self::chunk_count()
}

fn compute_generalized_index(
parent: GeneralizedIndex,
path: Path,
) -> Result<GeneralizedIndex, MerkleizationError> {
if let Some((next, rest)) = path.split_first() {
match next {
PathElement::Index(i) => {
if *i >= N {
return Err(MerkleizationError::InvalidPathElement(next.clone()))
}
let chunk_position = i / 256;
let child = parent * get_power_of_two_ceil(<Self as Indexed>::chunk_count()) +
chunk_position;
// NOTE: use `bool` as effective type of element
bool::compute_generalized_index(child, rest)
}
elem => Err(MerkleizationError::InvalidPathElement(elem.clone())),
}
} else {
Ok(parent)
}
}
}

Expand Down
12 changes: 12 additions & 0 deletions ssz-rs/src/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,9 @@ where
if let Some((next, rest)) = path.split_first() {
match next {
PathElement::Index(i) => {
if *i >= N {
return Err(MerkleizationError::InvalidPathElement(next.clone()))
}
let chunk_position = i * T::item_length() / 32;
let child =
parent * 2 * get_power_of_two_ceil(<Self as Indexed>::chunk_count()) +
Expand Down Expand Up @@ -427,4 +430,13 @@ mod tests {
let bad_input_str = "[1, 2, 3, 4, 5]";
let _: L = serde_json::from_str(bad_input_str).unwrap();
}

#[test]
#[should_panic]
fn test_illegal_generalized_index() {
type L = List<u8, 4>;

let path = &[5.into()];
let _ = L::generalized_index(path).unwrap();
}
}
12 changes: 12 additions & 0 deletions ssz-rs/src/vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,9 @@ where
if let Some((next, rest)) = path.split_first() {
match next {
PathElement::Index(i) => {
if *i >= N {
return Err(MerkleizationError::InvalidPathElement(next.clone()))
}
let chunk_position = i * T::item_length() / 32;
let child =
parent * get_power_of_two_ceil(Self::chunk_count()) + chunk_position;
Expand Down Expand Up @@ -443,4 +446,13 @@ mod tests {
let bad_input_str = "[]";
let _: V = serde_json::from_str(bad_input_str).unwrap();
}

#[test]
#[should_panic]
fn test_illegal_generalized_index() {
type V = Vector<u8, 4>;

let path = &[5.into()];
let _ = V::generalized_index(path).unwrap();
}
}

0 comments on commit 6329986

Please sign in to comment.