-
Notifications
You must be signed in to change notification settings - Fork 14
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
Conversation
richardpringle
commented
Nov 7, 2023
- 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
f25a9f1
to
7c01d0d
Compare
a2e3c30
to
fcdcfce
Compare
ca59f9a
to
6365bef
Compare
44591c3
to
cd22881
Compare
cd22881
to
3c5ea5b
Compare
There was a problem hiding this 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!
There was a problem hiding this 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.
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()); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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")] |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let children = Default::default(); | ||
let value = value.map(Data); | ||
// TODO: Properly test empty data as a value |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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")] |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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))
}
There was a problem hiding this comment.
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.
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
2d90bb3
to
1e51e15
Compare
a0854fa
to
74e264f
Compare
We decided to land this despite completing the review as it is for some reason blocking adding a configuration flag to enable extension nodes |