@@ -493,7 +493,7 @@ class PeerManagerImpl final : public PeerManager
493493 void SendPings () override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
494494 void RelayTransaction (const uint256& txid, const uint256& wtxid) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
495495 void SetBestHeight (int height) override { m_best_height = height; };
496- void Misbehaving ( const NodeId pnode, const int howmuch, const std::string& message ) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
496+ void UnitTestMisbehaving ( NodeId peer_id, int howmuch) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex) { Misbehaving (* Assert ( GetPeerRef (peer_id)), howmuch, " " ); } ;
497497 void ProcessMessage (CNode& pfrom, const std::string& msg_type, CDataStream& vRecv,
498498 const std::chrono::microseconds time_received, const std::atomic<bool >& interruptMsgProc) override
499499 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, !m_recent_confirmed_transactions_mutex, !m_most_recent_block_mutex);
@@ -517,6 +517,12 @@ class PeerManagerImpl final : public PeerManager
517517 * May return an empty shared_ptr if the Peer object can't be found. */
518518 PeerRef RemovePeer (NodeId id) EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
519519
520+ /* *
521+ * Increment peer's misbehavior score. If the new value >= DISCOURAGEMENT_THRESHOLD, mark the node
522+ * to be discouraged, meaning the peer might be disconnected and added to the discouragement filter.
523+ */
524+ void Misbehaving (Peer& peer, int howmuch, const std::string& message);
525+
520526 /* *
521527 * Potentially mark a node discouraged based on the contents of a BlockValidationState object
522528 *
@@ -550,13 +556,12 @@ class PeerManagerImpl final : public PeerManager
550556 void ProcessOrphanTx (std::set<uint256>& orphan_work_set) EXCLUSIVE_LOCKS_REQUIRED(cs_main, g_cs_orphans)
551557 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
552558 /* * Process a single headers message from a peer. */
553- void ProcessHeadersMessage (CNode& pfrom, const Peer& peer,
559+ void ProcessHeadersMessage (CNode& pfrom, Peer& peer,
554560 const std::vector<CBlockHeader>& headers,
555561 bool via_compact_block)
556562 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
557563
558- void SendBlockTransactions (CNode& pfrom, const CBlock& block, const BlockTransactionsRequest& req)
559- EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
564+ void SendBlockTransactions (CNode& pfrom, Peer& peer, const CBlock& block, const BlockTransactionsRequest& req);
560565
561566 /* * Register with TxRequestTracker that an INV has been received from a
562567 * peer. The announcement parameters are decided in PeerManager and then
@@ -1444,41 +1449,39 @@ void PeerManagerImpl::AddToCompactExtraTransactions(const CTransactionRef& tx)
14441449 vExtraTxnForCompactIt = (vExtraTxnForCompactIt + 1 ) % max_extra_txn;
14451450}
14461451
1447- void PeerManagerImpl::Misbehaving (const NodeId pnode, const int howmuch, const std::string& message)
1452+ void PeerManagerImpl::Misbehaving (Peer& peer, int howmuch, const std::string& message)
14481453{
14491454 assert (howmuch > 0 );
14501455
1451- PeerRef peer = GetPeerRef (pnode);
1452- if (peer == nullptr ) return ;
1453-
1454- LOCK (peer->m_misbehavior_mutex );
1455- const int score_before{peer->m_misbehavior_score };
1456- peer->m_misbehavior_score += howmuch;
1457- const int score_now{peer->m_misbehavior_score };
1456+ LOCK (peer.m_misbehavior_mutex );
1457+ const int score_before{peer.m_misbehavior_score };
1458+ peer.m_misbehavior_score += howmuch;
1459+ const int score_now{peer.m_misbehavior_score };
14581460
14591461 const std::string message_prefixed = message.empty () ? " " : (" : " + message);
14601462 std::string warning;
14611463
14621464 if (score_now >= DISCOURAGEMENT_THRESHOLD && score_before < DISCOURAGEMENT_THRESHOLD) {
14631465 warning = " DISCOURAGE THRESHOLD EXCEEDED" ;
1464- peer-> m_should_discourage = true ;
1466+ peer. m_should_discourage = true ;
14651467 }
14661468
14671469 LogPrint (BCLog::NET, " Misbehaving: peer=%d (%d -> %d)%s%s\n " ,
1468- pnode , score_before, score_now, warning, message_prefixed);
1470+ peer. m_id , score_before, score_now, warning, message_prefixed);
14691471}
14701472
14711473bool PeerManagerImpl::MaybePunishNodeForBlock (NodeId nodeid, const BlockValidationState& state,
14721474 bool via_compact_block, const std::string& message)
14731475{
1476+ PeerRef peer{GetPeerRef (nodeid)};
14741477 switch (state.GetResult ()) {
14751478 case BlockValidationResult::BLOCK_RESULT_UNSET:
14761479 break ;
14771480 // The node is providing invalid data:
14781481 case BlockValidationResult::BLOCK_CONSENSUS:
14791482 case BlockValidationResult::BLOCK_MUTATED:
14801483 if (!via_compact_block) {
1481- Misbehaving (nodeid , 100 , message);
1484+ if (peer) Misbehaving (*peer , 100 , message);
14821485 return true ;
14831486 }
14841487 break ;
@@ -1493,20 +1496,20 @@ bool PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidati
14931496 // Discourage outbound (but not inbound) peers if on an invalid chain.
14941497 // Exempt HB compact block peers. Manual connections are always protected from discouragement.
14951498 if (!via_compact_block && !node_state->m_is_inbound ) {
1496- Misbehaving (nodeid , 100 , message);
1499+ if (peer) Misbehaving (*peer , 100 , message);
14971500 return true ;
14981501 }
14991502 break ;
15001503 }
15011504 case BlockValidationResult::BLOCK_INVALID_HEADER:
15021505 case BlockValidationResult::BLOCK_CHECKPOINT:
15031506 case BlockValidationResult::BLOCK_INVALID_PREV:
1504- Misbehaving (nodeid , 100 , message);
1507+ if (peer) Misbehaving (*peer , 100 , message);
15051508 return true ;
15061509 // Conflicting (but not necessarily invalid) data or different policy:
15071510 case BlockValidationResult::BLOCK_MISSING_PREV:
15081511 // TODO: Handle this much more gracefully (10 DoS points is super arbitrary)
1509- Misbehaving (nodeid , 10 , message);
1512+ if (peer) Misbehaving (*peer , 10 , message);
15101513 return true ;
15111514 case BlockValidationResult::BLOCK_RECENT_CONSENSUS_CHANGE:
15121515 case BlockValidationResult::BLOCK_TIME_FUTURE:
@@ -1520,12 +1523,13 @@ bool PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidati
15201523
15211524bool PeerManagerImpl::MaybePunishNodeForTx (NodeId nodeid, const TxValidationState& state, const std::string& message)
15221525{
1526+ PeerRef peer{GetPeerRef (nodeid)};
15231527 switch (state.GetResult ()) {
15241528 case TxValidationResult::TX_RESULT_UNSET:
15251529 break ;
15261530 // The node is providing invalid data:
15271531 case TxValidationResult::TX_CONSENSUS:
1528- Misbehaving (nodeid , 100 , message);
1532+ if (peer) Misbehaving (*peer , 100 , message);
15291533 return true ;
15301534 // Conflicting (but not necessarily invalid) data or different policy:
15311535 case TxValidationResult::TX_RECENT_CONSENSUS_CHANGE:
@@ -2175,12 +2179,12 @@ uint32_t PeerManagerImpl::GetFetchFlags(const CNode& pfrom) const EXCLUSIVE_LOCK
21752179 return nFetchFlags;
21762180}
21772181
2178- void PeerManagerImpl::SendBlockTransactions (CNode& pfrom, const CBlock& block, const BlockTransactionsRequest& req)
2182+ void PeerManagerImpl::SendBlockTransactions (CNode& pfrom, Peer& peer, const CBlock& block, const BlockTransactionsRequest& req)
21792183{
21802184 BlockTransactions resp (req);
21812185 for (size_t i = 0 ; i < req.indexes .size (); i++) {
21822186 if (req.indexes [i] >= block.vtx .size ()) {
2183- Misbehaving (pfrom. GetId () , 100 , " getblocktxn with out-of-bounds tx indices" );
2187+ Misbehaving (peer , 100 , " getblocktxn with out-of-bounds tx indices" );
21842188 return ;
21852189 }
21862190 resp.txn [i] = block.vtx [req.indexes [i]];
@@ -2190,7 +2194,7 @@ void PeerManagerImpl::SendBlockTransactions(CNode& pfrom, const CBlock& block, c
21902194 m_connman.PushMessage (&pfrom, msgMaker.Make (NetMsgType::BLOCKTXN, resp));
21912195}
21922196
2193- void PeerManagerImpl::ProcessHeadersMessage (CNode& pfrom, const Peer& peer,
2197+ void PeerManagerImpl::ProcessHeadersMessage (CNode& pfrom, Peer& peer,
21942198 const std::vector<CBlockHeader>& headers,
21952199 bool via_compact_block)
21962200{
@@ -2230,15 +2234,15 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
22302234 UpdateBlockAvailability (pfrom.GetId (), headers.back ().GetHash ());
22312235
22322236 if (nodestate->nUnconnectingHeaders % MAX_UNCONNECTING_HEADERS == 0 ) {
2233- Misbehaving (pfrom. GetId () , 20 , strprintf (" %d non-connecting headers" , nodestate->nUnconnectingHeaders ));
2237+ Misbehaving (peer , 20 , strprintf (" %d non-connecting headers" , nodestate->nUnconnectingHeaders ));
22342238 }
22352239 return ;
22362240 }
22372241
22382242 uint256 hashLastBlock;
22392243 for (const CBlockHeader& header : headers) {
22402244 if (!hashLastBlock.IsNull () && header.hashPrevBlock != hashLastBlock) {
2241- Misbehaving (pfrom. GetId () , 20 , " non-continuous headers sequence" );
2245+ Misbehaving (peer , 20 , " non-continuous headers sequence" );
22422246 return ;
22432247 }
22442248 hashLastBlock = header.GetHash ();
@@ -3001,7 +3005,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
30013005
30023006 if (vAddr.size () > MAX_ADDR_TO_SEND)
30033007 {
3004- Misbehaving (pfrom. GetId () , 20 , strprintf (" %s message size = %u" , msg_type, vAddr.size ()));
3008+ Misbehaving (*peer , 20 , strprintf (" %s message size = %u" , msg_type, vAddr.size ()));
30053009 return ;
30063010 }
30073011
@@ -3082,7 +3086,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
30823086 vRecv >> vInv;
30833087 if (vInv.size () > MAX_INV_SZ)
30843088 {
3085- Misbehaving (pfrom. GetId () , 20 , strprintf (" inv message size = %u" , vInv.size ()));
3089+ Misbehaving (*peer , 20 , strprintf (" inv message size = %u" , vInv.size ()));
30863090 return ;
30873091 }
30883092
@@ -3150,7 +3154,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
31503154 vRecv >> vInv;
31513155 if (vInv.size () > MAX_INV_SZ)
31523156 {
3153- Misbehaving (pfrom. GetId () , 20 , strprintf (" getdata message size = %u" , vInv.size ()));
3157+ Misbehaving (*peer , 20 , strprintf (" getdata message size = %u" , vInv.size ()));
31543158 return ;
31553159 }
31563160
@@ -3248,7 +3252,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
32483252 // Unlock m_most_recent_block_mutex to avoid cs_main lock inversion
32493253 }
32503254 if (recent_block) {
3251- SendBlockTransactions (pfrom, *recent_block, req);
3255+ SendBlockTransactions (pfrom, *peer, * recent_block, req);
32523256 return ;
32533257 }
32543258
@@ -3266,7 +3270,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
32663270 bool ret = ReadBlockFromDisk (block, pindex, m_chainparams.GetConsensus ());
32673271 assert (ret);
32683272
3269- SendBlockTransactions (pfrom, block, req);
3273+ SendBlockTransactions (pfrom, *peer, block, req);
32703274 return ;
32713275 }
32723276 }
@@ -3685,7 +3689,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
36853689 ReadStatus status = partialBlock.InitData (cmpctblock, vExtraTxnForCompact);
36863690 if (status == READ_STATUS_INVALID) {
36873691 RemoveBlockRequest (pindex->GetBlockHash ()); // Reset in-flight state in case Misbehaving does not result in a disconnect
3688- Misbehaving (pfrom. GetId () , 100 , " invalid compact block" );
3692+ Misbehaving (*peer , 100 , " invalid compact block" );
36893693 return ;
36903694 } else if (status == READ_STATUS_FAILED) {
36913695 // 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,
38123816 ReadStatus status = partialBlock.FillBlock (*pblock, resp.txn );
38133817 if (status == READ_STATUS_INVALID) {
38143818 RemoveBlockRequest (resp.blockhash ); // Reset in-flight state in case Misbehaving does not result in a disconnect
3815- Misbehaving (pfrom. GetId () , 100 , " invalid compact block/non-matching block transactions" );
3819+ Misbehaving (*peer , 100 , " invalid compact block/non-matching block transactions" );
38163820 return ;
38173821 } else if (status == READ_STATUS_FAILED) {
38183822 // Might have collided, fall back to getdata now :(
@@ -3873,7 +3877,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
38733877 // Bypass the normal CBlock deserialization, as we don't want to risk deserializing 2000 full blocks.
38743878 unsigned int nCount = ReadCompactSize (vRecv);
38753879 if (nCount > MAX_HEADERS_RESULTS) {
3876- Misbehaving (pfrom. GetId () , 20 , strprintf (" headers message size = %u" , nCount));
3880+ Misbehaving (*peer , 20 , strprintf (" headers message size = %u" , nCount));
38773881 return ;
38783882 }
38793883 headers.resize (nCount);
@@ -4067,7 +4071,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
40674071 if (!filter.IsWithinSizeConstraints ())
40684072 {
40694073 // There is no excuse for sending a too-large filter
4070- Misbehaving (pfrom. GetId () , 100 , " too-large bloom filter" );
4074+ Misbehaving (*peer , 100 , " too-large bloom filter" );
40714075 } else if (auto tx_relay = peer->GetTxRelay (); tx_relay != nullptr ) {
40724076 {
40734077 LOCK (tx_relay->m_bloom_filter_mutex );
@@ -4103,7 +4107,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
41034107 }
41044108 }
41054109 if (bad) {
4106- Misbehaving (pfrom. GetId () , 100 , " bad filteradd message" );
4110+ Misbehaving (*peer , 100 , " bad filteradd message" );
41074111 }
41084112 return ;
41094113 }
0 commit comments