-
Notifications
You must be signed in to change notification settings - Fork 38.7k
Deduplicate CMerkleBlock construction code, add test coverage #11293
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
Conversation
700a113 to
5bd892c
Compare
|
Concept ACK. Very nice! :-) |
promag
left a comment
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.
Separate refactor and test in 2 commits?
src/merkleblock.h
Outdated
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.
Instead of pointers, you can make it receive references, just pass either CBloomFilter() or std::set<uint256>(), and remove the != nullptr conditions above. Note that CBloomFilter is optimized when it is empty.
If you do this then this constructor can be public.
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 will work in the case of filter being unused. I'm getting the following compilation error:
In file included from merkleblock.cpp:6:0:
merkleblock.h: In constructor ‘CMerkleBlock::CMerkleBlock(const CBlock&, const std::set<uint256>&)’:
merkleblock.h:145:93: error: invalid initialization of non-const reference of type ‘CBloomFilter&’ from an rvalue of type ‘CBloomFilter’
CMerkleBlock(const CBlock& block, const std::set<uint256>& txids) : CMerkleBlock(block, CBloomFilter(), txids) {}
^~~~~~~~~~~~~~
merkleblock.h:148:5: note: initializing argument 2 of ‘CMerkleBlock::CMerkleBlock(const CBlock&, CBloomFilter&, const std::set<uint256>&)’
CMerkleBlock(const CBlock& block, CBloomFilter& filter, const std::set<uint256>& txids);
^~~~~~~~~~~~
Apparently we can't create an unnamed, non-const CBloomFilter reference from an rvalue. I'm not sure how to avoid this when using constructor delegation.
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.
You're not allowed to pass a temporary into a method that expects a non-const reference. Non-const references are intended for output arguments, and passing a temporary would mean there is effectively no output argument the caller can observe.
It seems to be that using a pointer which can be optionally nullptr is the correct approach here.
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.
Should have tested my suggestion. Agree with this approach.
5bd892c to
75d8f46
Compare
|
@promag I've split this into two commits as requested. Thanks for the look. |
src/merkleblock.cpp
Outdated
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.
You can avoid constructing an intermediate std::pair<unsigned int, uint256>, by using:
vMatchedTxn.emplace_back(i, hash);
src/merkleblock.cpp
Outdated
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.
Use txids->count(hash) instead.
src/merkleblock.cpp
Outdated
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.
Use filter->IsRelevantAndUpdate(*block.vtx[i]).
75d8f46 to
1f6fe13
Compare
|
Changed per feedback; thanks @sipa. |
promag
left a comment
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.
utACK, some nits though.
src/merkleblock.h
Outdated
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.
Should have tested my suggestion. Agree with this approach.
src/test/bloom_tests.cpp
Outdated
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.
Nit, move before #include "random.h".
src/merkleblock.cpp
Outdated
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.
Nit, just
if (txids && txids->count(hash)) {Same below.
1f6fe13 to
17dd097
Compare
|
Incorporated feedback; thanks @promag. |
|
utACK 17dd0973a63706717905bb3865129a32a4287adf |
TheBlueMatt
left a comment
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, would be nice to test a few more things since the goal is to add test coverage.
src/test/merkleblock_tests.cpp
Outdated
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.
You've added a bunch of trailing whitespace in this file (as well as test_bitcoin.cpp in 2 places and test_bitcoin.h in one). If you re-push this PR should fail travis due to #11300.
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.
Ah, totally right. Editor config adjusted -- thanks.
src/test/merkleblock_tests.cpp
Outdated
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.
Seems a strange thing to test, here? Maybe document on merkleblock.h what this thing even means? (ie "Set only when constructing from a bloom filter to allow testing the set of things which matched the bloom filter directly").
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.
Comment added inline with test as well as merkleblock.h. Basically just used your copy directly.
src/test/merkleblock_tests.cpp
Outdated
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.
Would be neat to also test the vIndex values here, too, no?
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.
Good idea! Added.
Incorporates feedback suggested by @sipa, @promag, @TheBlueMatt.
17dd097 to
46ce223
Compare
|
@TheBlueMatt thanks for the look. I've updated the tests to be a little more comprehensive per your feedback. |
|
utACK 46ce223 |
1 similar comment
|
utACK 46ce223 |
|
Anything else needed here @laanwj? |
gmaxwell
left a comment
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.
ACK.
jnewbery
left a comment
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.
Tested ACK 46ce223
The constructor can only be called with txids or filter specified, not both. How about making that explicit in the implementation with a comment or an assert (or both)? eg:
diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp
index 3f07b4d..7fd2934 100644
--- a/src/merkleblock.cpp
+++ b/src/merkleblock.cpp
@@ -12,6 +12,9 @@
CMerkleBlock::CMerkleBlock(const CBlock& block, CBloomFilter* filter, const std::set<uint256>* txids)
{
+ // The constructor can only be called with filter or txids, not both.
+ assert(!filter or !txids);
+
header = block.GetBlockHeader();
std::vector<bool> vMatch;
|
utACK 46ce223 |
|
utACK 46ce223. |
…verage 46ce223 Add tests for CMerkleBlock usage with txids specified (James O'Beirne) 5ab586f Consolidate CMerkleBlock constructor into a single method (James O'Beirne) Pull request description: What started as a simple task to add test coverage ended up giving way to a light refactoring. This consolidates the mostly-identical `CMerkleBlock` constructors into one (using C++11 constructor delegation) and adds coverage for the by-txids construction case. ### Before  ### After  Tree-SHA512: eed84ed3e8bfc43473077b575c8252759a857e37275e4b36ca7cc2c17a65895e5f494bfd9d4aeab09fc6e98fc6a9c641ac7ecc0ddbeefe01a9e4308e7909e529
…verage Summary: 46ce223 Add tests for CMerkleBlock usage with txids specified (James O'Beirne) Pull request description: What started as a simple task to add test coverage ended up giving way to a light refactoring. This consolidates the mostly-identical `CMerkleBlock` constructors into one (using C++11 constructor delegation) and adds coverage for the by-txids construction case. ### Before  ### After  Tree-SHA512: eed84ed3e8bfc43473077b575c8252759a857e37275e4b36ca7cc2c17a65895e5f494bfd9d4aeab09fc6e98fc6a9c641ac7ecc0ddbeefe01a9e4308e7909e529 Changes made in D3371 conflict with the original PR; the constructor has been updated to the form it would take if D3371 would have been implemented after this refactoring. This private constructor is more strict than the original one (the original could be called with either, both, or neither of the `filter` and `txids` parameters). Partial backport of Core PR11293 bitcoin/bitcoin#11293 Also includes left over changes to PR12920 bitcoin/bitcoin#12920 Test Plan: make check ninja check Reviewers: deadalnix, Fabien, jasonbcox, O1 Bitcoin ABC, #bitcoin_abc, nakihito Reviewed By: deadalnix, Fabien, jasonbcox, O1 Bitcoin ABC, #bitcoin_abc, nakihito Differential Revision: https://reviews.bitcoinabc.org/D3689
…test coverage 46ce223 Add tests for CMerkleBlock usage with txids specified (James O'Beirne) 5ab586f Consolidate CMerkleBlock constructor into a single method (James O'Beirne) Pull request description: What started as a simple task to add test coverage ended up giving way to a light refactoring. This consolidates the mostly-identical `CMerkleBlock` constructors into one (using C++11 constructor delegation) and adds coverage for the by-txids construction case. ### Before  ### After  Tree-SHA512: eed84ed3e8bfc43473077b575c8252759a857e37275e4b36ca7cc2c17a65895e5f494bfd9d4aeab09fc6e98fc6a9c641ac7ecc0ddbeefe01a9e4308e7909e529
What started as a simple task to add test coverage ended up giving way to a light refactoring. This consolidates the mostly-identical
CMerkleBlockconstructors into one (using C++11 constructor delegation) and adds coverage for the by-txids construction case.Before
After