@@ -630,7 +630,7 @@ class PeerManagerImpl final : public PeerManager
630630 void RelayRecoveredSig (const llmq::CRecoveredSig& sig, bool proactive_relay) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
631631 void RelayDSQ (const CCoinJoinQueue& queue) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
632632 void SetBestHeight (int height) override { m_best_height = height; };
633- void Misbehaving ( const NodeId pnode, const int howmuch, const std::string& message = " " ) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
633+ void UnitTestMisbehaving ( NodeId peer_id, int howmuch) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex) { Misbehaving (* Assert ( GetPeerRef (peer_id)), howmuch, " " ); } ;
634634 void ProcessMessage (CNode& pfrom, const std::string& msg_type, CDataStream& vRecv,
635635 const std::chrono::microseconds time_received, const std::atomic<bool >& interruptMsgProc) override
636636 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, !m_recent_confirmed_transactions_mutex, !m_most_recent_block_mutex, g_msgproc_mutex);
@@ -706,6 +706,11 @@ class PeerManagerImpl final : public PeerManager
706706 * May return an empty shared_ptr if the Peer object can't be found. */
707707 PeerRef RemovePeer (NodeId id) EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
708708
709+ /* *
710+ * Increment peer's misbehavior score. If the new value surpasses DISCOURAGEMENT_THRESHOLD (specified on startup or by default), mark node to be discouraged, meaning the peer might be disconnected & added to the discouragement filter.
711+ */
712+ void Misbehaving (Peer& peer, int howmuch, const std::string& message);
713+
709714 /* *
710715 * Potentially mark a node discouraged based on the contents of a BlockValidationState object
711716 *
@@ -776,8 +781,7 @@ class PeerManagerImpl final : public PeerManager
776781 /* * Update peer state based on received headers message */
777782 void UpdatePeerStateForReceivedHeaders (CNode& pfrom, const CBlockIndex& last_header, bool received_new_header, bool may_have_more_headers);
778783
779- void SendBlockTransactions (CNode& pfrom, const CBlock& block, const BlockTransactionsRequest& req)
780- EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
784+ void SendBlockTransactions (CNode& pfrom, Peer& peer, const CBlock& block, const BlockTransactionsRequest& req);
781785
782786 /* * Send a version message to a peer */
783787 void PushNodeVersion (CNode& pnode, const Peer& peer);
@@ -1891,31 +1895,28 @@ void PeerManagerImpl::AddToCompactExtraTransactions(const CTransactionRef& tx)
18911895 vExtraTxnForCompactIt = (vExtraTxnForCompactIt + 1 ) % max_extra_txn;
18921896}
18931897
1894- void PeerManagerImpl::Misbehaving (const NodeId pnode, const int howmuch, const std::string& message)
1898+ void PeerManagerImpl::Misbehaving (Peer& peer, int howmuch, const std::string& message)
18951899{
18961900 assert (howmuch > 0 );
18971901
1898- PeerRef peer = GetPeerRef (pnode);
1899- if (peer == nullptr ) return ;
1900-
1901- LOCK (peer->m_misbehavior_mutex );
1902- const int score_before{peer->m_misbehavior_score };
1903- peer->m_misbehavior_score += howmuch;
1904- const int score_now{peer->m_misbehavior_score };
1902+ LOCK (peer.m_misbehavior_mutex );
1903+ const int score_before{peer.m_misbehavior_score };
1904+ peer.m_misbehavior_score += howmuch;
1905+ const int score_now{peer.m_misbehavior_score };
19051906
19061907 const std::string message_prefixed = message.empty () ? " " : (" : " + message);
19071908 std::string warning;
19081909
19091910 if (score_now >= DISCOURAGEMENT_THRESHOLD && score_before < DISCOURAGEMENT_THRESHOLD ) {
19101911 warning = " DISCOURAGE THRESHOLD EXCEEDED" ;
1911- peer-> m_should_discourage = true ;
1912+ peer. m_should_discourage = true ;
19121913 ::g_stats_client->inc (" misbehavior.banned" , 1 .0f );
19131914 } else {
19141915 ::g_stats_client->count (" misbehavior.amount" , howmuch, 1.0 );
19151916 }
19161917
19171918 LogPrint (BCLog::NET , " Misbehaving: peer=%d (%d -> %d)%s%s\n " ,
1918- pnode , score_before, score_now, warning, message_prefixed);
1919+ peer. m_id , score_before, score_now, warning, message_prefixed);
19191920}
19201921
19211922bool PeerManagerImpl::IsBanned (NodeId pnode)
@@ -1933,14 +1934,15 @@ bool PeerManagerImpl::IsBanned(NodeId pnode)
19331934bool PeerManagerImpl::MaybePunishNodeForBlock (NodeId nodeid, const BlockValidationState& state,
19341935 bool via_compact_block, const std::string& message)
19351936{
1937+ PeerRef peer{GetPeerRef (nodeid)};
19361938 switch (state.GetResult ()) {
19371939 case BlockValidationResult::BLOCK_RESULT_UNSET :
19381940 break ;
19391941 // The node is providing invalid data:
19401942 case BlockValidationResult::BLOCK_CONSENSUS :
19411943 case BlockValidationResult::BLOCK_MUTATED :
19421944 if (!via_compact_block) {
1943- Misbehaving (nodeid , 100 , message);
1945+ if (peer) Misbehaving (*peer , 100 , message);
19441946 return true ;
19451947 }
19461948 break ;
@@ -1955,20 +1957,21 @@ bool PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidati
19551957 // Discourage outbound (but not inbound) peers if on an invalid chain.
19561958 // Exempt HB compact block peers. Manual connections are always protected from discouragement.
19571959 if (!via_compact_block && !node_state->m_is_inbound ) {
1958- Misbehaving (nodeid , 100 , message);
1960+ if (peer) Misbehaving (*peer , 100 , message);
19591961 return true ;
19601962 }
19611963 break ;
19621964 }
19631965 case BlockValidationResult::BLOCK_INVALID_HEADER :
19641966 case BlockValidationResult::BLOCK_CHECKPOINT :
19651967 case BlockValidationResult::BLOCK_INVALID_PREV :
1966- Misbehaving (nodeid , 100 , message);
1968+ if (peer) Misbehaving (*peer , 100 , message);
19671969 return true ;
19681970 // Conflicting (but not necessarily invalid) data or different policy:
19691971 case BlockValidationResult::BLOCK_MISSING_PREV :
19701972 case BlockValidationResult::BLOCK_CHAINLOCK :
1971- Misbehaving (nodeid, 10 , message);
1973+ if (peer) Misbehaving (*peer, 10 , message);
1974+ // TODO: Handle this much more gracefully (10 DoS points is super arbitrary)
19721975 return true ;
19731976 case BlockValidationResult::BLOCK_RECENT_CONSENSUS_CHANGE :
19741977 case BlockValidationResult::BLOCK_TIME_FUTURE :
@@ -1980,13 +1983,15 @@ bool PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidati
19801983 return false ;
19811984}
19821985
1983- bool PeerManagerImpl::MaybePunishNodeForTx (NodeId nodeid, const TxValidationState& state) {
1986+ bool PeerManagerImpl::MaybePunishNodeForTx (NodeId nodeid, const TxValidationState& state)
1987+ {
1988+ PeerRef peer{GetPeerRef (nodeid)};
19841989 switch (state.GetResult ()) {
19851990 case TxValidationResult::TX_RESULT_UNSET :
19861991 break ;
19871992 // The node is providing invalid data:
19881993 case TxValidationResult::TX_CONSENSUS :
1989- Misbehaving (nodeid , 100 );
1994+ if (peer) Misbehaving (*peer , 100 , " " );
19901995 return true ;
19911996 // Conflicting (but not necessarily invalid) data or different policy:
19921997 case TxValidationResult::TX_RECENT_CONSENSUS_CHANGE :
@@ -3031,11 +3036,11 @@ void PeerManagerImpl::ProcessGetData(CNode& pfrom, Peer& peer, const std::atomic
30313036 }
30323037}
30333038
3034- void PeerManagerImpl::SendBlockTransactions (CNode& pfrom, const CBlock& block, const BlockTransactionsRequest& req) {
3039+ void PeerManagerImpl::SendBlockTransactions (CNode& pfrom, Peer& peer, const CBlock& block, const BlockTransactionsRequest& req) {
30353040 BlockTransactions resp (req);
30363041 for (size_t i = 0 ; i < req.indexes .size (); i++) {
30373042 if (req.indexes [i] >= block.vtx .size ()) {
3038- Misbehaving (pfrom. GetId () , 100 , " getblocktxn with out-of-bounds tx indices" );
3043+ Misbehaving (peer , 100 , " getblocktxn with out-of-bounds tx indices" );
30393044 return ;
30403045 }
30413046 resp.txn [i] = block.vtx [req.indexes [i]];
@@ -3081,7 +3086,7 @@ void PeerManagerImpl::HandleFewUnconnectingHeaders(CNode& pfrom, Peer& peer,
30813086 // The peer may just be broken, so periodically assign DoS points if this
30823087 // condition persists.
30833088 if (nodestate->nUnconnectingHeaders % MAX_UNCONNECTING_HEADERS == 0 ) {
3084- Misbehaving (pfrom. GetId () , 20 , strprintf (" %d non-connecting headers" , nodestate->nUnconnectingHeaders ));
3089+ Misbehaving (peer , 20 , strprintf (" %d non-connecting headers" , nodestate->nUnconnectingHeaders ));
30853090 }
30863091}
30873092
@@ -3264,14 +3269,14 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, Peer& peer,
32643269 // could be benign.
32653270 HandleFewUnconnectingHeaders (pfrom, peer, headers);
32663271 } else {
3267- Misbehaving (pfrom. GetId () , 10 , " invalid header received" );
3272+ Misbehaving (peer , 10 , " invalid header received" );
32683273 }
32693274 return ;
32703275 }
32713276
32723277 // At this point, the headers connect to something in our block index.
32733278 if (!CheckHeadersAreContinuous (headers)) {
3274- Misbehaving (pfrom. GetId () , 20 , " non-continuous headers sequence" );
3279+ Misbehaving (peer , 20 , " non-continuous headers sequence" );
32753280 return ;
32763281 }
32773282
@@ -3602,7 +3607,7 @@ void PeerManagerImpl::ProcessBlock(CNode& node, const std::shared_ptr<const CBlo
36023607void PeerManagerImpl::PostProcessMessage (MessageProcessingResult&& result, NodeId node)
36033608{
36043609 if (result.m_error ) {
3605- Misbehaving (node, result.m_error ->score , result.m_error ->message );
3610+ Misbehaving (* Assert ( GetPeerRef ( node)) , result.m_error ->score , result.m_error ->message );
36063611 }
36073612 if (result.m_to_erase ) {
36083613 WITH_LOCK (cs_main, EraseObjectRequest (node, result.m_to_erase .value ()));
@@ -3809,9 +3814,9 @@ void PeerManagerImpl::ProcessMessage(
38093814 if (cleanSubVer.find (strprintf (" devnet.%s" , gArgs .GetDevNetName ())) == std::string::npos) {
38103815 LogPrintf (" connected to wrong devnet. Reported version is %s, expected devnet name is %s\n " , cleanSubVer, gArgs .GetDevNetName ());
38113816 if (!pfrom.IsInboundConn ())
3812- Misbehaving (pfrom. GetId () , 100 ); // don't try to connect again
3817+ Misbehaving (*peer , 100 , " wrong-devnet-name " ); // don't try to connect again
38133818 else
3814- Misbehaving (pfrom. GetId () , 1 ); // whover connected, might just have made a mistake, don't ban him immediately
3819+ Misbehaving (*peer , 1 , " wrong-devnet-name " ); // whover connected, might just have made a mistake, don't ban him immediately
38153820 pfrom.fDisconnect = true ;
38163821 return ;
38173822 }
@@ -4164,7 +4169,7 @@ void PeerManagerImpl::ProcessMessage(
41644169
41654170 if (vAddr.size () > MAX_ADDR_TO_SEND )
41664171 {
4167- Misbehaving (pfrom. GetId () , 20 , strprintf (" %s message size = %u" , msg_type, vAddr.size ()));
4172+ Misbehaving (*peer , 20 , strprintf (" %s message size = %u" , msg_type, vAddr.size ()));
41684173 return ;
41694174 }
41704175
@@ -4268,7 +4273,7 @@ void PeerManagerImpl::ProcessMessage(
42684273 vRecv >> vInv;
42694274 if (vInv.size () > MAX_INV_SZ )
42704275 {
4271- Misbehaving (pfrom. GetId () , 20 , strprintf (" inv message size = %u" , vInv.size ()));
4276+ Misbehaving (*peer , 20 , strprintf (" inv message size = %u" , vInv.size ()));
42724277 return ;
42734278 }
42744279
@@ -4374,8 +4379,7 @@ void PeerManagerImpl::ProcessMessage(
43744379 vRecv >> vInv;
43754380 if (vInv.size () > MAX_INV_SZ )
43764381 {
4377-
4378- Misbehaving (pfrom.GetId (), 20 , strprintf (" getdata message size = %u" , vInv.size ()));
4382+ Misbehaving (*peer, 20 , strprintf (" getdata message size = %u" , vInv.size ()));
43794383 return ;
43804384 }
43814385
@@ -4474,7 +4478,7 @@ void PeerManagerImpl::ProcessMessage(
44744478 // Unlock m_most_recent_block_mutex to avoid cs_main lock inversion
44754479 }
44764480 if (recent_block) {
4477- SendBlockTransactions (pfrom, *recent_block, req);
4481+ SendBlockTransactions (pfrom, *peer, * recent_block, req);
44784482 return ;
44794483 }
44804484
@@ -4492,7 +4496,7 @@ void PeerManagerImpl::ProcessMessage(
44924496 bool ret = ReadBlockFromDisk (block, pindex, m_chainparams.GetConsensus ());
44934497 assert (ret);
44944498
4495- SendBlockTransactions (pfrom, block, req);
4499+ SendBlockTransactions (pfrom, *peer, block, req);
44964500 return ;
44974501 }
44984502 }
@@ -4891,7 +4895,7 @@ void PeerManagerImpl::ProcessMessage(
48914895 ReadStatus status = partialBlock.InitData (cmpctblock, vExtraTxnForCompact);
48924896 if (status == READ_STATUS_INVALID ) {
48934897 RemoveBlockRequest (pindex->GetBlockHash (), pfrom.GetId ()); // Reset in-flight state in case Misbehaving does not result in a disconnect
4894- Misbehaving (pfrom. GetId () , 100 , " invalid compact block" );
4898+ Misbehaving (*peer , 100 , " invalid compact block" );
48954899 return ;
48964900 } else if (status == READ_STATUS_FAILED ) {
48974901 // Duplicate txindexes, the block is now in-flight, so just request it
@@ -5017,7 +5021,7 @@ void PeerManagerImpl::ProcessMessage(
50175021 ReadStatus status = partialBlock.FillBlock (*pblock, resp.txn );
50185022 if (status == READ_STATUS_INVALID ) {
50195023 RemoveBlockRequest (resp.blockhash , pfrom.GetId ()); // Reset in-flight state in case Misbehaving does not result in a disconnect
5020- Misbehaving (pfrom. GetId () , 100 , " invalid compact block/non-matching block transactions" );
5024+ Misbehaving (*peer , 100 , " invalid compact block/non-matching block transactions" );
50215025 return ;
50225026 } else if (status == READ_STATUS_FAILED ) {
50235027 // Might have collided, fall back to getdata now :(
@@ -5081,7 +5085,7 @@ void PeerManagerImpl::ProcessMessage(
50815085 // Bypass the normal CBlock deserialization, as we don't want to risk deserializing 2000 full blocks.
50825086 unsigned int nCount = ReadCompactSize (vRecv);
50835087 if (nCount > GetHeadersLimit (pfrom, msg_type == NetMsgType::HEADERS2 )) {
5084- Misbehaving (pfrom. GetId () , 20 , strprintf (" headers message size = %u" , nCount));
5088+ Misbehaving (*peer , 20 , strprintf (" headers message size = %u" , nCount));
50855089 return ;
50865090 }
50875091
@@ -5286,7 +5290,7 @@ void PeerManagerImpl::ProcessMessage(
52865290 if (!filter.IsWithinSizeConstraints ())
52875291 {
52885292 // There is no excuse for sending a too-large filter
5289- Misbehaving (pfrom. GetId () , 100 , " too-large bloom filter" );
5293+ Misbehaving (*peer , 100 , " too-large bloom filter" );
52905294 } else if (auto tx_relay = peer->GetTxRelay (); tx_relay != nullptr ) {
52915295 {
52925296 LOCK (tx_relay->m_bloom_filter_mutex );
@@ -5322,7 +5326,7 @@ void PeerManagerImpl::ProcessMessage(
53225326 }
53235327 }
53245328 if (bad) {
5325- Misbehaving (pfrom. GetId () , 100 , " bad filteradd message" );
5329+ Misbehaving (*peer , 100 , " bad filteradd message" );
53265330 }
53275331 return ;
53285332 }
@@ -5360,7 +5364,7 @@ void PeerManagerImpl::ProcessMessage(
53605364 m_connman.PushMessage (&pfrom, msgMaker.Make (NetMsgType::MNLISTDIFF , mnListDiff));
53615365 } else {
53625366 strError = strprintf (" getmnlistdiff failed for baseBlockHash=%s, blockHash=%s. error=%s" , cmd.baseBlockHash .ToString (), cmd.blockHash .ToString (), strError);
5363- Misbehaving (pfrom. GetId () , 1 , strError);
5367+ Misbehaving (*peer , 1 , strError);
53645368 }
53655369 return ;
53665370 }
@@ -5383,7 +5387,7 @@ void PeerManagerImpl::ProcessMessage(
53835387
53845388 if (msg_type == NetMsgType::MNLISTDIFF ) {
53855389 // we have never requested this
5386- Misbehaving (pfrom. GetId () , 100 , strprintf (" received not-requested mnlistdiff. peer=%d" , pfrom.GetId ()));
5390+ Misbehaving (*peer , 100 , strprintf (" received not-requested mnlistdiff. peer=%d" , pfrom.GetId ()));
53875391 return ;
53885392 }
53895393
@@ -5400,7 +5404,7 @@ void PeerManagerImpl::ProcessMessage(
54005404 m_connman.PushMessage (&pfrom, msgMaker.Make (NetMsgType::QUORUMROTATIONINFO , quorumRotationInfoRet));
54015405 } else {
54025406 strError = strprintf (" getquorumrotationinfo failed for size(baseBlockHashes)=%d, blockRequestHash=%s. error=%s" , cmd.baseBlockHashes .size (), cmd.blockRequestHash .ToString (), strError);
5403- Misbehaving (pfrom. GetId () , 1 , strError);
5407+ Misbehaving (*peer , 1 , strError);
54045408 }
54055409 return ;
54065410 }
@@ -5414,7 +5418,7 @@ void PeerManagerImpl::ProcessMessage(
54145418 WITH_LOCK (::cs_main, EraseObjectRequest (pfrom.GetId (), spork_inv));
54155419 auto opt_signer = m_sporkman.GetValidSporkSigner (spork);
54165420 if (!opt_signer) {
5417- Misbehaving (pfrom. GetId () , 100 , strprintf (" invalid spork received. peer=%d" , pfrom.GetId ()));
5421+ Misbehaving (*peer , 100 , strprintf (" invalid spork received. peer=%d" , pfrom.GetId ()));
54185422 return ;
54195423 }
54205424 if (m_sporkman.ProcessSpork (spork, *opt_signer, strprintf (" peer=%d" , pfrom.GetId ()))) {
@@ -5436,7 +5440,7 @@ void PeerManagerImpl::ProcessMessage(
54365440
54375441 if (msg_type == NetMsgType::QUORUMROTATIONINFO ) {
54385442 // we have never requested this
5439- Misbehaving (pfrom. GetId () , 100 , strprintf (" received not-requested quorumrotationinfo. peer=%d" , pfrom.GetId ()));
5443+ Misbehaving (*peer , 100 , strprintf (" received not-requested quorumrotationinfo. peer=%d" , pfrom.GetId ()));
54405444 return ;
54415445 }
54425446 if (msg_type == NetMsgType::NOTFOUND ) {
@@ -6578,7 +6582,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
65786582
65796583void PeerManagerImpl::PeerMisbehaving (const NodeId pnode, const int howmuch, const std::string& message)
65806584{
6581- Misbehaving (pnode, howmuch, message);
6585+ Misbehaving (* Assert ( GetPeerRef ( pnode)) , howmuch, message);
65826586}
65836587
65846588bool PeerManagerImpl::PeerIsBanned (const NodeId node_id)
0 commit comments