-
Notifications
You must be signed in to change notification settings - Fork 27
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
Merkle tree construction #504
Conversation
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 can rap-battle some more about the 1D array index stuff, if you'd like. (Or we can delay it till we get to serialization where we need to do it anyway.)
e162f43
to
6238664
Compare
But @benbierens it's like |
Oh yeah, no doubt the 1D thing is much better in this way. It's just, we were just starting and needed a way to think about what we were trying to do. So we started with lots of allocs. |
b60c442
to
d560d5e
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.
I have what are mostly petty comments. 🙂 Overall it looks good, particularly given that it passes the tests.
digestSize =? leaves.?[0].?size: | ||
return failure("At least one leaf is required") | ||
|
||
if not leaves.allIt(it.mcodec == mcodec): |
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 get why you are doing this, but to me this is a symptom that mcodec should be a property of the tree and not a property of the node. Not sure there's much of a way around it though.
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.
Yeah, initially I started implementing it this way, but the new code has to be compatible with already existing code and it's just easier to do it this way than converting to/from MultiHash
in each public function. For the serialization though we will likely use a tree property instead of a node property.
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.
Got it
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 it's relevant to check the type of hash of the leafs, in fact we can just treat them as abstract blobs. We should just have this as a property of the entire tree.
In fact, we have some potential use cases, where the leafs can be pretty much anything, for example KZG commitments...
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've address this by hardcoding a hashing algorithm for merkle trees tho SHA-256 in #516
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.
Looks good to me!
|
||
test "tree with three leaves has expected root": | ||
let | ||
expectedRoot = combine(combine(leaves[0], leaves[1]), combine(leaves[2], leaves[2])) |
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.
Looks like you're duplicating the last element when the tree is odd? It would probably be better to use a specific "null node".
The reason comes from reviewing the Bitcoin merkle trees there were some issues with duplicating issues at the end. With a properly constructed dataset in Bitcoin you could do a denial-of-service. See CVE-2012-2459.
There was a proposal for a better merkle design for Bitcoin at BIP-98. It describes the issue better. I didn't dive much into the proof side of things (maybe it's better).
It may all not apply to us, but I think prudence would say to use the fixes others did in 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.
@gmega your question about balanced merkle tree reminded me of this
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.
Fixed in the #516
proc init*( | ||
T: type MerkleTree, | ||
leaves: seq[MerkleHash] | ||
): ?!MerkleTree = |
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.
Could you add a short description noting the ordering of the nodes? When this comes up later it's nice to know "leaves start at 0..k, with proofs being k+1..n" or something similar.
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.
P.S. you could also add docs to the module. Just use ##
like ## about this module
as the comment block type and Nim doc gen will turn it into a module doc.
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.
Fixed in the #516
T: type MerkleProof, | ||
index: int, | ||
path: seq[MerkleHash] | ||
): MerkleProof = |
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.
Same as above! Just enough details to what the proof is of.
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.
Fixed in the #516
Ok, created an issue to follow up on the pre-image attack thing to get this unblocked: #511 |
index: int | ||
path: seq[MerkleHash] | ||
|
||
# Tree constructed from leaves H0..H2 is |
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.
Thanks for documenting this!
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.
Thanks! Note if you use ##
here then it'd show up if we ever run docgen. :)
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.
Fixed in #516
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.
OK, I think this is looking good for a first pass.
We're missing proof validation (or am I blind?) and and tree validation when constructed with a merkle root. We can cover that in a separate PR tho.
We should also address the security concernes, but I'd leave it for a separate PR as well.
@@ -0,0 +1,189 @@ | |||
## Nim-Codex | |||
## Copyright (c) 2022 Status Research & Development GmbH |
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.
## Copyright (c) 2022 Status Research & Development GmbH | |
## Copyright (c) 2023 Status Research & Development GmbH |
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.
Fixed in #516
I'm going to address all of the comments in the upcoming PR. |
No description provided.