merge bitcoin#19607: Add Peer struct for per-peer data in net processing

This commit is contained in:
Kittywhiskers Van Gogh 2023-02-16 17:46:27 +00:00 committed by UdjinM6
parent 698a717ecd
commit 07fe6d4738
16 changed files with 110 additions and 121 deletions

View File

@ -54,7 +54,6 @@ void CCoinJoinClientQueueManager::ProcessDSQueue(const CNode& peer, CDataStream&
vRecv >> dsq;
if (dsq.masternodeOutpoint.IsNull() && dsq.m_protxHash.IsNull()) {
LOCK(cs_main);
Misbehaving(peer.GetId(), 100);
return;
}
@ -64,7 +63,6 @@ void CCoinJoinClientQueueManager::ProcessDSQueue(const CNode& peer, CDataStream&
if (auto dmn = mnList.GetValidMN(dsq.m_protxHash)) {
dsq.masternodeOutpoint = dmn->collateralOutpoint;
} else {
LOCK(cs_main);
Misbehaving(peer.GetId(), 10);
return;
}
@ -100,7 +98,6 @@ void CCoinJoinClientQueueManager::ProcessDSQueue(const CNode& peer, CDataStream&
}
if (!dsq.CheckSignature(dmn->pdmnState->pubKeyOperator.Get())) {
LOCK(cs_main);
Misbehaving(peer.GetId(), 10);
return;
}

View File

@ -113,7 +113,6 @@ void CCoinJoinServer::ProcessDSQUEUE(const CNode& peer, CDataStream& vRecv)
vRecv >> dsq;
if (dsq.masternodeOutpoint.IsNull() && dsq.m_protxHash.IsNull()) {
LOCK(cs_main);
Misbehaving(peer.GetId(), 100);
return;
}
@ -123,7 +122,6 @@ void CCoinJoinServer::ProcessDSQUEUE(const CNode& peer, CDataStream& vRecv)
if (auto dmn = mnList.GetValidMN(dsq.m_protxHash)) {
dsq.masternodeOutpoint = dmn->collateralOutpoint;
} else {
LOCK(cs_main);
Misbehaving(peer.GetId(), 10);
return;
}
@ -159,7 +157,6 @@ void CCoinJoinServer::ProcessDSQUEUE(const CNode& peer, CDataStream& vRecv)
}
if (!dsq.CheckSignature(dmn->pdmnState->pubKeyOperator.Get())) {
LOCK(cs_main);
Misbehaving(peer.GetId(), 10);
return;
}

View File

@ -70,26 +70,22 @@ void CMNAuth::ProcessMessage(CNode& peer, CConnman& connman, std::string_view ms
// only one MNAUTH allowed
if (!peer.GetVerifiedProRegTxHash().IsNull()) {
LOCK(cs_main);
Misbehaving(peer.GetId(), 100, "duplicate mnauth");
return;
}
if ((~peer.nServices) & (NODE_NETWORK | NODE_BLOOM)) {
// either NODE_NETWORK or NODE_BLOOM bit is missing in node's services
LOCK(cs_main);
Misbehaving(peer.GetId(), 100, "mnauth from a node with invalid services");
return;
}
if (mnauth.proRegTxHash.IsNull()) {
LOCK(cs_main);
Misbehaving(peer.GetId(), 100, "empty mnauth proRegTxHash");
return;
}
if (!mnauth.sig.IsValid()) {
LOCK(cs_main);
Misbehaving(peer.GetId(), 100, "invalid mnauth signature");
return;
}
@ -97,7 +93,6 @@ void CMNAuth::ProcessMessage(CNode& peer, CConnman& connman, std::string_view ms
const auto mnList = deterministicMNManager->GetListAtChainTip();
const auto dmn = mnList.GetMN(mnauth.proRegTxHash);
if (!dmn) {
LOCK(cs_main);
// in case node was unlucky and not up to date, just let it be connected as a regular node, which gives it
// a chance to get up-to-date and thus realize that it's not a MN anymore. We still give it a
// low DoS score.
@ -122,7 +117,6 @@ void CMNAuth::ProcessMessage(CNode& peer, CConnman& connman, std::string_view ms
LogPrint(BCLog::NET_NETCONN, "CMNAuth::%s -- constructed signHash for nVersion %d, peer=%d\n", __func__, peer.nVersion, peer.GetId());
if (!mnauth.sig.VerifyInsecure(dmn->pdmnState->pubKeyOperator.Get(), signHash)) {
LOCK(cs_main);
// Same as above, MN seems to not know its fate yet, so give it a chance to update. If this is a
// malicious node (DoSing us), it'll get banned soon.
Misbehaving(peer.GetId(), 10, "mnauth signature verification failed");

View File

@ -219,7 +219,6 @@ void CGovernanceManager::ProcessMessage(CNode& peer, CConnman& connman, std::str
} else {
LogPrint(BCLog::GOBJECT, "MNGOVERNANCEOBJECTVOTE -- Rejected vote, error = %s\n", exception.what());
if ((exception.GetNodePenalty() != 0) && ::masternodeSync->IsSynced()) {
LOCK(cs_main);
Misbehaving(peer.GetId(), exception.GetNodePenalty());
}
return;
@ -625,7 +624,6 @@ void CGovernanceManager::SyncObjects(CNode& peer, CConnman& connman) const
if (netfulfilledman.HasFulfilledRequest(peer.addr, NetMsgType::MNGOVERNANCESYNC)) {
// Asking for the whole list multiple times in a short period of time is no good
LogPrint(BCLog::GOBJECT, "CGovernanceManager::%s -- peer already asked me for the list\n", __func__);
LOCK(cs_main);
Misbehaving(peer.GetId(), 20);
return;
}

View File

@ -55,14 +55,14 @@ void CQuorumBlockProcessor::ProcessMessage(const CNode& peer, std::string_view m
if (qc.IsNull()) {
LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- null commitment from peer=%d\n", __func__, peer.GetId());
WITH_LOCK(cs_main, Misbehaving(peer.GetId(), 100));
Misbehaving(peer.GetId(), 100);
return;
}
if (!Params().HasLLMQ(qc.llmqType)) {
LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- invalid commitment type %d from peer=%d\n", __func__,
ToUnderlying(qc.llmqType), peer.GetId());
WITH_LOCK(cs_main, Misbehaving(peer.GetId(), 100));
Misbehaving(peer.GetId(), 100);
return;
}
auto type = qc.llmqType;
@ -125,7 +125,7 @@ void CQuorumBlockProcessor::ProcessMessage(const CNode& peer, std::string_view m
LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- commitment for quorum %s:%d is not valid quorumIndex[%d] nversion[%d], peer=%d\n",
__func__, qc.quorumHash.ToString(),
ToUnderlying(qc.llmqType), qc.quorumIndex, qc.nVersion, peer.GetId());
WITH_LOCK(cs_main, Misbehaving(peer.GetId(), 100));
Misbehaving(peer.GetId(), 100);
return;
}

View File

@ -125,7 +125,6 @@ void CChainLocksHandler::ProcessNewChainLock(const NodeId from, const llmq::CCha
if (!llmq::CSigningManager::VerifyRecoveredSig(Params().GetConsensus().llmqTypeChainLocks, *llmq::quorumManager, clsig.getHeight(), requestId, clsig.getBlockHash(), clsig.getSig())) {
LogPrint(BCLog::CHAINLOCKS, "CChainLocksHandler::%s -- invalid CLSIG (%s), peer=%d\n", __func__, clsig.ToString(), from);
if (from != -1) {
LOCK(cs_main);
Misbehaving(from, 10);
}
return;

View File

@ -429,7 +429,6 @@ bool ProcessPendingMessageBatch(CDKGSession& session, CDKGPendingMessages& pendi
if (!p.second) {
LogPrint(BCLog::LLMQ_DKG, "%s -- failed to deserialize message, peer=%d\n", __func__, nodeId);
{
LOCK(cs_main);
Misbehaving(nodeId, 100);
}
continue;
@ -439,7 +438,6 @@ bool ProcessPendingMessageBatch(CDKGSession& session, CDKGPendingMessages& pendi
if (ban) {
LogPrint(BCLog::LLMQ_DKG, "%s -- banning node due to failed preverification, peer=%d\n", __func__, nodeId);
{
LOCK(cs_main);
Misbehaving(nodeId, 100);
}
}
@ -470,7 +468,6 @@ bool ProcessPendingMessageBatch(CDKGSession& session, CDKGPendingMessages& pendi
session.ReceiveMessage(*p.second, ban);
if (ban) {
LogPrint(BCLog::LLMQ_DKG, "%s -- banning node after ReceiveMessage failed, peer=%d\n", __func__, nodeId);
LOCK(cs_main);
Misbehaving(nodeId, 100);
badNodes.emplace(nodeId);
}

View File

@ -185,7 +185,6 @@ void CDKGSessionManager::ProcessMessage(CNode& pfrom, const CQuorumManager& quor
}
if (vRecv.empty()) {
LOCK(cs_main);
Misbehaving(pfrom.GetId(), 100);
return;
}
@ -198,7 +197,6 @@ void CDKGSessionManager::ProcessMessage(CNode& pfrom, const CQuorumManager& quor
vRecv.Rewind(sizeof(uint8_t));
if (!Params().HasLLMQ(llmqType)) {
LOCK(cs_main);
LogPrintf("CDKGSessionManager -- invalid llmqType [%d]\n", ToUnderlying(llmqType));
Misbehaving(pfrom.GetId(), 100);
return;
@ -219,7 +217,6 @@ void CDKGSessionManager::ProcessMessage(CNode& pfrom, const CQuorumManager& quor
if (quorumIndex == -1) {
CBlockIndex* pQuorumBaseBlockIndex = WITH_LOCK(cs_main, return LookupBlockIndex(quorumHash));
if (pQuorumBaseBlockIndex == nullptr) {
LOCK(cs_main);
LogPrintf("CDKGSessionManager -- unknown quorumHash %s\n", quorumHash.ToString());
// NOTE: do not insta-ban for this, we might be lagging behind
Misbehaving(pfrom.GetId(), 10);
@ -227,7 +224,6 @@ void CDKGSessionManager::ProcessMessage(CNode& pfrom, const CQuorumManager& quor
}
if (!utils::IsQuorumTypeEnabled(llmqType, quorum_manager, pQuorumBaseBlockIndex->pprev)) {
LOCK(cs_main);
LogPrintf("CDKGSessionManager -- llmqType [%d] quorums aren't active\n", ToUnderlying(llmqType));
Misbehaving(pfrom.GetId(), 100);
return;
@ -239,14 +235,12 @@ void CDKGSessionManager::ProcessMessage(CNode& pfrom, const CQuorumManager& quor
llmqParams.signingActiveQuorumCount - 1 : 0;
if (quorumIndex > quorumIndexMax) {
LOCK(cs_main);
LogPrintf("CDKGSessionManager -- invalid quorumHash %s\n", quorumHash.ToString());
Misbehaving(pfrom.GetId(), 100);
return;
}
if (!dkgSessionHandlers.count(std::make_pair(llmqType, quorumIndex))) {
LOCK(cs_main);
LogPrintf("CDKGSessionManager -- no session handlers for quorumIndex [%d]\n", quorumIndex);
Misbehaving(pfrom.GetId(), 100);
return;

View File

@ -788,7 +788,6 @@ void CInstantSendManager::ProcessMessageInstantSendLock(const CNode& pfrom, cons
}
if (!islock->TriviallyValid()) {
LOCK(cs_main);
Misbehaving(pfrom.GetId(), 100);
return;
}
@ -798,14 +797,14 @@ void CInstantSendManager::ProcessMessageInstantSendLock(const CNode& pfrom, cons
const auto blockIndex = WITH_LOCK(cs_main, return LookupBlockIndex(islock->cycleHash));
if (blockIndex == nullptr) {
// Maybe we don't have the block yet or maybe some peer spams invalid values for cycleHash
WITH_LOCK(cs_main, Misbehaving(pfrom.GetId(), 1));
Misbehaving(pfrom.GetId(), 1);
return;
}
// Deterministic islocks MUST use rotation based llmq
auto llmqType = Params().GetConsensus().llmqTypeDIP0024InstantSend;
if (blockIndex->nHeight % GetLLMQParams(llmqType).dkgInterval != 0) {
WITH_LOCK(cs_main, Misbehaving(pfrom.GetId(), 100));
Misbehaving(pfrom.GetId(), 100);
return;
}
}

View File

@ -611,7 +611,6 @@ void CQuorumManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, C
auto errorHandler = [&](const std::string& strError, int nScore = 10) {
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- %s: %s, from peer=%d\n", strFunc, msg_type, strError, pfrom.GetId());
if (nScore > 0) {
LOCK(cs_main);
Misbehaving(pfrom.GetId(), nScore);
}
};

View File

@ -577,7 +577,6 @@ void CSigningManager::ProcessMessageRecoveredSig(const CNode& pfrom, const std::
bool ban = false;
if (!PreVerifyRecoveredSig(qman, *recoveredSig, ban)) {
if (ban) {
LOCK(cs_main);
Misbehaving(pfrom.GetId(), 100);
}
return;
@ -752,7 +751,6 @@ bool CSigningManager::ProcessPendingRecoveredSigs()
if (batchVerifier.badSources.count(nodeId)) {
LogPrint(BCLog::LLMQ, "CSigningManager::%s -- invalid recSig from other node, banning peer=%d\n", __func__, nodeId);
LOCK(cs_main);
Misbehaving(nodeId, 100);
continue;
}

View File

@ -1402,7 +1402,6 @@ void CSigSharesManager::BanNode(NodeId nodeId)
}
{
LOCK(cs_main);
Misbehaving(nodeId, 100);
}

View File

@ -268,12 +268,6 @@ struct CNodeState {
const CService address;
//! Whether we have a fully established connection.
bool fCurrentlyConnected;
//! Accumulated misbehaviour score for this peer.
int nMisbehavior;
//! Whether this peer should be disconnected and marked as discouraged (unless it has the noban permission).
bool m_should_discourage;
//! String name of this peer (debugging/logging purposes).
const std::string name;
//! The best known block we know this peer has announced.
const CBlockIndex *pindexBestKnownBlock;
//! The hash of the last unknown block this peer has announced.
@ -410,13 +404,10 @@ struct CNodeState {
//! Whether this peer is a manual connection
bool m_is_manual_connection;
CNodeState(CAddress addrIn, std::string addrNameIn, bool is_inbound, bool is_manual) :
address(addrIn), name(std::move(addrNameIn)), m_is_inbound(is_inbound),
m_is_manual_connection (is_manual)
CNodeState(CAddress addrIn, bool is_inbound, bool is_manual) :
address(addrIn), m_is_inbound(is_inbound), m_is_manual_connection(is_manual)
{
fCurrentlyConnected = false;
nMisbehavior = 0;
m_should_discourage = false;
pindexBestKnownBlock = nullptr;
hashLastUnknownBlock.SetNull();
pindexLastCommonBlock = nullptr;
@ -453,6 +444,50 @@ static CNodeState *State(NodeId pnode) EXCLUSIVE_LOCKS_REQUIRED(cs_main) {
return &it->second;
}
/**
* Data structure for an individual peer. This struct is not protected by
* cs_main since it does not contain validation-critical data.
*
* Memory is owned by shared pointers and this object is destructed when
* the refcount drops to zero.
*
* TODO: move most members from CNodeState to this structure.
* TODO: move remaining application-layer data members from CNode to this structure.
*/
struct Peer {
/** Same id as the CNode object for this peer */
const NodeId m_id{0};
/** Protects misbehavior data members */
Mutex m_misbehavior_mutex;
/** Accumulated misbehavior score for this peer */
int nMisbehavior GUARDED_BY(m_misbehavior_mutex){0};
/** Whether this peer should be disconnected and marked as discouraged (unless it has the noban permission). */
bool m_should_discourage GUARDED_BY(m_misbehavior_mutex){false};
Peer(NodeId id) : m_id(id) {}
};
using PeerRef = std::shared_ptr<Peer>;
/**
* Map of all Peer objects, keyed by peer id. This map is protected
* by the global g_peer_mutex. Once a shared pointer reference is
* taken, the lock may be released. Individual fields are protected by
* their own locks.
*/
Mutex g_peer_mutex;
static std::map<NodeId, PeerRef> g_peer_map GUARDED_BY(g_peer_mutex);
/** Get a shared pointer to the Peer object.
* May return nullptr if the Peer object can't be found. */
static PeerRef GetPeerRef(NodeId id)
{
LOCK(g_peer_mutex);
auto it = g_peer_map.find(id);
return it != g_peer_map.end() ? it->second : nullptr;
}
static void UpdatePreferredDownload(const CNode& node, CNodeState* state) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
nPreferredDownload -= state->fPreferredDownload;
@ -906,13 +941,17 @@ static bool IsOutboundDisconnectionCandidate(const CNode& node)
void PeerLogicValidation::InitializeNode(CNode *pnode) {
CAddress addr = pnode->addr;
std::string addrName = pnode->GetAddrName();
NodeId nodeid = pnode->GetId();
{
LOCK(cs_main);
mapNodeState.emplace_hint(mapNodeState.end(), std::piecewise_construct, std::forward_as_tuple(nodeid), std::forward_as_tuple(addr, std::move(addrName), pnode->fInbound, pnode->m_manual_connection));
mapNodeState.emplace_hint(mapNodeState.end(), std::piecewise_construct, std::forward_as_tuple(nodeid), std::forward_as_tuple(addr, pnode->fInbound, pnode->m_manual_connection));
}
if(!pnode->fInbound)
{
PeerRef peer = std::make_shared<Peer>(nodeid);
LOCK(g_peer_mutex);
g_peer_map.emplace_hint(g_peer_map.end(), nodeid, std::move(peer));
}
if (!pnode->fInbound)
PushNodeVersion(*pnode, m_connman, GetTime());
}
@ -933,13 +972,21 @@ void PeerLogicValidation::FinalizeNode(const CNode& node, bool& fUpdateConnectio
NodeId nodeid = node.GetId();
fUpdateConnectionTime = false;
LOCK(cs_main);
int misbehavior{0};
{
PeerRef peer = GetPeerRef(nodeid);
assert(peer != nullptr);
misbehavior = WITH_LOCK(peer->m_misbehavior_mutex, return peer->nMisbehavior);
LOCK(g_peer_mutex);
g_peer_map.erase(nodeid);
}
CNodeState *state = State(nodeid);
assert(state != nullptr);
if (state->fSyncStarted)
nSyncStarted--;
if (state->nMisbehavior == 0 && state->fCurrentlyConnected && !node.m_block_relay_only_peer) {
if (misbehavior == 0 && state->fCurrentlyConnected && !node.m_block_relay_only_peer) {
// Note: we avoid changing visible addrman state for block-relay-only peers
fUpdateConnectionTime = true;
}
@ -967,17 +1014,23 @@ void PeerLogicValidation::FinalizeNode(const CNode& node, bool& fUpdateConnectio
}
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats) {
{
LOCK(cs_main);
CNodeState *state = State(nodeid);
CNodeState* state = State(nodeid);
if (state == nullptr)
return false;
stats.nMisbehavior = state->nMisbehavior;
stats.nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->nHeight : -1;
stats.nCommonHeight = state->pindexLastCommonBlock ? state->pindexLastCommonBlock->nHeight : -1;
for (const QueuedBlock& queue : state->vBlocksInFlight) {
if (queue.pindex)
stats.vHeightInFlight.push_back(queue.pindex->nHeight);
}
}
PeerRef peer = GetPeerRef(nodeid);
if (peer == nullptr) return false;
stats.nMisbehavior = WITH_LOCK(peer->m_misbehavior_mutex, return peer->nMisbehavior);
return true;
}
@ -1127,33 +1180,35 @@ void static ProcessOrphanTx(CConnman& connman, CTxMemPool& mempool, std::set<uin
/**
* Increment peer's misbehavior score. If the new value surpasses banscore (specified on startup or by default), mark node to be discouraged, meaning the peer might be disconnected & added to the discouragement filter.
*/
void Misbehaving(const NodeId pnode, const int howmuch, const std::string& message) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
void Misbehaving(const NodeId pnode, const int howmuch, const std::string& message)
{
assert(howmuch > 0);
CNodeState* const state = State(pnode);
if (state == nullptr) return;
PeerRef peer = GetPeerRef(pnode);
if (peer == nullptr) return;
state->nMisbehavior += howmuch;
LOCK(peer->m_misbehavior_mutex);
peer->nMisbehavior += howmuch;
const int banscore = gArgs.GetArg("-banscore", DEFAULT_BANSCORE_THRESHOLD);
const std::string message_prefixed = message.empty() ? "" : (": " + message);
if (state->nMisbehavior >= banscore && state->nMisbehavior - howmuch < banscore)
if (peer->nMisbehavior >= banscore && peer->nMisbehavior - howmuch < banscore)
{
LogPrint(BCLog::NET, "Misbehaving: peer=%d (%d -> %d) DISCOURAGE THRESHOLD EXCEEDED%s\n", pnode, state->nMisbehavior - howmuch, state->nMisbehavior, message_prefixed);
state->m_should_discourage = true;
LogPrint(BCLog::NET, "Misbehaving: peer=%d (%d -> %d) DISCOURAGE THRESHOLD EXCEEDED%s\n", pnode, peer->nMisbehavior - howmuch, peer->nMisbehavior, message_prefixed);
peer->m_should_discourage = true;
statsClient.inc("misbehavior.banned", 1.0f);
} else {
LogPrint(BCLog::NET, "Misbehaving: peer=%d (%d -> %d)%s\n", pnode, state->nMisbehavior - howmuch, state->nMisbehavior, message_prefixed);
LogPrint(BCLog::NET, "Misbehaving: peer=%d (%d -> %d)%s\n", pnode, peer->nMisbehavior - howmuch, peer->nMisbehavior, message_prefixed);
statsClient.count("misbehavior.amount", howmuch, 1.0);
}
}
bool IsBanned(NodeId pnode)
{
CNodeState *state = State(pnode);
if (state == nullptr)
PeerRef peer = GetPeerRef(pnode);
if (peer == nullptr)
return false;
if (state->m_should_discourage) {
LOCK(peer->m_misbehavior_mutex);
if (peer->m_should_discourage) {
return true;
}
return false;
@ -1178,7 +1233,6 @@ static bool MaybePunishNode(NodeId nodeid, const CValidationState& state, bool v
case ValidationInvalidReason::CONSENSUS:
case ValidationInvalidReason::BLOCK_MUTATED:
if (!via_compact_block) {
LOCK(cs_main);
Misbehaving(nodeid, 100, message);
return true;
}
@ -1202,21 +1256,14 @@ static bool MaybePunishNode(NodeId nodeid, const CValidationState& state, bool v
case ValidationInvalidReason::BLOCK_INVALID_HEADER:
case ValidationInvalidReason::BLOCK_CHECKPOINT:
case ValidationInvalidReason::BLOCK_INVALID_PREV:
{
LOCK(cs_main);
Misbehaving(nodeid, 100, message);
}
return true;
// Conflicting (but not necessarily invalid) data or different policy:
case ValidationInvalidReason::BLOCK_MISSING_PREV:
case ValidationInvalidReason::BLOCK_CHAINLOCK:
case ValidationInvalidReason::TX_BAD_SPECIAL:
case ValidationInvalidReason::TX_CONFLICT_LOCK:
{
// TODO: Handle this much more gracefully (10 DoS points is super arbitrary)
LOCK(cs_main);
Misbehaving(nodeid, 10, message);
}
return true;
case ValidationInvalidReason::RECENT_CONSENSUS_CHANGE:
case ValidationInvalidReason::BLOCK_TIME_FUTURE:
@ -2000,7 +2047,6 @@ inline void static SendBlockTransactions(const CBlock& block, const BlockTransac
BlockTransactions resp(req);
for (size_t i = 0; i < req.indexes.size(); i++) {
if (req.indexes[i] >= block.vtx.size()) {
LOCK(cs_main);
Misbehaving(pfrom.GetId(), 100, "getblocktxn with out-of-bounds tx indices");
return;
}
@ -2572,7 +2618,6 @@ void PeerLogicValidation::ProcessMessage(
(msg_type == NetMsgType::FILTERLOAD ||
msg_type == NetMsgType::FILTERADD))
{
LOCK(cs_main);
Misbehaving(pfrom.GetId(), 100);
return;
}
@ -2581,7 +2626,6 @@ void PeerLogicValidation::ProcessMessage(
// Each connection can only send one version message
if (pfrom.nVersion != 0)
{
LOCK(cs_main);
Misbehaving(pfrom.GetId(), 1, "redundant version message");
return;
}
@ -2670,7 +2714,6 @@ void PeerLogicValidation::ProcessMessage(
if (Params().NetworkIDString() == CBaseChainParams::DEVNET) {
if (cleanSubVer.find(strprintf("devnet.%s", gArgs.GetDevNetName())) == std::string::npos) {
LOCK(cs_main);
LogPrintf("connected to wrong devnet. Reported version is %s, expected devnet name is %s\n", cleanSubVer, gArgs.GetDevNetName());
if (!pfrom.fInbound)
Misbehaving(pfrom.GetId(), 100); // don't try to connect again
@ -2768,7 +2811,6 @@ void PeerLogicValidation::ProcessMessage(
if (pfrom.nVersion == 0) {
// Must have a version message before anything else
LOCK(cs_main);
Misbehaving(pfrom.GetId(), 1, "non-version message before version handshake");
return;
}
@ -2843,7 +2885,6 @@ void PeerLogicValidation::ProcessMessage(
if (!pfrom.fSuccessfullyConnected) {
// Must have a verack message before anything else
LOCK(cs_main);
Misbehaving(pfrom.GetId(), 1, "non-verack message before version handshake");
return;
}
@ -2886,7 +2927,6 @@ void PeerLogicValidation::ProcessMessage(
}
if (vAddr.size() > 1000)
{
LOCK(cs_main);
Misbehaving(pfrom.GetId(), 20, strprintf("%s message size = %u", msg_type, vAddr.size()));
return;
}
@ -2975,7 +3015,6 @@ void PeerLogicValidation::ProcessMessage(
vRecv >> vInv;
if (vInv.size() > MAX_INV_SZ)
{
LOCK(cs_main);
Misbehaving(pfrom.GetId(), 20, strprintf("message inv size() = %u", vInv.size()));
return;
}
@ -3066,7 +3105,6 @@ void PeerLogicValidation::ProcessMessage(
vRecv >> vInv;
if (vInv.size() > MAX_INV_SZ)
{
LOCK(cs_main);
Misbehaving(pfrom.GetId(), 20, strprintf("message getdata size() = %u", vInv.size()));
return;
}
@ -3750,7 +3788,6 @@ void PeerLogicValidation::ProcessMessage(
// Bypass the normal CBlock deserialization, as we don't want to risk deserializing 2000 full blocks.
unsigned int nCount = ReadCompactSize(vRecv);
if (nCount > MAX_HEADERS_RESULTS) {
LOCK(cs_main);
Misbehaving(pfrom.GetId(), 20, strprintf("headers message size = %u", nCount));
return;
}
@ -3952,7 +3989,6 @@ void PeerLogicValidation::ProcessMessage(
if (!filter.IsWithinSizeConstraints())
{
// There is no excuse for sending a too-large filter
LOCK(cs_main);
Misbehaving(pfrom.GetId(), 100, "too-large bloom filter");
}
else if (!pfrom.m_block_relay_only_peer)
@ -3982,7 +4018,6 @@ void PeerLogicValidation::ProcessMessage(
}
}
if (bad) {
LOCK(cs_main);
Misbehaving(pfrom.GetId(), 100, "bad filteradd message");
}
return;
@ -4035,7 +4070,6 @@ void PeerLogicValidation::ProcessMessage(
if (msg_type == NetMsgType::MNLISTDIFF) {
// we have never requested this
LOCK(cs_main);
Misbehaving(pfrom.GetId(), 100, strprintf("received not-requested mnlistdiff. peer=%d", pfrom.GetId()));
return;
}
@ -4059,7 +4093,6 @@ void PeerLogicValidation::ProcessMessage(
if (msg_type == NetMsgType::QUORUMROTATIONINFO) {
// we have never requested this
LOCK(cs_main);
Misbehaving(pfrom.GetId(), 100, strprintf("received not-requested quorumrotationinfo. peer=%d", pfrom.GetId()));
return;
}
@ -4136,15 +4169,17 @@ void PeerLogicValidation::ProcessMessage(
bool PeerLogicValidation::MaybeDiscourageAndDisconnect(CNode& pnode)
{
const NodeId peer_id{pnode.GetId()};
PeerRef peer = GetPeerRef(peer_id);
if (peer == nullptr) return false;
{
LOCK(cs_main);
CNodeState& state = *State(peer_id);
LOCK(peer->m_misbehavior_mutex);
// There's nothing to do if the m_should_discourage flag isn't set
if (!state.m_should_discourage) return false;
if (!peer->m_should_discourage) return false;
state.m_should_discourage = false;
} // cs_main
peer->m_should_discourage = false;
} // peer.m_misbehavior_mutex
if (pnode.HasPermission(PF_NOBAN)) {
// We never disconnect or discourage peers for bad behavior if they have the NOBAN permission flag

View File

@ -104,7 +104,7 @@ bool IsBanned(NodeId nodeid) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
// Upstream moved this into net_processing.cpp (13417), however since we use Misbehaving in a number of dash specific
// files such as mnauth.cpp and governance.cpp it makes sense to keep it in the header
/** Increase a node's misbehavior score. */
void Misbehaving(NodeId nodeid, int howmuch, const std::string& message="") EXCLUSIVE_LOCKS_REQUIRED(cs_main);
void Misbehaving(const NodeId pnode, const int howmuch, const std::string& message="");
void EraseObjectRequest(NodeId nodeId, const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
void RequestObject(NodeId nodeId, const CInv& inv, std::chrono::microseconds current_time, bool fForce=false) EXCLUSIVE_LOCKS_REQUIRED(cs_main);

View File

@ -130,7 +130,6 @@ void CSporkManager::ProcessSpork(const CNode& peer, CConnman& connman, CDataStre
}
if (spork.nTimeSigned > GetAdjustedTime() + 2 * 60 * 60) {
LOCK(cs_main);
LogPrint(BCLog::SPORK, "CSporkManager::ProcessSpork -- ERROR: too far into the future\n");
Misbehaving(peer.GetId(), 100);
return;
@ -139,7 +138,6 @@ void CSporkManager::ProcessSpork(const CNode& peer, CConnman& connman, CDataStre
auto opt_keyIDSigner = spork.GetSignerKeyID();
if (opt_keyIDSigner == std::nullopt || WITH_LOCK(cs, return !setSporkPubKeyIDs.count(*opt_keyIDSigner))) {
LOCK(cs_main);
LogPrint(BCLog::SPORK, "CSporkManager::ProcessSpork -- ERROR: invalid signature\n");
Misbehaving(peer.GetId(), 100);
return;

View File

@ -240,10 +240,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning)
peerLogic->InitializeNode(&dummyNode1);
dummyNode1.nVersion = 1;
dummyNode1.fSuccessfullyConnected = true;
{
LOCK(cs_main);
Misbehaving(dummyNode1.GetId(), 100); // Should get banned
}
{
LOCK(dummyNode1.cs_sendProcessing);
BOOST_CHECK(peerLogic->SendMessages(&dummyNode1));
@ -257,20 +254,14 @@ BOOST_AUTO_TEST_CASE(DoS_banning)
peerLogic->InitializeNode(&dummyNode2);
dummyNode2.nVersion = 1;
dummyNode2.fSuccessfullyConnected = true;
{
LOCK(cs_main);
Misbehaving(dummyNode2.GetId(), 50);
}
{
LOCK(dummyNode2.cs_sendProcessing);
BOOST_CHECK(peerLogic->SendMessages(&dummyNode2));
}
BOOST_CHECK(!banman->IsDiscouraged(addr2)); // 2 not banned yet...
BOOST_CHECK(banman->IsDiscouraged(addr1)); // ... but 1 still should be
{
LOCK(cs_main);
Misbehaving(dummyNode2.GetId(), 50);
}
{
LOCK(dummyNode2.cs_sendProcessing);
BOOST_CHECK(peerLogic->SendMessages(&dummyNode2));
@ -299,7 +290,6 @@ BOOST_AUTO_TEST_CASE(DoS_banscore)
dummyNode1.nVersion = 1;
dummyNode1.fSuccessfullyConnected = true;
{
LOCK(cs_main);
Misbehaving(dummyNode1.GetId(), 100);
}
{
@ -308,7 +298,6 @@ BOOST_AUTO_TEST_CASE(DoS_banscore)
}
BOOST_CHECK(!banman->IsDiscouraged(addr1));
{
LOCK(cs_main);
Misbehaving(dummyNode1.GetId(), 10);
}
{
@ -317,7 +306,6 @@ BOOST_AUTO_TEST_CASE(DoS_banscore)
}
BOOST_CHECK(!banman->IsDiscouraged(addr1));
{
LOCK(cs_main);
Misbehaving(dummyNode1.GetId(), 1);
}
{
@ -350,10 +338,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime)
dummyNode.nVersion = 1;
dummyNode.fSuccessfullyConnected = true;
{
LOCK(cs_main);
Misbehaving(dummyNode.GetId(), 100);
}
{
LOCK(dummyNode.cs_sendProcessing);
BOOST_CHECK(peerLogic->SendMessages(&dummyNode));