Skip to content

Commit ef54b48

Browse files
TheBlueMattsdaftuar
authored andcommitted
[refactor] Use Reasons directly instead of DoS codes
1 parent 9ab2a04 commit ef54b48

File tree

1 file changed

+57
-30
lines changed

1 file changed

+57
-30
lines changed

src/net_processing.cpp

Lines changed: 57 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -959,27 +959,68 @@ void Misbehaving(NodeId pnode, int howmuch, const std::string& message) EXCLUSIV
959959
LogPrint(BCLog::NET, "%s: %s peer=%d (%d -> %d)%s\n", __func__, state->name, pnode, state->nMisbehavior-howmuch, state->nMisbehavior, message_prefixed);
960960
}
961961

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+
*/
962967
static bool TxRelayMayResultInDisconnect(const CValidationState& state)
963968
{
964-
return (state.GetDoS() > 0);
969+
return state.GetReason() == ValidationInvalidReason::CONSENSUS;
965970
}
966971

967972
/**
968973
* 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.
971974
*
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
973976
* punish peers differently depending on whether the data was provided in a compact
974977
* block message or not. If the compact block had a valid header, but contained invalid
975978
* 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().
976983
*/
977984
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;
9831024
}
9841025
if (message != "") {
9851026
LogPrint(BCLog::NET, "peer=%d: %s\n", nodeid, message);
@@ -2513,14 +2554,13 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
25132554
// to policy, allowing the node to function as a gateway for
25142555
// nodes hidden behind it.
25152556
//
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 {
25202562
LogPrintf("Force relaying tx %s from whitelisted peer=%d\n", tx.GetHash().ToString(), pfrom->GetId());
25212563
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));
25242564
}
25252565
}
25262566
}
@@ -2590,21 +2630,8 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
25902630
const CBlockIndex *pindex = nullptr;
25912631
CValidationState state;
25922632
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");
26082635
return true;
26092636
}
26102637
}

0 commit comments

Comments
 (0)