Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Prove trait with more generic Visitable trait, implement for all types, and rewrite prove in terms of it #174

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

willemolding
Copy link

This crate has a forking issue. Many useful additions are scattered across over 40 forks and to me this suggests that the underlying API is not flexible enough to allow consumers to do what they want to do.

This PR aims to fix that once and for all so that a single version of ssz_rs can stabilize while new features can continue to be added in their own separate crates that work together with this one.

Motivation

Features missing from this crate but implemented in forks include:

  • Merkle proof building with caching
  • Support different hash types
  • Memory efficient proof building using precomputed zero nodes
  • Merkle multiproofs
  • Compact multiproofs

One operation that is common to all these algorithms is the idea of visiting the different containers that make up a composite SSZ container.

Implementation

This PR introduces a generic Visitable trait

trait Visitable {
    fn visit_element<V: Visitor>(&self, _index: usize, _visitor: &mut V) -> Result<(), V::Error>;
}

that is implemented by all primitives and containers via the derive macros.

The above algorithms and more can be implemented by writing a custom type that implements the Visitor trait

trait Visitor: Sized {
    type Error: From<VisitorError>;

    fn visit<T: SimpleSerialize + Visitable + ?Sized>(
        &mut self,
        element: &T,
    ) -> Result<(), Self::Error>;
}

It also adds a new trait Chunkable also implemented for all primitives and containers that allows Visitor developers to access the underlying leaves of the subtree for each subcontainer.

For example in this PR the Prover implementation is rewritten as a visitor that consumes chunks.
https://github.com/willemolding/ssz-rs/blob/c1b956fe9d4dafc4309bcda118a6c6489a6c9064/ssz-rs/src/merkleization/proofs.rs#L75

This new API should make it easy for developers who want to implement new algorithms (or variations) that operate over the SSZ data structures in their own crates

Changes

  • Add Visitable, Visitor, and Chunkable traits
  • Add implementations of Visitable and Chunkable for all primitive types
  • Add derive implementations of Visitable and Chunkable via derive macros
  • Reimplement Prover in terms of the above traits
  • fmt and clippy modified files

implementation of Prover using visitor sketched out

remove generic from Visitible trait and put it on method

remove prove_elemement from Prove trait

rename Prove to Chunkable

add Prove blanked impl trait

add derive impl for Visitable and rename error type

proving implement using visitor pattern

satisfy clippy
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant