aboutsummaryrefslogtreecommitdiff
path: root/src/net_processing.cpp
diff options
context:
space:
mode:
authorMacroFake <falke.marco@gmail.com>2022-06-27 11:20:47 +0200
committerMacroFake <falke.marco@gmail.com>2022-06-27 11:21:08 +0200
commit50a3921c96bf0336760d836b24ce23563a752bac (patch)
tree8b6a3b69ae8aa4fc9dc67a57d0b367ed0c663f5a /src/net_processing.cpp
parentfffff0abb9c71f0af83a7925db3c293b3bb12158 (diff)
parentfa8aa0aa8180c3a0369c7589b8747666778a0deb (diff)
downloadbitcoin-50a3921c96bf0336760d836b24ce23563a752bac.tar.xz
Merge bitcoin/bitcoin#25144: refactor: Pass Peer& to Misbehaving()
fa8aa0aa8180c3a0369c7589b8747666778a0deb Pass Peer& to Misbehaving() (MacroFake) Pull request description: `Misbehaving` has several coding related issues (ignoring the conceptual issues here for now): * It is public, but it is not supposed to be called from outside of net_processing. Fix that by making it private and creating a public `UnitTestMisbehaving` method for unit testing only. * It doesn't do anything if a `nullptr` is passed. It would be less confusing to just skip the call instead. Fix that by passing `Peer&` to `Misbehaving()`. * It calls `GetPeerRef`, causing `!m_peer_mutex` lock annotations to be propagated. This is harmless, but verbose. Fix it by removing the no longer needed call to `GetPeerRef` and the no longer needed lock annotations. ACKs for top commit: vasild: ACK fa8aa0aa8180c3a0369c7589b8747666778a0deb w0xlt: Code Review ACK https://github.com/bitcoin/bitcoin/pull/25144/commits/fa8aa0aa8180c3a0369c7589b8747666778a0deb Tree-SHA512: e60a6b317f2b826f9e0724285d00b632d3e2a91ded9fa5ba01c80766c5d39270b719be234c01302d46eaba600910032693836aa116ff05ee1b590c7530881cd3
Diffstat (limited to 'src/net_processing.cpp')
-rw-r--r--src/net_processing.cpp72
1 files changed, 38 insertions, 34 deletions
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index cbba1d0aa2..bc7d42ac20 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -493,7 +493,7 @@ public:
void SendPings() override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
void RelayTransaction(const uint256& txid, const uint256& wtxid) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
void SetBestHeight(int height) override { m_best_height = height; };
- void Misbehaving(const NodeId pnode, const int howmuch, const std::string& message) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
+ void UnitTestMisbehaving(NodeId peer_id, int howmuch) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex) { Misbehaving(*Assert(GetPeerRef(peer_id)), howmuch, ""); };
void ProcessMessage(CNode& pfrom, const std::string& msg_type, CDataStream& vRecv,
const std::chrono::microseconds time_received, const std::atomic<bool>& interruptMsgProc) override
EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, !m_recent_confirmed_transactions_mutex, !m_most_recent_block_mutex);
@@ -518,6 +518,12 @@ private:
PeerRef RemovePeer(NodeId id) EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
/**
+ * Increment peer's misbehavior score. If the new value >= DISCOURAGEMENT_THRESHOLD, mark the node
+ * to be discouraged, meaning the peer might be disconnected and added to the discouragement filter.
+ */
+ void Misbehaving(Peer& peer, int howmuch, const std::string& message);
+
+ /**
* Potentially mark a node discouraged based on the contents of a BlockValidationState object
*
* @param[in] via_compact_block this bool is passed in because net_processing should
@@ -550,13 +556,12 @@ private:
void ProcessOrphanTx(std::set<uint256>& orphan_work_set) EXCLUSIVE_LOCKS_REQUIRED(cs_main, g_cs_orphans)
EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
/** Process a single headers message from a peer. */
- void ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
+ void ProcessHeadersMessage(CNode& pfrom, Peer& peer,
const std::vector<CBlockHeader>& headers,
bool via_compact_block)
EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
- void SendBlockTransactions(CNode& pfrom, const CBlock& block, const BlockTransactionsRequest& req)
- EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
+ void SendBlockTransactions(CNode& pfrom, Peer& peer, const CBlock& block, const BlockTransactionsRequest& req);
/** Register with TxRequestTracker that an INV has been received from a
* peer. The announcement parameters are decided in PeerManager and then
@@ -1444,33 +1449,31 @@ void PeerManagerImpl::AddToCompactExtraTransactions(const CTransactionRef& tx)
vExtraTxnForCompactIt = (vExtraTxnForCompactIt + 1) % max_extra_txn;
}
-void PeerManagerImpl::Misbehaving(const NodeId pnode, const int howmuch, const std::string& message)
+void PeerManagerImpl::Misbehaving(Peer& peer, int howmuch, const std::string& message)
{
assert(howmuch > 0);
- PeerRef peer = GetPeerRef(pnode);
- if (peer == nullptr) return;
-
- LOCK(peer->m_misbehavior_mutex);
- const int score_before{peer->m_misbehavior_score};
- peer->m_misbehavior_score += howmuch;
- const int score_now{peer->m_misbehavior_score};
+ LOCK(peer.m_misbehavior_mutex);
+ const int score_before{peer.m_misbehavior_score};
+ peer.m_misbehavior_score += howmuch;
+ const int score_now{peer.m_misbehavior_score};
const std::string message_prefixed = message.empty() ? "" : (": " + message);
std::string warning;
if (score_now >= DISCOURAGEMENT_THRESHOLD && score_before < DISCOURAGEMENT_THRESHOLD) {
warning = " DISCOURAGE THRESHOLD EXCEEDED";
- peer->m_should_discourage = true;
+ peer.m_should_discourage = true;
}
LogPrint(BCLog::NET, "Misbehaving: peer=%d (%d -> %d)%s%s\n",
- pnode, score_before, score_now, warning, message_prefixed);
+ peer.m_id, score_before, score_now, warning, message_prefixed);
}
bool PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidationState& state,
bool via_compact_block, const std::string& message)
{
+ PeerRef peer{GetPeerRef(nodeid)};
switch (state.GetResult()) {
case BlockValidationResult::BLOCK_RESULT_UNSET:
break;
@@ -1478,7 +1481,7 @@ bool PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidati
case BlockValidationResult::BLOCK_CONSENSUS:
case BlockValidationResult::BLOCK_MUTATED:
if (!via_compact_block) {
- Misbehaving(nodeid, 100, message);
+ if (peer) Misbehaving(*peer, 100, message);
return true;
}
break;
@@ -1493,7 +1496,7 @@ bool PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidati
// Discourage outbound (but not inbound) peers if on an invalid chain.
// Exempt HB compact block peers. Manual connections are always protected from discouragement.
if (!via_compact_block && !node_state->m_is_inbound) {
- Misbehaving(nodeid, 100, message);
+ if (peer) Misbehaving(*peer, 100, message);
return true;
}
break;
@@ -1501,12 +1504,12 @@ bool PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidati
case BlockValidationResult::BLOCK_INVALID_HEADER:
case BlockValidationResult::BLOCK_CHECKPOINT:
case BlockValidationResult::BLOCK_INVALID_PREV:
- Misbehaving(nodeid, 100, message);
+ if (peer) Misbehaving(*peer, 100, message);
return true;
// Conflicting (but not necessarily invalid) data or different policy:
case BlockValidationResult::BLOCK_MISSING_PREV:
// TODO: Handle this much more gracefully (10 DoS points is super arbitrary)
- Misbehaving(nodeid, 10, message);
+ if (peer) Misbehaving(*peer, 10, message);
return true;
case BlockValidationResult::BLOCK_RECENT_CONSENSUS_CHANGE:
case BlockValidationResult::BLOCK_TIME_FUTURE:
@@ -1520,12 +1523,13 @@ bool PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidati
bool PeerManagerImpl::MaybePunishNodeForTx(NodeId nodeid, const TxValidationState& state, const std::string& message)
{
+ PeerRef peer{GetPeerRef(nodeid)};
switch (state.GetResult()) {
case TxValidationResult::TX_RESULT_UNSET:
break;
// The node is providing invalid data:
case TxValidationResult::TX_CONSENSUS:
- Misbehaving(nodeid, 100, message);
+ if (peer) Misbehaving(*peer, 100, message);
return true;
// Conflicting (but not necessarily invalid) data or different policy:
case TxValidationResult::TX_RECENT_CONSENSUS_CHANGE:
@@ -2175,12 +2179,12 @@ uint32_t PeerManagerImpl::GetFetchFlags(const CNode& pfrom) const EXCLUSIVE_LOCK
return nFetchFlags;
}
-void PeerManagerImpl::SendBlockTransactions(CNode& pfrom, const CBlock& block, const BlockTransactionsRequest& req)
+void PeerManagerImpl::SendBlockTransactions(CNode& pfrom, Peer& peer, const CBlock& block, const BlockTransactionsRequest& req)
{
BlockTransactions resp(req);
for (size_t i = 0; i < req.indexes.size(); i++) {
if (req.indexes[i] >= block.vtx.size()) {
- Misbehaving(pfrom.GetId(), 100, "getblocktxn with out-of-bounds tx indices");
+ Misbehaving(peer, 100, "getblocktxn with out-of-bounds tx indices");
return;
}
resp.txn[i] = block.vtx[req.indexes[i]];
@@ -2190,7 +2194,7 @@ void PeerManagerImpl::SendBlockTransactions(CNode& pfrom, const CBlock& block, c
m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::BLOCKTXN, resp));
}
-void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
+void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, Peer& peer,
const std::vector<CBlockHeader>& headers,
bool via_compact_block)
{
@@ -2230,7 +2234,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
UpdateBlockAvailability(pfrom.GetId(), headers.back().GetHash());
if (nodestate->nUnconnectingHeaders % MAX_UNCONNECTING_HEADERS == 0) {
- Misbehaving(pfrom.GetId(), 20, strprintf("%d non-connecting headers", nodestate->nUnconnectingHeaders));
+ Misbehaving(peer, 20, strprintf("%d non-connecting headers", nodestate->nUnconnectingHeaders));
}
return;
}
@@ -2238,7 +2242,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
uint256 hashLastBlock;
for (const CBlockHeader& header : headers) {
if (!hashLastBlock.IsNull() && header.hashPrevBlock != hashLastBlock) {
- Misbehaving(pfrom.GetId(), 20, "non-continuous headers sequence");
+ Misbehaving(peer, 20, "non-continuous headers sequence");
return;
}
hashLastBlock = header.GetHash();
@@ -3001,7 +3005,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
if (vAddr.size() > MAX_ADDR_TO_SEND)
{
- Misbehaving(pfrom.GetId(), 20, strprintf("%s message size = %u", msg_type, vAddr.size()));
+ Misbehaving(*peer, 20, strprintf("%s message size = %u", msg_type, vAddr.size()));
return;
}
@@ -3082,7 +3086,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
vRecv >> vInv;
if (vInv.size() > MAX_INV_SZ)
{
- Misbehaving(pfrom.GetId(), 20, strprintf("inv message size = %u", vInv.size()));
+ Misbehaving(*peer, 20, strprintf("inv message size = %u", vInv.size()));
return;
}
@@ -3150,7 +3154,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
vRecv >> vInv;
if (vInv.size() > MAX_INV_SZ)
{
- Misbehaving(pfrom.GetId(), 20, strprintf("getdata message size = %u", vInv.size()));
+ Misbehaving(*peer, 20, strprintf("getdata message size = %u", vInv.size()));
return;
}
@@ -3248,7 +3252,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
// Unlock m_most_recent_block_mutex to avoid cs_main lock inversion
}
if (recent_block) {
- SendBlockTransactions(pfrom, *recent_block, req);
+ SendBlockTransactions(pfrom, *peer, *recent_block, req);
return;
}
@@ -3266,7 +3270,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
bool ret = ReadBlockFromDisk(block, pindex, m_chainparams.GetConsensus());
assert(ret);
- SendBlockTransactions(pfrom, block, req);
+ SendBlockTransactions(pfrom, *peer, block, req);
return;
}
}
@@ -3685,7 +3689,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
ReadStatus status = partialBlock.InitData(cmpctblock, vExtraTxnForCompact);
if (status == READ_STATUS_INVALID) {
RemoveBlockRequest(pindex->GetBlockHash()); // Reset in-flight state in case Misbehaving does not result in a disconnect
- Misbehaving(pfrom.GetId(), 100, "invalid compact block");
+ Misbehaving(*peer, 100, "invalid compact block");
return;
} else if (status == READ_STATUS_FAILED) {
// Duplicate txindexes, the block is now in-flight, so just request it
@@ -3812,7 +3816,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
ReadStatus status = partialBlock.FillBlock(*pblock, resp.txn);
if (status == READ_STATUS_INVALID) {
RemoveBlockRequest(resp.blockhash); // Reset in-flight state in case Misbehaving does not result in a disconnect
- Misbehaving(pfrom.GetId(), 100, "invalid compact block/non-matching block transactions");
+ Misbehaving(*peer, 100, "invalid compact block/non-matching block transactions");
return;
} else if (status == READ_STATUS_FAILED) {
// Might have collided, fall back to getdata now :(
@@ -3873,7 +3877,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
// Bypass the normal CBlock deserialization, as we don't want to risk deserializing 2000 full blocks.
unsigned int nCount = ReadCompactSize(vRecv);
if (nCount > MAX_HEADERS_RESULTS) {
- Misbehaving(pfrom.GetId(), 20, strprintf("headers message size = %u", nCount));
+ Misbehaving(*peer, 20, strprintf("headers message size = %u", nCount));
return;
}
headers.resize(nCount);
@@ -4067,7 +4071,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
if (!filter.IsWithinSizeConstraints())
{
// There is no excuse for sending a too-large filter
- Misbehaving(pfrom.GetId(), 100, "too-large bloom filter");
+ Misbehaving(*peer, 100, "too-large bloom filter");
} else if (auto tx_relay = peer->GetTxRelay(); tx_relay != nullptr) {
{
LOCK(tx_relay->m_bloom_filter_mutex);
@@ -4103,7 +4107,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
}
}
if (bad) {
- Misbehaving(pfrom.GetId(), 100, "bad filteradd message");
+ Misbehaving(*peer, 100, "bad filteradd message");
}
return;
}