-
Notifications
You must be signed in to change notification settings - Fork 37.7k
Decouple peer-processing-logic from block-connection-logic (#3) #9075
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
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
@@ -2976,8 +2976,6 @@ static bool ActivateBestChainStep(CValidationState& state, const CChainParams& c | |||
if (!ConnectTip(state, chainparams, pindexConnect, pindexConnect == pindexMostWork ? pblock : NULL, txConflicted, txChanged)) { | |||
if (state.IsInvalid()) { | |||
// The block violates a consensus rule. | |||
if (!state.CorruptionPossible()) |
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.
This does not actually remove a duplicate. If there is a reorganization, and some block within it is invalid, InvalidChainFound
will be called with the tip of the chain, rather than the block that failed. This may have an effect on the large fork detection 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.
Eek! Youre right. Just removed the commit...it wasnt important anyway.
forceProcessing |= MarkBlockAsReceived(hash); | ||
// mapBlockSource is only used for sending reject messages and DoS scores, | ||
// so the race between here and cs_main in ProcessNewBlock is fine. | ||
if (!mapBlockSource.count(hash)) |
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: You can use std::map::emplace here to avoid two searches (the bool returned in the pair tells you whether an insert occurred or now). You could also remember the created iterator and pass it to mapBlockSource.erase below. (and likewise above)
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
// out to be invalid. | ||
ProcessNewBlock(state, chainparams, &block, true, NULL, &fNewBlock); | ||
int nDoS; | ||
if (state.IsInvalid(nDoS)) { |
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.
So glad to see this duplication go!
2e30cb4
to
9ab2086
Compare
Needs rebase. |
9ab2086
to
dbaf9ee
Compare
Rebased. |
@@ -5914,22 +5910,29 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, | |||
// updated, reject messages go out, etc. | |||
MarkBlockAsReceived(resp.blockhash); // it is now an empty pointer | |||
fBlockRead = true; | |||
// mapBlockSource is only used for sending reject messages and DoS scores, |
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.
Stale comment? Or am I not seeing the race?
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.
Race if multiple nodes send you something near the same time you might send the DoS/Reject to the "wrong" node, of course we dont really care because we'll get to them next time they send us a block (and someone will still get 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 assumed this just referred to the fact that we drop the cs_main lock between here and the call to ProcessNewBlock
below, so in theory mapBlockSource could be modified in between, and we'd lose the expected callbacks.
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. After discussion on IRC, I'm good with this. Though the comment could be a bit more descriptive, it makes the issue seem like more than it is.
This only returned information in the case of CheckBlock failure, but breaks future changes.
This further decouples ProcessNewBlock from networking/peer logic.
dbaf9ee
to
ae22357
Compare
As mentioned on IRC, this now reverts #9087, which conflicted, but no one registered any serious desire to maintain its functionality since it was realtively trivial. |
utACK ae22357 |
utACK ae22357 other than the comment nit. Obviously not a blocker though. |
state = sc.state; | ||
} | ||
return BIP22ValidationResult(state); | ||
if (!sc.found) |
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.
not sure why this shouldn't be if (fAccepted && !sc.found)
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.
If it is not accepted, there will certainly have been a callback to signal what was invalid about it. Thus, not having had a signal implies it was accepted.
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.
Technically this is a change in behavior...previously: if you got an error (disk space, etc) during connection you would print it in the BIP22 result function, after this patch (though, indeed, adding an fAccepted check wouldnt help) you will no longer print that, and your node will just exit (probably after retuning "success" from this function.
} | ||
|
||
NotifyHeaderTip(); | ||
|
||
CValidationState state; // Only used to report errors, not invalidity - ignore 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.
you don't need to duplicate CValidationState state, you can move the first declaration out of the locked context.
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.
Personally I like making it clear that this CValidationState is unrelated to the other one; it was confusing in the old code that validation errors from different blocks might get put in the same CValidationState (which would get cleared out in ActivateBestChainStep).
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.
Not a big deal anyway.
ut ACK ae22357 apart from the couple of small nits. |
utACK ae22357 |
Is this change part of a roadmap that is documented somewhere? |
@rebroad It is part of a longer branch by @TheBlueMatt : https://github.com/TheBlueMatt/bitcoin/tree/net_processing_file which does enough decoupling to cleanly separate the p2p messages part out of main.o. But I think the PRs (and commits) stand on their own (I did less review on the previous steps). Perhaps @TheBlueMatt can give more details. |
@jtimon thanks. I also meant to ask: why is this being done? Is it because main.cpp is considered to be too large? |
@rebroad Splitting main into several files would be trivial to do, if we don't care much about clean separation between the resulting files. This PR is part of an ongoing effort to separate network processing (currently spread over net, protocol, and main) and block validation with clear interfaces between them. The end result is not only splitting main into two files, but splitting it into two files that each have clearly-separated responsibilities. |
Yet another step towards splitting main.cpp. After this and #8930 (which I will rebase after this is merged to clean it up a ton), we're ready to do the big code moves :).
This PR focuses on mapBlockSource, removing references to it from ProcessNewBlock and moving it to callsites, cleaning up logic in the process.
Built on #9026 to avoid conflicts and simplify the backporting (#9048).