@@ -492,7 +492,7 @@ class PeerManagerImpl final : public PeerManager
492492 void SendPings () override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
493493 void RelayTransaction (const uint256& txid, const uint256& wtxid) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
494494 void SetBestHeight (int height) override { m_best_height = height; };
495- void Misbehaving ( const NodeId pnode, const int howmuch, const std::string& message ) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
495+ void UnitTestMisbehaving ( NodeId peer_id, int howmuch) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex) { Misbehaving (* Assert ( GetPeerRef (peer_id)), howmuch, " " ); } ;
496496 void ProcessMessage (CNode& pfrom, const std::string& msg_type, CDataStream& vRecv,
497497 const std::chrono::microseconds time_received, const std::atomic<bool >& interruptMsgProc) override
498498 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, !m_recent_confirmed_transactions_mutex, !m_most_recent_block_mutex);
@@ -516,6 +516,12 @@ class PeerManagerImpl final : public PeerManager
516516 * May return an empty shared_ptr if the Peer object can't be found. */
517517 PeerRef RemovePeer (NodeId id) EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
518518
519+ /* *
520+ * Increment peer's misbehavior score. If the new value >= DISCOURAGEMENT_THRESHOLD, mark the node
521+ * to be discouraged, meaning the peer might be disconnected and added to the discouragement filter.
522+ */
523+ void Misbehaving (Peer& peer, int howmuch, const std::string& message);
524+
519525 /* *
520526 * Potentially mark a node discouraged based on the contents of a BlockValidationState object
521527 *
@@ -549,13 +555,12 @@ class PeerManagerImpl final : public PeerManager
549555 void ProcessOrphanTx (std::set<uint256>& orphan_work_set) EXCLUSIVE_LOCKS_REQUIRED(cs_main, g_cs_orphans)
550556 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
551557 /* * Process a single headers message from a peer. */
552- void ProcessHeadersMessage (CNode& pfrom, const Peer& peer,
558+ void ProcessHeadersMessage (CNode& pfrom, Peer& peer,
553559 const std::vector<CBlockHeader>& headers,
554560 bool via_compact_block)
555561 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
556562
557- void SendBlockTransactions (CNode& pfrom, const CBlock& block, const BlockTransactionsRequest& req)
558- EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
563+ void SendBlockTransactions (CNode& pfrom, Peer& peer, const CBlock& block, const BlockTransactionsRequest& req);
559564
560565 /* * Register with TxRequestTracker that an INV has been received from a
561566 * peer. The announcement parameters are decided in PeerManager and then
@@ -1441,41 +1446,39 @@ void PeerManagerImpl::AddToCompactExtraTransactions(const CTransactionRef& tx)
14411446 vExtraTxnForCompactIt = (vExtraTxnForCompactIt + 1 ) % max_extra_txn;
14421447}
14431448
1444- void PeerManagerImpl::Misbehaving (const NodeId pnode, const int howmuch, const std::string& message)
1449+ void PeerManagerImpl::Misbehaving (Peer& peer, int howmuch, const std::string& message)
14451450{
14461451 assert (howmuch > 0 );
14471452
1448- PeerRef peer = GetPeerRef (pnode);
1449- if (peer == nullptr ) return ;
1450-
1451- LOCK (peer->m_misbehavior_mutex );
1452- const int score_before{peer->m_misbehavior_score };
1453- peer->m_misbehavior_score += howmuch;
1454- const int score_now{peer->m_misbehavior_score };
1453+ LOCK (peer.m_misbehavior_mutex );
1454+ const int score_before{peer.m_misbehavior_score };
1455+ peer.m_misbehavior_score += howmuch;
1456+ const int score_now{peer.m_misbehavior_score };
14551457
14561458 const std::string message_prefixed = message.empty () ? " " : (" : " + message);
14571459 std::string warning;
14581460
14591461 if (score_now >= DISCOURAGEMENT_THRESHOLD && score_before < DISCOURAGEMENT_THRESHOLD) {
14601462 warning = " DISCOURAGE THRESHOLD EXCEEDED" ;
1461- peer-> m_should_discourage = true ;
1463+ peer. m_should_discourage = true ;
14621464 }
14631465
14641466 LogPrint (BCLog::NET, " Misbehaving: peer=%d (%d -> %d)%s%s\n " ,
1465- pnode , score_before, score_now, warning, message_prefixed);
1467+ peer. m_id , score_before, score_now, warning, message_prefixed);
14661468}
14671469
14681470bool PeerManagerImpl::MaybePunishNodeForBlock (NodeId nodeid, const BlockValidationState& state,
14691471 bool via_compact_block, const std::string& message)
14701472{
1473+ PeerRef peer{GetPeerRef (nodeid)};
14711474 switch (state.GetResult ()) {
14721475 case BlockValidationResult::BLOCK_RESULT_UNSET:
14731476 break ;
14741477 // The node is providing invalid data:
14751478 case BlockValidationResult::BLOCK_CONSENSUS:
14761479 case BlockValidationResult::BLOCK_MUTATED:
14771480 if (!via_compact_block) {
1478- Misbehaving (nodeid , 100 , message);
1481+ if (peer) Misbehaving (*peer , 100 , message);
14791482 return true ;
14801483 }
14811484 break ;
@@ -1490,20 +1493,20 @@ bool PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidati
14901493 // Discourage outbound (but not inbound) peers if on an invalid chain.
14911494 // Exempt HB compact block peers. Manual connections are always protected from discouragement.
14921495 if (!via_compact_block && !node_state->m_is_inbound ) {
1493- Misbehaving (nodeid , 100 , message);
1496+ if (peer) Misbehaving (*peer , 100 , message);
14941497 return true ;
14951498 }
14961499 break ;
14971500 }
14981501 case BlockValidationResult::BLOCK_INVALID_HEADER:
14991502 case BlockValidationResult::BLOCK_CHECKPOINT:
15001503 case BlockValidationResult::BLOCK_INVALID_PREV:
1501- Misbehaving (nodeid , 100 , message);
1504+ if (peer) Misbehaving (*peer , 100 , message);
15021505 return true ;
15031506 // Conflicting (but not necessarily invalid) data or different policy:
15041507 case BlockValidationResult::BLOCK_MISSING_PREV:
15051508 // TODO: Handle this much more gracefully (10 DoS points is super arbitrary)
1506- Misbehaving (nodeid , 10 , message);
1509+ if (peer) Misbehaving (*peer , 10 , message);
15071510 return true ;
15081511 case BlockValidationResult::BLOCK_RECENT_CONSENSUS_CHANGE:
15091512 case BlockValidationResult::BLOCK_TIME_FUTURE:
@@ -1517,12 +1520,13 @@ bool PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidati
15171520
15181521bool PeerManagerImpl::MaybePunishNodeForTx (NodeId nodeid, const TxValidationState& state, const std::string& message)
15191522{
1523+ PeerRef peer{GetPeerRef (nodeid)};
15201524 switch (state.GetResult ()) {
15211525 case TxValidationResult::TX_RESULT_UNSET:
15221526 break ;
15231527 // The node is providing invalid data:
15241528 case TxValidationResult::TX_CONSENSUS:
1525- Misbehaving (nodeid , 100 , message);
1529+ if (peer) Misbehaving (*peer , 100 , message);
15261530 return true ;
15271531 // Conflicting (but not necessarily invalid) data or different policy:
15281532 case TxValidationResult::TX_RECENT_CONSENSUS_CHANGE:
@@ -2172,12 +2176,12 @@ uint32_t PeerManagerImpl::GetFetchFlags(const CNode& pfrom) const EXCLUSIVE_LOCK
21722176 return nFetchFlags;
21732177}
21742178
2175- void PeerManagerImpl::SendBlockTransactions (CNode& pfrom, const CBlock& block, const BlockTransactionsRequest& req)
2179+ void PeerManagerImpl::SendBlockTransactions (CNode& pfrom, Peer& peer, const CBlock& block, const BlockTransactionsRequest& req)
21762180{
21772181 BlockTransactions resp (req);
21782182 for (size_t i = 0 ; i < req.indexes .size (); i++) {
21792183 if (req.indexes [i] >= block.vtx .size ()) {
2180- Misbehaving (pfrom. GetId () , 100 , " getblocktxn with out-of-bounds tx indices" );
2184+ Misbehaving (peer , 100 , " getblocktxn with out-of-bounds tx indices" );
21812185 return ;
21822186 }
21832187 resp.txn [i] = block.vtx [req.indexes [i]];
@@ -2187,7 +2191,7 @@ void PeerManagerImpl::SendBlockTransactions(CNode& pfrom, const CBlock& block, c
21872191 m_connman.PushMessage (&pfrom, msgMaker.Make (NetMsgType::BLOCKTXN, resp));
21882192}
21892193
2190- void PeerManagerImpl::ProcessHeadersMessage (CNode& pfrom, const Peer& peer,
2194+ void PeerManagerImpl::ProcessHeadersMessage (CNode& pfrom, Peer& peer,
21912195 const std::vector<CBlockHeader>& headers,
21922196 bool via_compact_block)
21932197{
@@ -2227,15 +2231,15 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
22272231 UpdateBlockAvailability (pfrom.GetId (), headers.back ().GetHash ());
22282232
22292233 if (nodestate->nUnconnectingHeaders % MAX_UNCONNECTING_HEADERS == 0 ) {
2230- Misbehaving (pfrom. GetId () , 20 , strprintf (" %d non-connecting headers" , nodestate->nUnconnectingHeaders ));
2234+ Misbehaving (peer , 20 , strprintf (" %d non-connecting headers" , nodestate->nUnconnectingHeaders ));
22312235 }
22322236 return ;
22332237 }
22342238
22352239 uint256 hashLastBlock;
22362240 for (const CBlockHeader& header : headers) {
22372241 if (!hashLastBlock.IsNull () && header.hashPrevBlock != hashLastBlock) {
2238- Misbehaving (pfrom. GetId () , 20 , " non-continuous headers sequence" );
2242+ Misbehaving (peer , 20 , " non-continuous headers sequence" );
22392243 return ;
22402244 }
22412245 hashLastBlock = header.GetHash ();
@@ -2998,7 +3002,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
29983002
29993003 if (vAddr.size () > MAX_ADDR_TO_SEND)
30003004 {
3001- Misbehaving (pfrom. GetId () , 20 , strprintf (" %s message size = %u" , msg_type, vAddr.size ()));
3005+ Misbehaving (*peer , 20 , strprintf (" %s message size = %u" , msg_type, vAddr.size ()));
30023006 return ;
30033007 }
30043008
@@ -3079,7 +3083,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
30793083 vRecv >> vInv;
30803084 if (vInv.size () > MAX_INV_SZ)
30813085 {
3082- Misbehaving (pfrom. GetId () , 20 , strprintf (" inv message size = %u" , vInv.size ()));
3086+ Misbehaving (*peer , 20 , strprintf (" inv message size = %u" , vInv.size ()));
30833087 return ;
30843088 }
30853089
@@ -3154,7 +3158,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
31543158 vRecv >> vInv;
31553159 if (vInv.size () > MAX_INV_SZ)
31563160 {
3157- Misbehaving (pfrom. GetId () , 20 , strprintf (" getdata message size = %u" , vInv.size ()));
3161+ Misbehaving (*peer , 20 , strprintf (" getdata message size = %u" , vInv.size ()));
31583162 return ;
31593163 }
31603164
@@ -3252,7 +3256,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
32523256 // Unlock m_most_recent_block_mutex to avoid cs_main lock inversion
32533257 }
32543258 if (recent_block) {
3255- SendBlockTransactions (pfrom, *recent_block, req);
3259+ SendBlockTransactions (pfrom, *peer, * recent_block, req);
32563260 return ;
32573261 }
32583262
@@ -3270,7 +3274,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
32703274 bool ret = ReadBlockFromDisk (block, pindex, m_chainparams.GetConsensus ());
32713275 assert (ret);
32723276
3273- SendBlockTransactions (pfrom, block, req);
3277+ SendBlockTransactions (pfrom, *peer, block, req);
32743278 return ;
32753279 }
32763280 }
@@ -3678,7 +3682,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
36783682 ReadStatus status = partialBlock.InitData (cmpctblock, vExtraTxnForCompact);
36793683 if (status == READ_STATUS_INVALID) {
36803684 RemoveBlockRequest (pindex->GetBlockHash ()); // Reset in-flight state in case Misbehaving does not result in a disconnect
3681- Misbehaving (pfrom. GetId () , 100 , " invalid compact block" );
3685+ Misbehaving (*peer , 100 , " invalid compact block" );
36823686 return ;
36833687 } else if (status == READ_STATUS_FAILED) {
36843688 // Duplicate txindexes, the block is now in-flight, so just request it
@@ -3805,7 +3809,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
38053809 ReadStatus status = partialBlock.FillBlock (*pblock, resp.txn );
38063810 if (status == READ_STATUS_INVALID) {
38073811 RemoveBlockRequest (resp.blockhash ); // Reset in-flight state in case Misbehaving does not result in a disconnect
3808- Misbehaving (pfrom. GetId () , 100 , " invalid compact block/non-matching block transactions" );
3812+ Misbehaving (*peer , 100 , " invalid compact block/non-matching block transactions" );
38093813 return ;
38103814 } else if (status == READ_STATUS_FAILED) {
38113815 // Might have collided, fall back to getdata now :(
@@ -3866,7 +3870,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
38663870 // Bypass the normal CBlock deserialization, as we don't want to risk deserializing 2000 full blocks.
38673871 unsigned int nCount = ReadCompactSize (vRecv);
38683872 if (nCount > MAX_HEADERS_RESULTS) {
3869- Misbehaving (pfrom. GetId () , 20 , strprintf (" headers message size = %u" , nCount));
3873+ Misbehaving (*peer , 20 , strprintf (" headers message size = %u" , nCount));
38703874 return ;
38713875 }
38723876 headers.resize (nCount);
@@ -4060,7 +4064,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
40604064 if (!filter.IsWithinSizeConstraints ())
40614065 {
40624066 // There is no excuse for sending a too-large filter
4063- Misbehaving (pfrom. GetId () , 100 , " too-large bloom filter" );
4067+ Misbehaving (*peer , 100 , " too-large bloom filter" );
40644068 } else if (auto tx_relay = peer->GetTxRelay (); tx_relay != nullptr ) {
40654069 {
40664070 LOCK (tx_relay->m_bloom_filter_mutex );
@@ -4095,7 +4099,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
40954099 }
40964100 }
40974101 if (bad) {
4098- Misbehaving (pfrom. GetId () , 100 , " bad filteradd message" );
4102+ Misbehaving (*peer , 100 , " bad filteradd message" );
40994103 }
41004104 return ;
41014105 }
0 commit comments