aboutsummaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2016-11-17 13:08:30 -0800
committerPieter Wuille <pieter.wuille@gmail.com>2016-11-17 13:23:50 -0800
commit9346f8429957e356d21c665bab59fe45bcf1f74e (patch)
treea4d65bb5589741c522c6c13ba20448abf7e64913 /src/main.cpp
parenta8b2a82618bec43977a65c076f691ec1cddd54be (diff)
parentae223576077448bd4ec250c73f5d8fe5e9a9ac7d (diff)
downloadbitcoin-9346f8429957e356d21c665bab59fe45bcf1f74e.tar.xz
Merge #9075: Decouple peer-processing-logic from block-connection-logic (#3)
ae22357 Replace CValidationState param in ProcessNewBlock with BlockChecked (Matt Corallo) 7c98ce5 Remove pfrom parameter from ProcessNewBlock (Matt Corallo) e2e069d Revert "RPC: Give more details when "generate" fails" (Matt Corallo)
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp60
1 files changed, 27 insertions, 33 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 10f9b15ec6..263421aea4 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -3788,26 +3788,26 @@ static bool AcceptBlock(const CBlock& block, CValidationState& state, const CCha
return true;
}
-bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, CNode* pfrom, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp, bool fMayBanPeerIfInvalid)
+bool ProcessNewBlock(const CChainParams& chainparams, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp, bool *fNewBlock)
{
{
LOCK(cs_main);
// Store to disk
CBlockIndex *pindex = NULL;
- bool fNewBlock = false;
- bool ret = AcceptBlock(*pblock, state, chainparams, &pindex, fForceProcessing, dbp, &fNewBlock);
- if (pindex && pfrom) {
- mapBlockSource[pindex->GetBlockHash()] = std::make_pair(pfrom->GetId(), fMayBanPeerIfInvalid);
- if (fNewBlock) pfrom->nLastBlockTime = GetTime();
- }
+ if (fNewBlock) *fNewBlock = false;
+ CValidationState state;
+ bool ret = AcceptBlock(*pblock, state, chainparams, &pindex, fForceProcessing, dbp, fNewBlock);
CheckBlockIndex(chainparams.GetConsensus());
- if (!ret)
+ if (!ret) {
+ GetMainSignals().BlockChecked(*pblock, state);
return error("%s: AcceptBlock FAILED", __func__);
+ }
}
NotifyHeaderTip();
+ CValidationState state; // Only used to report errors, not invalidity - ignore it
if (!ActivateBestChain(state, chainparams, pblock))
return error("%s: ActivateBestChain failed", __func__);
@@ -5927,22 +5927,21 @@ 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,
+ // so the race between here and cs_main in ProcessNewBlock is fine.
+ // BIP 152 permits peers to relay compact blocks after validating
+ // the header only; we should not punish peers if the block turns
+ // out to be invalid.
+ mapBlockSource.emplace(resp.blockhash, std::make_pair(pfrom->GetId(), false));
}
} // Don't hold cs_main when we call into ProcessNewBlock
if (fBlockRead) {
- CValidationState state;
+ bool fNewBlock = false;
// Since we requested this block (it was in mapBlocksInFlight), force it to be processed,
// even if it would not be a candidate for new tip (missing previous block, chain not long enough, etc)
- // BIP 152 permits peers to relay compact blocks after validating
- // the header only; we should not punish peers if the block turns
- // out to be invalid.
- ProcessNewBlock(state, chainparams, pfrom, &block, true, NULL, false);
- int nDoS;
- if (state.IsInvalid(nDoS)) {
- assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes
- connman.PushMessage(pfrom, NetMsgType::REJECT, strCommand, (unsigned char)state.GetRejectCode(),
- state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), block.GetHash());
- }
+ ProcessNewBlock(chainparams, &block, true, NULL, &fNewBlock);
+ if (fNewBlock)
+ pfrom->nLastBlockTime = GetTime();
}
}
@@ -6100,30 +6099,25 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
LogPrint("net", "received block %s peer=%d\n", block.GetHash().ToString(), pfrom->id);
- CValidationState state;
// Process all blocks from whitelisted peers, even if not requested,
// unless we're still syncing with the network.
// Such an unrequested block may still be processed, subject to the
// conditions in AcceptBlock().
bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload();
+ const uint256 hash(block.GetHash());
{
LOCK(cs_main);
// Also always process if we requested the block explicitly, as we may
// need it even though it is not a candidate for a new best tip.
- forceProcessing |= MarkBlockAsReceived(block.GetHash());
+ 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.
+ mapBlockSource.emplace(hash, std::make_pair(pfrom->GetId(), true));
}
- ProcessNewBlock(state, chainparams, pfrom, &block, forceProcessing, NULL, true);
- int nDoS;
- if (state.IsInvalid(nDoS)) {
- assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes
- connman.PushMessage(pfrom, NetMsgType::REJECT, strCommand, (unsigned char)state.GetRejectCode(),
- state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), block.GetHash());
- if (nDoS > 0) {
- LOCK(cs_main);
- Misbehaving(pfrom->GetId(), nDoS);
- }
- }
-
+ bool fNewBlock = false;
+ ProcessNewBlock(chainparams, &block, forceProcessing, NULL, &fNewBlock);
+ if (fNewBlock)
+ pfrom->nLastBlockTime = GetTime();
}