-
Notifications
You must be signed in to change notification settings - Fork 37.7k
Move orphan processing to ActivateBestChain #8930
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
9860cda
to
b4c3c3b
Compare
// Notifications/callbacks that can run without cs_main | ||
if(connman) | ||
connman->SetBestHeight(nNewHeight); | ||
|
||
|
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.
Useful.
@@ -3068,10 +3048,38 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, | |||
} | |||
// When we reach this point, we switched to a new tip (stored in pindexNewTip). | |||
|
|||
// Remove orphan transactions with cs_main | |||
{ | |||
LOCK(cs_main); |
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 hope we can separate nodestate and other message-processing related variables from cs_main...
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.
@sipa Absolutely, I'm planning on doing that after the dust settles here, unless @TheBlueMatt already has it queued up. I'm planning on moving lots of what's currently in CNode to CNodeState, so breaking out the locks is a prerequisite for that.
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.
Dont have it queued up, but, indeed, thats an obvious change after we split main.cpp.
Closing for now. Will rebase on #9075 when its merged. |
This further decouples "main" and "net" processing logic by moving orphan processing out of the chain-connecting cs_main lock and into its own cs_main lock, beside all of the other chain callbacks. Once further decoupling of net and main processing logic occurs, orphan handing should move to its own lock, out of cs_main. Note that this will introduce a race if there are any cases where we assume the orphan map to be consistent with the current chain tip, however I am confident there is no such case (ATMP will fail without DoS score in all such cases).
b4c3c3b
to
2dd652a
Compare
Rebased on #9075...this now forms the last pull before main.cpp is split clean in two :). |
utACK 2dd652a |
What is the rationale behind this refactoring please? What future changes is it enabling? Or what is it fixing? |
Decoupling unrelated logic to be able to split up main into validation and network handling parts. |
@TheBlueMatt One thing we don't currently do, but probably should, is try to reaccept orphan transactions to the mempool if their missing inputs appear in a block. After this PR, would you suggest we just do that inside |
utACK. You could get rid of the BOOST_FOREACH along the way, if you wish. |
@sdaftuar that seems reasonable, yea. Not for this PR, though, indeed. |
utACK |
@@ -4744,6 +4724,30 @@ PeerLogicValidation::PeerLogicValidation(CConnman* connmanIn) : connman(connmanI | |||
recentRejects.reset(new CRollingBloomFilter(120000, 0.000001)); | |||
} | |||
|
|||
void PeerLogicValidation::SyncTransaction(const CTransaction& tx, const CBlockIndex* pindex, int nPosInBlock) { | |||
LOCK(cs_main); |
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.
Shouldn't this check against CMainSignals::SYNC_TRANSACTION_NOT_IN_BLOCK?
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.
Hmmmmm...good point...for corectness I'll add that check to this PR, but I think we probably actually want to remove it in a future one since I believe it would allow us to clean up orphan cleanup logic in the ::TX message handling logic.
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.
Yep, makes sense. But for now, it can at least be a short-circuit for returning without locking cs_main (not sure if there's any unlocked caller who would benefit, 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.
Done
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.
@TheBlueMatt Your comment confuses me a bit. Wouldn't this be broken without that check?
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.
@morcos it was a reference to the fact that we might want to remove orphan transactions which conflict with txn which were added to mempool, instead of doing that work in the ::TX message handling. I believe without the check they would step all over each other, but this could be fixed in the future.
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 agree, nice to move all logic to this function.
But for now, we don't actually remove orphan txs which conflict with things accepted to mempool. We could, however, move recursive processing of orphan txs that depended on mempool accepted txs here, I agree.
Also there are other places SyncTransaction is called, such as for disconnected block txs, where it would be incorrect to remove orphan txs which conflict with txs from disconnected blocks.
In any case, the code is correct now, I just want to be sure we think about all the ways SyncTransaction is called when we change it in the future.
2dd652a
to
f733b49
Compare
This makes the orphan map a part of net-processing logic instead of main logic.
f733b49
to
d2b88f9
Compare
utACK d2b88f9 |
for (auto mi = itByPrev->second.begin(); mi != itByPrev->second.end(); ++mi) { | ||
const CTransaction& orphanTx = (*mi)->second.tx; | ||
const uint256& orphanHash = orphanTx.GetHash(); | ||
vOrphanErase.push_back(orphanHash); |
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.
Why create vOrphanErase at all? Why not simply run the EraseOrphanTx() here instead?
Based on #8928 because its the only way I can run tests.
This will conflict a bit with #8865, but that's easy to resolve, and I'd rather get some eyeballs on this sooner rather than later, so am leaving it freestanding. Once #8865 goes in the orphan processing will go into the CValidationInterface which manges "net processing" stuff.
This further decouples "main" and "net" processing logic by moving
orphan processing out of the chain-connecting cs_main lock and
into its own cs_main lock, beside all of the other chain callbacks.
Once further decoupling of net and main processing logic occurs,
orphan handing should move to its own lock, out of cs_main.
Note that this will introduce a race if there are any cases where
we assume the orphan map to be consistent with the current chain
tip, however I am confident there is no such case (ATMP will fail
without DoS score in all such cases).