|
|
@ -3787,7 +3787,7 @@ static bool AcceptBlock(const CBlock& block, CValidationState& state, const CCha
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp, bool *fNewBlock)
|
|
|
|
bool ProcessNewBlock(const CChainParams& chainparams, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp, bool *fNewBlock)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
{
|
|
|
|
{
|
|
|
|
LOCK(cs_main);
|
|
|
|
LOCK(cs_main);
|
|
|
@ -3795,14 +3795,18 @@ bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, c
|
|
|
|
// Store to disk
|
|
|
|
// Store to disk
|
|
|
|
CBlockIndex *pindex = NULL;
|
|
|
|
CBlockIndex *pindex = NULL;
|
|
|
|
if (fNewBlock) *fNewBlock = false;
|
|
|
|
if (fNewBlock) *fNewBlock = false;
|
|
|
|
|
|
|
|
CValidationState state;
|
|
|
|
bool ret = AcceptBlock(*pblock, state, chainparams, &pindex, fForceProcessing, dbp, fNewBlock);
|
|
|
|
bool ret = AcceptBlock(*pblock, state, chainparams, &pindex, fForceProcessing, dbp, fNewBlock);
|
|
|
|
CheckBlockIndex(chainparams.GetConsensus());
|
|
|
|
CheckBlockIndex(chainparams.GetConsensus());
|
|
|
|
if (!ret)
|
|
|
|
if (!ret) {
|
|
|
|
|
|
|
|
GetMainSignals().BlockChecked(*pblock, state);
|
|
|
|
return error("%s: AcceptBlock FAILED", __func__);
|
|
|
|
return error("%s: AcceptBlock FAILED", __func__);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NotifyHeaderTip();
|
|
|
|
NotifyHeaderTip();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CValidationState state; // Only used to report errors, not invalidity - ignore it
|
|
|
|
if (!ActivateBestChain(state, chainparams, pblock))
|
|
|
|
if (!ActivateBestChain(state, chainparams, pblock))
|
|
|
|
return error("%s: ActivateBestChain failed", __func__);
|
|
|
|
return error("%s: ActivateBestChain failed", __func__);
|
|
|
|
|
|
|
|
|
|
|
@ -5912,26 +5916,18 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
|
|
|
fBlockRead = true;
|
|
|
|
fBlockRead = true;
|
|
|
|
// mapBlockSource is only used for sending reject messages and DoS scores,
|
|
|
|
// mapBlockSource is only used for sending reject messages and DoS scores,
|
|
|
|
// so the race between here and cs_main in ProcessNewBlock is fine.
|
|
|
|
// 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));
|
|
|
|
mapBlockSource.emplace(resp.blockhash, std::make_pair(pfrom->GetId(), false));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} // Don't hold cs_main when we call into ProcessNewBlock
|
|
|
|
} // Don't hold cs_main when we call into ProcessNewBlock
|
|
|
|
if (fBlockRead) {
|
|
|
|
if (fBlockRead) {
|
|
|
|
CValidationState state;
|
|
|
|
|
|
|
|
bool fNewBlock = false;
|
|
|
|
bool fNewBlock = false;
|
|
|
|
// Since we requested this block (it was in mapBlocksInFlight), force it to be processed,
|
|
|
|
// 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)
|
|
|
|
// 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
|
|
|
|
ProcessNewBlock(chainparams, &block, true, NULL, &fNewBlock);
|
|
|
|
// the header only; we should not punish peers if the block turns
|
|
|
|
if (fNewBlock)
|
|
|
|
// out to be invalid.
|
|
|
|
|
|
|
|
ProcessNewBlock(state, chainparams, &block, true, NULL, &fNewBlock);
|
|
|
|
|
|
|
|
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());
|
|
|
|
|
|
|
|
LOCK(cs_main);
|
|
|
|
|
|
|
|
mapBlockSource.erase(resp.blockhash);
|
|
|
|
|
|
|
|
} else if (fNewBlock)
|
|
|
|
|
|
|
|
pfrom->nLastBlockTime = GetTime();
|
|
|
|
pfrom->nLastBlockTime = GetTime();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -6090,7 +6086,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
|
|
|
|
|
|
|
|
|
|
|
LogPrint("net", "received block %s peer=%d\n", block.GetHash().ToString(), pfrom->id);
|
|
|
|
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,
|
|
|
|
// Process all blocks from whitelisted peers, even if not requested,
|
|
|
|
// unless we're still syncing with the network.
|
|
|
|
// unless we're still syncing with the network.
|
|
|
|
// Such an unrequested block may still be processed, subject to the
|
|
|
|
// Such an unrequested block may still be processed, subject to the
|
|
|
@ -6107,21 +6102,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
|
|
|
mapBlockSource.emplace(hash, std::make_pair(pfrom->GetId(), true));
|
|
|
|
mapBlockSource.emplace(hash, std::make_pair(pfrom->GetId(), true));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bool fNewBlock = false;
|
|
|
|
bool fNewBlock = false;
|
|
|
|
ProcessNewBlock(state, chainparams, &block, forceProcessing, NULL, &fNewBlock);
|
|
|
|
ProcessNewBlock(chainparams, &block, forceProcessing, NULL, &fNewBlock);
|
|
|
|
int nDoS;
|
|
|
|
if (fNewBlock)
|
|
|
|
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);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
LOCK(cs_main);
|
|
|
|
|
|
|
|
mapBlockSource.erase(hash);
|
|
|
|
|
|
|
|
} else if (fNewBlock)
|
|
|
|
|
|
|
|
pfrom->nLastBlockTime = GetTime();
|
|
|
|
pfrom->nLastBlockTime = GetTime();
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|