diff --git a/src/masternode/meta.cpp b/src/masternode/meta.cpp index 9b0e26bc77..ca3a6a37ef 100644 --- a/src/masternode/meta.cpp +++ b/src/masternode/meta.cpp @@ -8,7 +8,7 @@ CMasternodeMetaMan mmetaman; -const std::string CMasternodeMetaMan::SERIALIZATION_VERSION_STRING = "CMasternodeMetaMan-Version-2"; +const std::string CMasternodeMetaMan::SERIALIZATION_VERSION_STRING = "CMasternodeMetaMan-Version-3"; UniValue CMasternodeMetaInfo::ToJson() const { @@ -18,6 +18,7 @@ UniValue CMasternodeMetaInfo::ToJson() const ret.pushKV("lastDSQ", nLastDsq); ret.pushKV("mixingTxCount", nMixingTxCount); + ret.pushKV("outboundAttemptCount", outboundAttemptCount); ret.pushKV("lastOutboundAttempt", lastOutboundAttempt); ret.pushKV("lastOutboundAttemptElapsed", now - lastOutboundAttempt); ret.pushKV("lastOutboundSuccess", lastOutboundSuccess); diff --git a/src/masternode/meta.h b/src/masternode/meta.h index 1a93b09d93..f41e695f5a 100644 --- a/src/masternode/meta.h +++ b/src/masternode/meta.h @@ -16,6 +16,7 @@ class CConnman; static constexpr int MASTERNODE_MAX_MIXING_TXES{5}; +static constexpr int MASTERNODE_MAX_FAILED_OUTBOUND_ATTEMPTS{5}; // Holds extra (non-deterministic) information about masternodes // This is mostly local information, e.g. about mixing and governance @@ -35,6 +36,7 @@ private: // KEEP TRACK OF GOVERNANCE ITEMS EACH MASTERNODE HAS VOTE UPON FOR RECALCULATION std::map mapGovernanceObjectsVotedOn GUARDED_BY(cs); + std::atomic outboundAttemptCount{0}; std::atomic lastOutboundAttempt{0}; std::atomic lastOutboundSuccess{0}; @@ -59,6 +61,7 @@ public: obj.nLastDsq, obj.nMixingTxCount, obj.mapGovernanceObjectsVotedOn, + obj.outboundAttemptCount, obj.lastOutboundAttempt, obj.lastOutboundSuccess ); @@ -78,9 +81,10 @@ public: void RemoveGovernanceObject(const uint256& nGovernanceObjectHash); - void SetLastOutboundAttempt(int64_t t) { lastOutboundAttempt = t; } + bool OutboundFailedTooManyTimes() const { return outboundAttemptCount > MASTERNODE_MAX_FAILED_OUTBOUND_ATTEMPTS; } + void SetLastOutboundAttempt(int64_t t) { lastOutboundAttempt = t; ++outboundAttemptCount; } int64_t GetLastOutboundAttempt() const { return lastOutboundAttempt; } - void SetLastOutboundSuccess(int64_t t) { lastOutboundSuccess = t; } + void SetLastOutboundSuccess(int64_t t) { lastOutboundSuccess = t; outboundAttemptCount = 0; } int64_t GetLastOutboundSuccess() const { return lastOutboundSuccess; } }; using CMasternodeMetaInfoPtr = std::shared_ptr; diff --git a/src/net.cpp b/src/net.cpp index 26210f2c82..adb8dc3ebd 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2476,8 +2476,11 @@ void CConnman::ThreadOpenMasternodeConnections() }); if (!connected) { LogPrint(BCLog::NET_NETCONN, "CConnman::%s -- connection failed for masternode %s, service=%s\n", __func__, connectToDmn->proTxHash.ToString(), connectToDmn->pdmnState->addr.ToString(false)); - // reset last outbound success - mmetaman.GetMetaInfo(connectToDmn->proTxHash)->SetLastOutboundSuccess(0); + // Will take a few consequent failed attempts to PoSe-punish a MN. + if (mmetaman.GetMetaInfo(connectToDmn->proTxHash)->OutboundFailedTooManyTimes()) { + LogPrint(BCLog::NET_NETCONN, "CConnman::%s -- failed to connect to masternode %s too many times, resetting outbound success time\n", __func__, connectToDmn->proTxHash.ToString()); + mmetaman.GetMetaInfo(connectToDmn->proTxHash)->SetLastOutboundSuccess(0); + } } } }