-
Notifications
You must be signed in to change notification settings - Fork 37.7k
refactor: Make mapBlocksUnknownParent local, and rename it #19594
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
Friendly ping @LarryRuane :) |
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
Concept ACK: local is easier to reason about :) |
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 adc08e1
Looks good, very nice PR, better than I could have done! I did some basic testing (ran bitcoind -reindex
).
Here's a slightly tangential suggestion, as long as you're changing this code, to eliminate one level of looping:
while (!queue.empty()) {
const uint256& head = queue.front();
auto it = blocks_with_unknown_parent->find(head);
if (it == blocks_with_unknown_parent->end()) {
queue.pop_front();
continue;
}
std::shared_ptr<CBlock> pblockrecursive = std::make_shared<CBlock>();
if (ReadBlockFromDisk(*pblockrecursive, it->second, chainparams.GetConsensus()))
{
LogPrint(BCLog::REINDEX, "%s: Processing out of order child %s of %s\n", __func__, pblockrecursive->GetHash().ToString(),
head.ToString());
LOCK(cs_main);
BlockValidationState dummy;
if (::ChainstateActive().AcceptBlock(pblockrecursive, dummy, chainparams, nullptr, true, &it->second, nullptr))
{
nLoaded++;
queue.push_back(pblockrecursive->GetHash());
}
}
blocks_with_unknown_parent->erase(it);
NotifyHeaderTip();
}
@@ -4752,15 +4758,17 @@ void LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, FlatFi | |||
|
|||
NotifyHeaderTip(); | |||
|
|||
if (!blocks_with_unknown_parent) continue; |
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.
Nice! It was hard to understand the previous code when !dbp
.
range.first++; | ||
mapBlocksUnknownParent.erase(it); | ||
blocks_with_unknown_parent->erase(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.
range.first++; | |
mapBlocksUnknownParent.erase(it); | |
blocks_with_unknown_parent->erase(it); | |
range.first = blocks_with_unknown_parent->erase(it); |
As written this is safe with this container type, but the assignment makes fewer assumptions (and is one less line of code!).
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.
Agree. But current diff is minimal :)
if (dbp && blocks_with_unknown_parent) { | ||
blocks_with_unknown_parent->emplace(block.hashPrevBlock, *dbp); | ||
} |
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 could test either variable here (probably blocks_with_unknown_parent
would be best), but I assume you're testing both since the code references both. The only downside is it could lead the casual reader to think that only one of these could be nullptr
and not the other. The emplace
simplification is nice 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.
... but I assume you're testing both since the code references both.
Correct.
Let's keep this PR diff minimal and focused :) |
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.
Concept ACK.
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.
Code review ACK adc08e1
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.
Code Review ACK adc08e1 🧇
|
code review ACK adc08e1 but I think OP should be updated. code currently is a pure refactor to maintain less global state. however, OP also has section that asks "what happens if there are leftover entries in this map after reindexing has completed", which I don't believe is addressed in this PR? tangential question: is |
The OP does mention logging if there are entries leftover entries, and I think that would be a good idea. But no other recovery is necessary, because the client will download the missing blocks from peers (I've verified this). While working on zcash, I recently looked into the
I could make a small PR to remove |
me:
On further thought, we shouldn't do this, because I can easily imagine that it may be currently used for testing (outside of our repo), for example, with |
@amitiuttarwar The purpose of |
It should also be possible to specify all block files of another datadir via multiple |
No, because when using We could add an unknown parents map to the |
right, sure, I think logging would make sense, but I'm talking about the difference between OP and code changes. Unless I'm mistaken, the code doesn't address this, so its misleading to talk about in the OP. additional logging could be added to this PR or it could be addressed in a separate PR, but the code & description should match :) RE:
on irc @sipa said
as Larry said, one reason but again, I don't think this is the most relevant to this PR. I current don't feel any conclusive evidence towards removing |
🐙 This pull request conflicts with the target branch and needs rebase. Want to unsubscribe from rebase notifications on this pull request? Just convert this pull request to a "draft". |
This will also fix an issue where the fuzz test goes OOM when running too long |
There hasn't been much activity lately and the patch still needs rebase. What is the status here?
|
I won't be able to focus on this stuff in the near future. So closing up for grabs. |
…cal, and rename it dd065da refactor: Make mapBlocksUnknownParent local, and rename it (Hennadii Stepanov) Pull request description: This PR is a second attempt at #19594. This PR has two motivations: - Improve code hygiene by eliminating a global variable, `mapBlocksUnknownParent` - Fix fuzz test OOM when running too long ([see #19594 comment](bitcoin/bitcoin#19594 (comment))) A minor added advantage is to release `mapBlocksUnknownParent` memory when the reindexing phase is done. The current situation is somewhat similar to a memory leak because this map exists unused for the remaining lifetime of the process. It's true that this map should be empty of data elements after use, but its internal metadata (indexing structures, etc.) can have non-trivial size because there can be many thousands of simultaneous elements in this map. This PR helps our efforts to reduce the use of global variables. This variable isn't just global, it's hidden inside a function (it looks like a local variable but has the `static` attribute). This global variable exists because the `-reindex` processing code calls `LoadExternalBlockFile()` multiple times (once for each block file), but that function must preserve some state between calls (the `mapBlocksUnknownParent` map). This PR fixes this by allocating this map as a local variable in the caller's scope and passing it in on each call. When reindexing completes, the map goes out of scope and is deallocated. I tested this manually by reindexing on mainnet and signet. Also, the existing `feature_reindex.py` functional test passes. ACKs for top commit: mzumsande: re-ACK dd065da theStack: re-ACK dd065da shaavan: reACK dd065da Tree-SHA512: 9cd20e44d2fa1096dd405bc107bc065ea8f904f5b3f63080341b08d8cf57b790df565f58815c2f331377d044d5306708b4bf6bdfc5ef8d0ed85d8e97d744732c
LarryRuane's comment in #16981: