-
Notifications
You must be signed in to change notification settings - Fork 31
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
feat: proof verification #13
Conversation
93d31ab
to
a345982
Compare
a345982
to
43561d4
Compare
let extension = ExtensionNode::new(nibble, val.to_vec()); | ||
let mut child = vec![]; | ||
val.to_vec().as_slice().encode(&mut child); | ||
let extension = ExtensionNode::new(nibble, child); | ||
let rlp = extension.as_ref().rlp(&mut vec![]); | ||
assert_eq!(rlp, hex!("c88300646f76657262")); | ||
assert_eq!(rlp, hex!("c98300646f8476657262")); |
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.
The child has to be a valid rlp encoded value but before it was just a hex
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.
Encoding looks to have been wrong, the extension node's child wasn't encoded as a string, but just plain hex without a header. Would have been decoded as 0x0604060f
+ 4 single bytes, since each byte of 0x76657262
is <= 0x7F
impl TrieNode { | ||
/// RLP encodes the node and returns either RLP(Node) or RLP(keccak(RLP(node))). | ||
pub fn rlp(&self, buf: &mut Vec<u8>) -> Vec<u8> { | ||
self.encode(buf); | ||
rlp_node(buf) | ||
} | ||
} | ||
|
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.
This is double-rlp encoding, could you remind me why?
} | ||
|
||
// Decode without advancing | ||
let Header { payload_length, .. } = Header::decode(&mut &bytes[..])?; |
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.
eok had forgotten that ::decode(&mut &bytes[..])
does not advance and it does it manually, but now i wonder why shouldn't we just ::decode(&mut bytes)
and let the decoder advance it?
Because values on the stack are RLP encoded, so if we did this we'd also RLP decode and we'd need to re-encode, whereas this is a "peek" at the RLP length and then you just push that to the stack w/o re-encoding & skip to next
src/nodes/branch.rs
Outdated
let mut buf = vec![]; | ||
|
||
let empty = BranchNode::default(); | ||
buf.clear(); |
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.
unnecessary
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.
sparse_node.encode(&mut buf); | ||
assert_eq!(BranchNode::decode(&mut &buf[..]).unwrap(), sparse_node); | ||
|
||
let leaf_child = LeafNode::new(Nibbles::from_nibbles(hex!("0203")), hex!("1234").to_vec()); | ||
buf.clear(); | ||
let leaf_rlp = leaf_child.as_ref().rlp(&mut buf); |
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.
NB: This does rlp
once, and then rlp_node
so it handles the "double rlp"ing which we did manually above
src/proof/verify.rs
Outdated
proof: I, | ||
root: B256, | ||
key: B256, |
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.
API should be: fn(root: B256, key: B256, value: Option<Vec>, proof: I) -> Ok(())
expected_value = match TrieNode::decode(&mut &node[..])? { | ||
TrieNode::Branch(branch) => 'val: { | ||
if let Some(next) = target.get(walked_path.len()) { | ||
let mut stack_ptr = branch.as_ref().first_child_index(); |
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.
TODO: The Branch Node's stack may have an arbitrary length whereas it should equal to the number of 1s in the state mask
src/proof/verify.rs
Outdated
if branch.state_mask.is_bit_set(index) { | ||
if index == *next { | ||
walked_path.push(*next); | ||
break 'val Some(branch.stack[stack_ptr].clone()); | ||
} | ||
stack_ptr += 1; | ||
} |
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.
get the next level's node from the stack and increment stack pointer
Description
Implement merkle proof verification algorithm. Also, fixes decoding for
BranchNode
.