Add trait bound to Merkle tree method; fix typing#2864
Add trait bound to Merkle tree method; fix typing#2864apoelstra merged 7 commits intorust-bitcoin:masterfrom
Conversation
60dce23 to
4dec788
Compare
Pull Request Test Coverage Report for Build 9501833057Details
💛 - Coveralls |
tcharding
left a comment
There was a problem hiding this comment.
Thanks for putting this up, I would have never got here because I was stuck on the inline conundrum. I particular like the combine function.
bitcoin/src/merkle_tree/mod.rs
Outdated
There was a problem hiding this comment.
This moves the problem I described (that I thought needed unsafe to solve) onto the user.
Said another way, what is the point of providing this function now, presumably the caller has a vector of Txids and needs to convert them to MerkleNode implementors?
There was a problem hiding this comment.
We could take the pub away if it worries you. It is only used within the library as a helper function to implement calculate_root, and it exists to theoretically allow people to implement calculate_root without any allocations.
I doubt it has ever been actually used by anybody else in the history of this library.
There was a problem hiding this comment.
BTW the algorithm implemented here is super memory-wasteful and bizarrely combines recursion with an explicit Vec, giving us the worst of both worlds (and spread across 3 functions for some reason). I'll do a followup PR that fixes this since I'm looking at it.
There was a problem hiding this comment.
Nah, I'll just do it here. If I'm breaking the API I should go all the way. Added two commits.
Pull Request Test Coverage Report for Build 9518993748Warning: This coverage report may be inaccurate.This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.
Details
💛 - Coveralls |
|
Looks good, its non-trivial to review for me though. Perhaps we should have some regression tests before we make the change? Currently only one unit test. |
|
@tcharding there are like a dozen regression tests in merkle_tree/block.rs, and the "one unit test" is also a regression test. Try changing the tree algorithm and see how much breaks. |
7384679 to
1835605
Compare
Pull Request Test Coverage Report for Build 9528363460Details
💛 - Coveralls |
Pull Request Test Coverage Report for Build 9528371517Details
💛 - Coveralls |
1835605 to
4cf9752
Compare
Pull Request Test Coverage Report for Build 9536877191Details
💛 - Coveralls |
Pull Request Test Coverage Report for Build 9536960269Details
💛 - Coveralls |
|
My bad, I appreciate you have also probably written this algorithm a dozen times before. I was sick in bed reviewing and had zero confidence in my ability to fully grok the change. I didn't look in ACK 66ca2c20519b726e3c5931d6b99eedc3aec60106 |
bitcoin/src/merkle_tree/mod.rs
Outdated
There was a problem hiding this comment.
Coming back for a post ack review :)
Perhaps:
/// Converts a hash to a leaf node of the tree.
fn from_leaf(leaf: Self::Leaf) -> Self;
/// Combines two nodes to get a single node.
///
/// The final node of the tree is the Merkle root.
fn combine(&self, other: &Self) -> Self;
bitcoin/src/merkle_tree/mod.rs
Outdated
There was a problem hiding this comment.
| /// Returns `None` iff the iterator was empty. | |
| /// # Returns | |
| /// | |
| /// Returns `None` iff the iterator was empty. |
Kixunil
left a comment
There was a problem hiding this comment.
ACK 66ca2c20519b726e3c5931d6b99eedc3aec60106
Nice changes overall!
bitcoin/src/merkle_tree/mod.rs
Outdated
There was a problem hiding this comment.
I find n /= 2 more readable
bitcoin/src/merkle_tree/mod.rs
Outdated
There was a problem hiding this comment.
n + 2 == 1 is more readable, the compiler knows how to optimize it.
|
One more thing: this does not address Taproot. I don't remember what the differences are. Can we unify them? |
Unfortunately not. The differences in Taproot are:
It's the last two points where we have a meaningfully different tree algorithm and I don't think it makes sense to unify them. |
I believe you're right then. Might be worth mention in the code. |
Currently we are defining the two merkle tree hash types in the `block` module, a better home for them is the `merkle_tree` module. This is an API breaking change because the types were public in the `block` module, however the change should/could be unnoticeable to users if they use the crate level re-export - which is maintained.
These are pretty noisy but it's just a move.
These changes are nontrivial. They * Drop the `From` impls from (w)txids to (w)TxMerkleRoots * Introduce a new trait and bound calculate_root on it... * ...in such a way that its return value cannot be inferred without further hints (though in practice this doesn't matter because usually the return value is immediately assigned to something with a known type such as a BlockHeader field)
Drop recursion, reduce memory usage to be logarithmic in size of tree rather than linear, and put it all in one function rather than three. Also make the method an trait method on MerkleNode which makes it a easier on type inference, by writing e.g. TxMerkleNode::calculate_root.
66ca2c2 to
90b6d67
Compare
|
Rebased and expanded comment. |
Pull Request Test Coverage Report for Build 9568518880Details
💛 - Coveralls |
Alternate to #2853. Takes patch 1 from that PR.