mirror of
https://github.com/Retropex/bitcoin.git
synced 2025-06-02 15:32:34 +02:00
Instead of DoS banning for invalid blocks, merely disconnect nodes if we're relying on them as a primary node
This commit is contained in:
parent
78b7447ab0
commit
4ea97916f8
19
src/net.h
19
src/net.h
@ -942,6 +942,25 @@ public:
|
|||||||
|
|
||||||
void CopyStats(CNodeStats& stats) EXCLUSIVE_LOCKS_REQUIRED(!m_subver_mutex, !m_addr_local_mutex, !cs_vSend, !cs_vRecv);
|
void CopyStats(CNodeStats& stats) EXCLUSIVE_LOCKS_REQUIRED(!m_subver_mutex, !m_addr_local_mutex, !cs_vSend, !cs_vRecv);
|
||||||
|
|
||||||
|
bool PunishInvalidBlocks() const
|
||||||
|
{
|
||||||
|
if (HasPermission(NetPermissionFlags::NoBan)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
switch (m_conn_type) {
|
||||||
|
case ConnectionType::INBOUND:
|
||||||
|
case ConnectionType::MANUAL:
|
||||||
|
case ConnectionType::FEELER:
|
||||||
|
return false;
|
||||||
|
case ConnectionType::OUTBOUND_FULL_RELAY:
|
||||||
|
case ConnectionType::BLOCK_RELAY:
|
||||||
|
case ConnectionType::ADDR_FETCH:
|
||||||
|
return true;
|
||||||
|
} // no default case, so the compiler can warn about missing cases
|
||||||
|
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
std::string ConnectionTypeAsString() const { return ::ConnectionTypeAsString(m_conn_type); }
|
std::string ConnectionTypeAsString() const { return ::ConnectionTypeAsString(m_conn_type); }
|
||||||
|
|
||||||
/** A ping-pong round trip has completed successfully. Update latest and minimum ping times. */
|
/** A ping-pong round trip has completed successfully. Update latest and minimum ping times. */
|
||||||
|
@ -1945,10 +1945,23 @@ void PeerManagerImpl::Misbehaving(Peer& peer, const std::string& message)
|
|||||||
LogPrint(BCLog::NET, "Misbehaving: peer=%d%s\n", peer.m_id, message_prefixed);
|
LogPrint(BCLog::NET, "Misbehaving: peer=%d%s\n", peer.m_id, message_prefixed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void HandleDoSPunishment(CConnman& connman, NodeId node_id, const int nDoS, const char * const what_is_it) {
|
||||||
|
// We never actually DoS ban for invalid blocks, merely disconnect nodes if we're relying on them as a primary node
|
||||||
|
const std::string msg = strprintf("peer=%d got DoS score %d on invalid %s", node_id, nDoS, what_is_it);
|
||||||
|
connman.ForNode(node_id, [msg](CNode* node) {
|
||||||
|
if (node->PunishInvalidBlocks()) {
|
||||||
|
LogPrint(BCLog::NET, "%s; simply disconnecting\n", msg);
|
||||||
|
node->fDisconnect = true;
|
||||||
|
} else {
|
||||||
|
LogPrint(BCLog::NET, "%s; tolerating\n", msg);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidationState& state,
|
void PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidationState& state,
|
||||||
bool via_compact_block, const std::string& message)
|
bool via_compact_block, const std::string& message)
|
||||||
{
|
{
|
||||||
PeerRef peer{GetPeerRef(nodeid)};
|
|
||||||
switch (state.GetResult()) {
|
switch (state.GetResult()) {
|
||||||
case BlockValidationResult::BLOCK_RESULT_UNSET:
|
case BlockValidationResult::BLOCK_RESULT_UNSET:
|
||||||
break;
|
break;
|
||||||
@ -1960,7 +1973,7 @@ void PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidati
|
|||||||
case BlockValidationResult::BLOCK_CONSENSUS:
|
case BlockValidationResult::BLOCK_CONSENSUS:
|
||||||
case BlockValidationResult::BLOCK_MUTATED:
|
case BlockValidationResult::BLOCK_MUTATED:
|
||||||
if (!via_compact_block) {
|
if (!via_compact_block) {
|
||||||
if (peer) Misbehaving(*peer, message);
|
HandleDoSPunishment(m_connman, nodeid, 100, "block");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1975,7 +1988,7 @@ void PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidati
|
|||||||
// Discourage outbound (but not inbound) peers if on an invalid chain.
|
// Discourage outbound (but not inbound) peers if on an invalid chain.
|
||||||
// Exempt HB compact block peers. Manual connections are always protected from discouragement.
|
// Exempt HB compact block peers. Manual connections are always protected from discouragement.
|
||||||
if (!via_compact_block && !node_state->m_is_inbound) {
|
if (!via_compact_block && !node_state->m_is_inbound) {
|
||||||
if (peer) Misbehaving(*peer, message);
|
HandleDoSPunishment(m_connman, nodeid, 100, "block");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1983,11 +1996,11 @@ void PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidati
|
|||||||
case BlockValidationResult::BLOCK_INVALID_HEADER:
|
case BlockValidationResult::BLOCK_INVALID_HEADER:
|
||||||
case BlockValidationResult::BLOCK_CHECKPOINT:
|
case BlockValidationResult::BLOCK_CHECKPOINT:
|
||||||
case BlockValidationResult::BLOCK_INVALID_PREV:
|
case BlockValidationResult::BLOCK_INVALID_PREV:
|
||||||
if (peer) Misbehaving(*peer, message);
|
HandleDoSPunishment(m_connman, nodeid, 100, "block header");
|
||||||
return;
|
return;
|
||||||
// Conflicting (but not necessarily invalid) data or different policy:
|
// Conflicting (but not necessarily invalid) data or different policy:
|
||||||
case BlockValidationResult::BLOCK_MISSING_PREV:
|
case BlockValidationResult::BLOCK_MISSING_PREV:
|
||||||
if (peer) Misbehaving(*peer, message);
|
HandleDoSPunishment(m_connman, nodeid, 100, "block header");
|
||||||
return;
|
return;
|
||||||
case BlockValidationResult::BLOCK_RECENT_CONSENSUS_CHANGE:
|
case BlockValidationResult::BLOCK_RECENT_CONSENSUS_CHANGE:
|
||||||
case BlockValidationResult::BLOCK_TIME_FUTURE:
|
case BlockValidationResult::BLOCK_TIME_FUTURE:
|
||||||
@ -2006,7 +2019,7 @@ void PeerManagerImpl::MaybePunishNodeForTx(NodeId nodeid, const TxValidationStat
|
|||||||
break;
|
break;
|
||||||
// The node is providing invalid data:
|
// The node is providing invalid data:
|
||||||
case TxValidationResult::TX_CONSENSUS:
|
case TxValidationResult::TX_CONSENSUS:
|
||||||
if (peer) Misbehaving(*peer, "");
|
HandleDoSPunishment(m_connman, nodeid, 100, "transaction");
|
||||||
return;
|
return;
|
||||||
// Conflicting (but not necessarily invalid) data or different policy:
|
// Conflicting (but not necessarily invalid) data or different policy:
|
||||||
case TxValidationResult::TX_RECENT_CONSENSUS_CHANGE:
|
case TxValidationResult::TX_RECENT_CONSENSUS_CHANGE:
|
||||||
@ -2767,6 +2780,10 @@ void PeerManagerImpl::HandleUnconnectingHeaders(CNode& pfrom, Peer& peer,
|
|||||||
// eventually get the headers - even from a different peer -
|
// eventually get the headers - even from a different peer -
|
||||||
// we can use this peer to download.
|
// we can use this peer to download.
|
||||||
WITH_LOCK(cs_main, UpdateBlockAvailability(pfrom.GetId(), headers.back().GetHash()));
|
WITH_LOCK(cs_main, UpdateBlockAvailability(pfrom.GetId(), headers.back().GetHash()));
|
||||||
|
|
||||||
|
if (pfrom.PunishInvalidBlocks()) {
|
||||||
|
pfrom.fDisconnect = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PeerManagerImpl::CheckHeadersAreContinuous(const std::vector<CBlockHeader>& headers) const
|
bool PeerManagerImpl::CheckHeadersAreContinuous(const std::vector<CBlockHeader>& headers) const
|
||||||
|
Loading…
Reference in New Issue
Block a user