@@ -959,27 +959,68 @@ void Misbehaving(NodeId pnode, int howmuch, const std::string& message) EXCLUSIV
959
959
LogPrint (BCLog::NET, " %s: %s peer=%d (%d -> %d)%s\n " , __func__, state->name , pnode, state->nMisbehavior -howmuch, state->nMisbehavior , message_prefixed);
960
960
}
961
961
962
+ /* *
963
+ * Returns true if the given validation state result may result in a peer
964
+ * banning/disconnecting us. We use this to determine which unaccepted
965
+ * transactions from a whitelisted peer that we can safely relay.
966
+ */
962
967
static bool TxRelayMayResultInDisconnect (const CValidationState& state)
963
968
{
964
- return ( state.GetDoS () > 0 ) ;
969
+ return state.GetReason () == ValidationInvalidReason::CONSENSUS ;
965
970
}
966
971
967
972
/* *
968
973
* Potentially ban a node based on the contents of a CValidationState object
969
- * TODO: net_processing should make the punish decision based on the reason
970
- * a tx/block was invalid, rather than just the nDoS score handed back by validation.
971
974
*
972
- * @parameter via_compact_block: this bool is passed in because net_processing should
975
+ * @param[in] via_compact_block: this bool is passed in because net_processing should
973
976
* punish peers differently depending on whether the data was provided in a compact
974
977
* block message or not. If the compact block had a valid header, but contained invalid
975
978
* txs, the peer should not be punished. See BIP 152.
979
+ *
980
+ * @return Returns true if the peer was punished (probably disconnected)
981
+ *
982
+ * Changes here may need to be reflected in TxRelayMayResultInDisconnect().
976
983
*/
977
984
static bool MaybePunishNode (NodeId nodeid, const CValidationState& state, bool via_compact_block, const std::string& message = " " ) {
978
- int nDoS = state.GetDoS ();
979
- if (nDoS > 0 && !via_compact_block) {
980
- LOCK (cs_main);
981
- Misbehaving (nodeid, nDoS, message);
982
- return true ;
985
+ switch (state.GetReason ()) {
986
+ case ValidationInvalidReason::NONE:
987
+ break ;
988
+ // The node is providing invalid data:
989
+ case ValidationInvalidReason::CONSENSUS:
990
+ case ValidationInvalidReason::BLOCK_MUTATED:
991
+ if (!via_compact_block) {
992
+ LOCK (cs_main);
993
+ Misbehaving (nodeid, 100 , message);
994
+ return true ;
995
+ }
996
+ break ;
997
+ // Handled elsewhere for now
998
+ case ValidationInvalidReason::CACHED_INVALID:
999
+ break ;
1000
+ case ValidationInvalidReason::BLOCK_INVALID_HEADER:
1001
+ case ValidationInvalidReason::BLOCK_CHECKPOINT:
1002
+ case ValidationInvalidReason::BLOCK_INVALID_PREV:
1003
+ {
1004
+ LOCK (cs_main);
1005
+ Misbehaving (nodeid, 100 , message);
1006
+ }
1007
+ return true ;
1008
+ // Conflicting (but not necessarily invalid) data or different policy:
1009
+ case ValidationInvalidReason::BLOCK_MISSING_PREV:
1010
+ {
1011
+ // TODO: Handle this much more gracefully (10 DoS points is super arbitrary)
1012
+ LOCK (cs_main);
1013
+ Misbehaving (nodeid, 10 , message);
1014
+ }
1015
+ return true ;
1016
+ case ValidationInvalidReason::RECENT_CONSENSUS_CHANGE:
1017
+ case ValidationInvalidReason::BLOCK_TIME_FUTURE:
1018
+ case ValidationInvalidReason::TX_NOT_STANDARD:
1019
+ case ValidationInvalidReason::TX_MISSING_INPUTS:
1020
+ case ValidationInvalidReason::TX_WITNESS_MUTATED:
1021
+ case ValidationInvalidReason::TX_CONFLICT:
1022
+ case ValidationInvalidReason::TX_MEMPOOL_POLICY:
1023
+ break ;
983
1024
}
984
1025
if (message != " " ) {
985
1026
LogPrint (BCLog::NET, " peer=%d: %s\n " , nodeid, message);
@@ -2513,14 +2554,13 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
2513
2554
// to policy, allowing the node to function as a gateway for
2514
2555
// nodes hidden behind it.
2515
2556
//
2516
- // Never relay transactions that we would assign a non-zero DoS
2517
- // score for, as we expect peers to do the same with us in that
2518
- // case.
2519
- if (!state.IsInvalid () || !TxRelayMayResultInDisconnect (state)) {
2557
+ // Never relay transactions that might result in being
2558
+ // disconnected (or banned).
2559
+ if (state.IsInvalid () && TxRelayMayResultInDisconnect (state)) {
2560
+ LogPrintf (" Not relaying invalid transaction %s from whitelisted peer=%d (%s)\n " , tx.GetHash ().ToString (), pfrom->GetId (), FormatStateMessage (state));
2561
+ } else {
2520
2562
LogPrintf (" Force relaying tx %s from whitelisted peer=%d\n " , tx.GetHash ().ToString (), pfrom->GetId ());
2521
2563
RelayTransaction (tx, connman);
2522
- } else {
2523
- LogPrintf (" Not relaying invalid transaction %s from whitelisted peer=%d (%s)\n " , tx.GetHash ().ToString (), pfrom->GetId (), FormatStateMessage (state));
2524
2564
}
2525
2565
}
2526
2566
}
@@ -2590,21 +2630,8 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
2590
2630
const CBlockIndex *pindex = nullptr ;
2591
2631
CValidationState state;
2592
2632
if (!ProcessNewBlockHeaders ({cmpctblock.header }, state, chainparams, &pindex)) {
2593
- if (state.IsInvalid () && received_new_header) {
2594
- // In this situation, the block header is known to be invalid.
2595
- // If we never created a CBlockIndex entry for it, then the
2596
- // header must be bad just by inspection (and is not one that
2597
- // looked okay but the block later turned out to be invalid for
2598
- // some other reason).
2599
- // We should punish compact block peers that give us an invalid
2600
- // header (other than a "duplicate-invalid" one, see
2601
- // ProcessHeadersMessage), so set via_compact_block to false
2602
- // here.
2603
- // TODO: when we switch from DoS scores to reasons that
2604
- // tx/blocks are invalid, this call should set
2605
- // via_compact_block to true, since MaybePunishNode will have
2606
- // sufficient information to act correctly.
2607
- MaybePunishNode (pfrom->GetId (), state, /* via_compact_block*/ false , " invalid header via cmpctblock" );
2633
+ if (state.IsInvalid ()) {
2634
+ MaybePunishNode (pfrom->GetId (), state, /* via_compact_block*/ true , " invalid header via cmpctblock" );
2608
2635
return true ;
2609
2636
}
2610
2637
}
0 commit comments