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

Add path to Branch-Nodes (don't use Extension-Nodes) #344

Merged
merged 9 commits into from
Feb 2, 2024

Conversation

richardpringle
Copy link
Contributor

  • Add path to branch-node
  • Split leaf, branch, and extension node files
  • NodeType should box the branch-node
  • Use leaf-node size
  • Use an enum instead of numbers
  • Refactor node-serialization
  • WIP

rkuris
rkuris previously requested changes Nov 11, 2023
firewood/src/merkle.rs Show resolved Hide resolved
firewood/src/merkle.rs Outdated Show resolved Hide resolved
firewood/src/merkle.rs Outdated Show resolved Hide resolved
firewood/src/merkle.rs Outdated Show resolved Hide resolved
firewood/src/merkle.rs Show resolved Hide resolved
firewood/src/merkle.rs Outdated Show resolved Hide resolved
firewood/src/merkle.rs Show resolved Hide resolved
firewood/src/merkle.rs Outdated Show resolved Hide resolved
firewood/src/merkle.rs Show resolved Hide resolved
firewood/src/merkle.rs Show resolved Hide resolved
@richardpringle richardpringle self-assigned this Nov 13, 2023
@richardpringle richardpringle mentioned this pull request Nov 20, 2023
@richardpringle richardpringle force-pushed the remove-extension-node branch 15 times, most recently from a2e3c30 to fcdcfce Compare November 27, 2023 16:32
@richardpringle richardpringle force-pushed the remove-extension-node branch 10 times, most recently from ca59f9a to 6365bef Compare November 29, 2023 05:47
@richardpringle richardpringle dismissed rkuris’s stale review January 16, 2024 01:32

I'm going to open a new PR

@richardpringle richardpringle marked this pull request as ready for review January 16, 2024 22:46
@richardpringle richardpringle requested a review from rkuris January 17, 2024 18:15
firewood/src/merkle/node.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@xinifinity xinifinity left a comment

Choose a reason for hiding this comment

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

Do you mind updating the description accordingly with the latest changes? Thanks!

Copy link
Contributor

@xinifinity xinifinity left a comment

Choose a reason for hiding this comment

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

Partial review as a first pass.

Comment on lines +2200 to +2212
let fetched_val = merkle.get(key, root).unwrap();

assert_eq!(fetched_val.as_deref(), val.as_slice().into());
}

for (key, val) in key_val {
let fetched_val = merkle.get(key, root).unwrap();

assert_eq!(fetched_val.as_deref(), val.as_slice().into());
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need a test to verify retrieve multiple times? What is the motivation?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We insert a value, then make sure that it's still there. Then we check to see if all the values are there at the end. In an improper implementation, it's possible that inserting new nodes will improperly move nodes (through splitting etc) and values will be inadvertently moved.

#[test_case(branch(&[2], b"", None); "branch with path")]
#[test_case(branch(b"", b"", vec![1, 2, 3].into()); "branch with children")]
#[test_case(branch(&[2], b"value", None); "branch with path and value")]
#[test_case(branch(b"", b"value", vec![1, 2, 3].into()); "branch with value and children")]
Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't this the same test as L2067?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Please use permalinks... the code changed and now I don't know what line you were talking about.
Maybe this one?

Looks the same. This will get fixed with #512

let children = Default::default();
let value = value.map(Data);
// TODO: Properly test empty data as a value
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need to test empty data in the no data case?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There can be subtle differences in serializing and deserializing Some(vec![]) vs None. It's valid to store an empty byte-vector at any key.

@@ -1528,17 +2018,44 @@ mod tests {
create_generic_test_merkle::<Bincode>()
}

fn branch(value: Option<Vec<u8>>, encoded_child: Option<Vec<u8>>) -> Node {
fn branch(path: &[u8], value: &[u8], encoded_child: Option<Vec<u8>>) -> Node {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need to split this to two functions? It seems there are repeated code after the split.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think this comment is relevant anymore due to changes that landed in main. Please re-open if that's not the case.

#[test_case(PlainCodec::new(), branch(Some(Vec::new()), vec![1, 2, 3].into()); "branch with empty value with PlainCodec")]
#[test_case(PlainCodec::new(), branch(b"", b"value", vec![1, 2, 3].into()) ; "branch with chd with PlainCodec")]
#[test_case(PlainCodec::new(), branch(b"", b"value", Some(Vec::new())); "branch with empty chd with PlainCodec")]
#[test_case(PlainCodec::new(), branch(b"", b"", vec![1, 2, 3].into()); "branch with empty value with PlainCodec")]
Copy link
Contributor

Choose a reason for hiding this comment

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

It doesn't seem we have a test case for branch with non empty path?

Copy link
Collaborator

@rkuris rkuris Jan 18, 2024

Choose a reason for hiding this comment

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

Rather than rolling each permutation by hand, the test_case crate also has test_matrix which can test all the combinations for you. Not only is this more readable, it names the arguments so you can see which permutations are actually being tested.

   #[test_matrix(
        [b"", b"key"],
        [b"", b"value"],
        [None, Some(vec![1,2,3])]
    )]
    fn encodes_then_decode_branches(key: &'static [u8], value: &'static [u8], vec: Option<Vec<u8>>) {
        encode(branch(key, value, vec));
    }

    #[test_matrix(
        [vec![], vec![1, 2. 3]],
        [vec![], vec![1, 2, 3]]
    )]
    fn encode_then_decode_leaves(key: Vec<u8>, value: Vec<u8>) {
        encode(leaf(key, value))
    }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See issue #512 for the test-matrix comment.

@xinifinity

It doesn't seem we have a test case for branch with non empty path?

Correct, the new encoding/decoding implementation isn't currently used anywhere. Can we push the implementation out after this PR lands? It's impossible that this doesn't get caught because all the proofs will start failing once we switch to the new encoding/decoding. It should also be trivial to implement

firewood/src/merkle.rs Outdated Show resolved Hide resolved
@richardpringle richardpringle merged commit 7713f2d into main Feb 2, 2024
5 checks passed
@richardpringle richardpringle deleted the remove-extension-node branch February 2, 2024 19:23
@rkuris
Copy link
Collaborator

rkuris commented Feb 5, 2024

We decided to land this despite completing the review as it is for some reason blocking adding a configuration flag to enable extension nodes

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

Successfully merging this pull request may close these issues.

3 participants