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

Multiproof with tree trait #44

Merged
merged 10 commits into from
Nov 30, 2019
Merged

Multiproof with tree trait #44

merged 10 commits into from
Nov 30, 2019

Conversation

gballet
Copy link
Owner

@gballet gballet commented Nov 22, 2019

This PR prepares the ground for supporting several tree formats. This addresses #10 and supersedes #42 and #43

  • It adds a Tree trait that supports operations like insertion and iteration over the set of child nodes, then re-implements Node in terms of this trait.
  • This trait is parameterized by another trait, describing the key and value formats by requiring the definition of the Key and Value types, making is easier to switch between a nibble-/byte-/binary-based key type.
  • The Multiproof structure is parameterized by the tree type, to be able to reconstruct different types of trees from a single proof type.
  • It makes rebuild a method of Multiproof, which is the first step in supporting different proof types (the end goal is to support proofs that use instructions and proofs that do not)
  • It also effectively deprecates the use of the LEAF(i) operand i as expressed in Drop LEAF's operand #19

@gballet gballet requested a review from s1na November 22, 2019 10:13
This was referenced Nov 22, 2019
@s1na
Copy link
Collaborator

s1na commented Nov 26, 2019

I was going through quilt/pm#2 recently and it seems you and Matt are thinking along the same lines (e.g. see "Authenticated multi-proof backend" in his first post, and the 3rd post). The difference being you're trying to generalize from the MPT and multiproof, he from a sparse merkle tree and SSZ like proofs.Maybe eventually it'll be possible to converge on the same API, that'll be great! you guys should talk :)

Copy link
Collaborator

@s1na s1na left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I still think the proof format and the tree structure are tighly coupled, and it'll be difficult to decouple them, but it might well be possible and IMO this PR is a good start in that direction. Maybe there are still some unclear points, but I expect it'll improve iteratively.

The code's level is above my Rust experience and I can't tell how idiomatic it is. Specially around the Tree, KeyValueStore, Node and Multiproof traits and structs and their relationship, but to me it seems kinda logical. I just had a few minor comments, but I'm approving anyway. If you think they make sense also feel free to address them either here or in later PRs.

type Value = Vec<u8>;
}

impl Tree<Node> for Node {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I imagine the naming around Tree and Node might be confusing for someone reading the code. I don't really have better suggestions, maybe Node and MPTNode, or Tree and MPT?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, at least for the Node part. I want to try binary trees and I will rename it MPTree at this stage. Don't want to make this PR longer than strictly necessary.


fn from_hash(h: Vec<u8>) -> Self;
fn new_empty() -> Self;
fn new_extension(ext: Vec<u8>, child: Self) -> Self;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These new_* methods seem to be specific to the MPT tree. Is there maybe a way in Rust to only define them on Node and then cast a Tree to a Node when these methods are needed?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked for a way to do that, and didn't find any. I guess this could be split into a simpler Tree trait that doesn't have any extension and a more complex TreeWithExtension : Tree that supports them. I need to give it more thoughts after trying to implement a binary tree with this. So far, I assumed that a binary tree would simply implement new_extension as a panic!

NibbleKey::from(key[key.len() - *keylength..].to_vec()),
value.to_vec(),
));
LEAF(keylength) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah LEAF's operand has been deprecated as in it's not used, but it still has an operand, I misread your comment initially. This makes it easy to remove the operand later thanks 👍

stack.push(b)
} else {
return Err(format!(
"Could not pop a value from the stack, that is required for a BRANCH({})",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, these lines don't seem to have proper indentation in github's diff explorer. But since CI passed cargo fmt... I assume it's alright.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree it's weird, but that's the output of my cargo fmt.

@lightclient
Copy link
Contributor

lightclient commented Nov 26, 2019

This is really cool! I'm excited to see how you guys evolve this. I think it is good that we are both thinking in similar terms of building these abstractions, and hopefully we get to a point down the line where we converge 😄.

So I still think the proof format and the tree structure are tightly coupled

This is a tough thing to fully decouple all in one go, and I agree this appears to be a great step forward. IMO as these things mature, we'll continue to find ways to naturally decouple them!

@gballet
Copy link
Owner Author

gballet commented Nov 30, 2019

@lightclient @s1na yes, convergence is near! 😉

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.

3 participants