Skip to content

Commit

Permalink
Instead of DoS banning for invalid blocks, merely disconnect nodes if…
Browse files Browse the repository at this point in the history
… we're relying on them as a primary node

Github-Pull: bitcoin#10593
Rebased-From: 35433a2
  • Loading branch information
luke-jr committed Jun 15, 2017
1 parent 09566ee commit 73ad56d
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 6 deletions.
5 changes: 5 additions & 0 deletions src/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,11 @@ class CNode
return nLocalServices;
}

bool PunishInvalidBlocks() const
{
return !(fInbound || fFeeler || fWhitelisted || fAddnode);
}

std::string GetAddrName() const;
//! Sets the addrName only if it was not previously set
void MaybeSetAddrName(const std::string& addrNameIn);
Expand Down
44 changes: 38 additions & 6 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -847,6 +847,30 @@ void PeerLogicValidation::UpdatedBlockTip(const CBlockIndex *pindexNew, const CB
nTimeBestReceived = GetTime();
}

namespace {

void HandleBlockDoS(std::string node_name, CNode * const pfrom, const int nDoS, const bool is_header) {
// We never actually DoS ban for invalid blocks, merely disconnect nodes if we're relying on them as a primary node
NodeId node_id = pfrom->GetId();
if (node_name.empty()) {
node_name = "(unknown)";
LOCK(cs_main);
CNodeState *nodestate = State(node_id);
if (nodestate) {
node_name = nodestate->name;
}
}
const std::string msg = strprintf("%s peer=%d got DoS score %d on invalid block%s", node_name, node_id, nDoS, is_header ? " header" : "");
if (pfrom->PunishInvalidBlocks()) {
LogPrint("net", "%s; simply disconnecting\n", msg);
pfrom->fDisconnect = true;
} else {
LogPrint("net", "%s; tolerating\n", msg);
}
}

}

void PeerLogicValidation::BlockChecked(const CBlock& block, const CValidationState& state) {
LOCK(cs_main);

Expand All @@ -857,10 +881,16 @@ void PeerLogicValidation::BlockChecked(const CBlock& block, const CValidationSta
if (state.IsInvalid(nDoS)) {
if (it != mapBlockSource.end() && State(it->second.first)) {
assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes
const NodeId node_id = it->second.first;
CNodeState * const nodestate = State(node_id);
CBlockReject reject = {(unsigned char)state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), hash};
State(it->second.first)->rejects.push_back(reject);
if (nDoS > 0 && it->second.second)
Misbehaving(it->second.first, nDoS);
if (nDoS > 0 && it->second.second) {
connman->ForNode(node_id, [nodestate, nDoS](CNode* pfrom){
HandleBlockDoS(nodestate->name, pfrom, nDoS, false);
return true;
});
}
}
}
// Check that:
Expand Down Expand Up @@ -1974,8 +2004,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
int nDoS;
if (state.IsInvalid(nDoS)) {
if (nDoS > 0) {
LOCK(cs_main);
Misbehaving(pfrom->GetId(), nDoS);
HandleBlockDoS("", pfrom, nDoS, true);
}
LogPrintf("Peer %d sent us invalid header via cmpctblock\n", pfrom->id);
return true;
Expand Down Expand Up @@ -2275,6 +2304,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
// we can use this peer to download.
UpdateBlockAvailability(pfrom->GetId(), headers.back().GetHash());

if (pfrom->PunishInvalidBlocks()) {
pfrom->fDisconnect = true;
}

return true;
}
}
Expand All @@ -2284,8 +2317,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
int nDoS;
if (state.IsInvalid(nDoS)) {
if (nDoS > 0) {
LOCK(cs_main);
Misbehaving(pfrom->GetId(), nDoS);
HandleBlockDoS("", pfrom, nDoS, true);
}
return error("invalid header received");
}
Expand Down

0 comments on commit 73ad56d

Please sign in to comment.