From afc74707f889722cf0f7b515cd10d40e97cfd3ce Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Mon, 31 Oct 2016 00:56:47 +0400 Subject: [PATCH] PoSe changes: (#1105) * PoSe changes: - use helpers to alter nPoSeBanScore within predefined range only - use nPoSeBanHeight instead of timeout of inactivity to ban masternodes till some block in the future (currently should block for the whole payment cycle) - add log output on pose score increase in CheckSameAddr --- src/darksend.cpp | 4 ++-- src/masternode.cpp | 35 ++++++++++++++++++++++------------- src/masternode.h | 7 ++++++- src/masternodeman.cpp | 13 +++++++------ 4 files changed, 37 insertions(+), 22 deletions(-) diff --git a/src/darksend.cpp b/src/darksend.cpp index 183a96bfa..76de567b1 100644 --- a/src/darksend.cpp +++ b/src/darksend.cpp @@ -1597,7 +1597,7 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun) LogPrintf("CDarksendPool::DoAutomaticDenominating -- can't connect, addr=%s\n", pmn->addr.ToString()); strAutoDenomResult = _("Error connecting to Masternode."); dsq.nTime = 0; //remove node - pmn->nPoSeBanScore++; + pmn->IncreasePoSeBanScore(); continue; } } @@ -1650,7 +1650,7 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun) } else { LogPrintf("CDarksendPool::DoAutomaticDenominating -- can't connect, addr=%s\n", pmn->addr.ToString()); nTries++; - pmn->nPoSeBanScore++; + pmn->IncreasePoSeBanScore(); continue; } } diff --git a/src/masternode.cpp b/src/masternode.cpp index 1ebec626d..e6ac5bac6 100644 --- a/src/masternode.cpp +++ b/src/masternode.cpp @@ -33,6 +33,7 @@ CMasternode::CMasternode() : nBlockLastPaid(0), nProtocolVersion(PROTOCOL_VERSION), nPoSeBanScore(0), + nPoSeBanHeight(0), fAllowMixingTx(true), fUnitTest(false) {} @@ -54,6 +55,7 @@ CMasternode::CMasternode(CService addrNew, CTxIn vinNew, CPubKey pubKeyCollatera nBlockLastPaid(0), nProtocolVersion(nProtocolVersionIn), nPoSeBanScore(0), + nPoSeBanHeight(0), fAllowMixingTx(true), fUnitTest(false) {} @@ -75,6 +77,7 @@ CMasternode::CMasternode(const CMasternode& other) : nBlockLastPaid(other.nBlockLastPaid), nProtocolVersion(other.nProtocolVersion), nPoSeBanScore(other.nPoSeBanScore), + nPoSeBanHeight(other.nPoSeBanHeight), fAllowMixingTx(other.fAllowMixingTx), fUnitTest(other.fUnitTest) {} @@ -96,6 +99,7 @@ CMasternode::CMasternode(const CMasternodeBroadcast& mnb) : nBlockLastPaid(0), nProtocolVersion(mnb.nProtocolVersion), nPoSeBanScore(0), + nPoSeBanHeight(0), fAllowMixingTx(true), fUnitTest(false) {} @@ -113,6 +117,7 @@ bool CMasternode::UpdateFromNewBroadcast(CMasternodeBroadcast& mnb) nProtocolVersion = mnb.nProtocolVersion; addr = mnb.addr; nPoSeBanScore = 0; + nPoSeBanHeight = 0; nTimeLastChecked = 0; nTimeLastWatchdogVote = mnb.sigTime; int nDos = 0; @@ -173,6 +178,7 @@ void CMasternode::Check(bool fForce) if(!fForce && (GetTime() - nTimeLastChecked < MASTERNODE_CHECK_SECONDS)) return; nTimeLastChecked = GetTime(); + int nHeight = 0; if(!fUnitTest) { TRY_LOCK(cs_main, lockMain); if(!lockMain) return; @@ -185,31 +191,34 @@ void CMasternode::Check(bool fForce) LogPrint("masternode", "CMasternode::Check -- Failed to find Masternode UTXO, masternode=%s\n", vin.prevout.ToStringShort()); return; } - } - // masternode doesn't meet payment protocol requirements ... - bool fRemove = nProtocolVersion < mnpayments.GetMinMasternodePaymentsProto() || - // or it's our own node and we just updated it to the new protocol but we are still waiting for activation ... - (pubKeyMasternode == activeMasternode.pubKeyMasternode && nProtocolVersion < PROTOCOL_VERSION); + nHeight = chainActive.Height(); + } // keep old masternodes on start, give them a chance to receive an updated ping without removal/expiry if(!masternodeSync.IsMasternodeListSynced()) nTimeStart = GetTime(); bool fWaitForPing = (GetTime() - nTimeStart < MASTERNODE_MIN_MNP_SECONDS); if(nActiveState == MASTERNODE_POSE_BAN) { - if(IsPingedWithin(MASTERNODE_POSE_BAN_SECONDS)) { - // Still alive? Good luck with that. - return; - } else { - // It's finally dead, good... - // or did we just start our node and it's too early to decide? - fRemove = !fWaitForPing; - } + if(nHeight < nPoSeBanHeight) return; // too early? + // Otherwise give it a chance to proceed further to do all the usual checks and to change its state. + // Masternode still will be on the edge and can be banned back easily if it keeps ignoring mnverify + // or connect attempts. Will require few mnverify messages to strengthen its position in mn list. + LogPrintf("CMasternode::Check -- Masternode %s is unbanned and back in list now\n", vin.prevout.ToStringShort()); + DecreasePoSeBanScore(); } else if(nPoSeBanScore >= MASTERNODE_POSE_BAN_MAX_SCORE) { nActiveState = MASTERNODE_POSE_BAN; + // ban for the whole payment cycle + nPoSeBanHeight = nHeight + mnodeman.size(); + LogPrintf("CMasternode::Check -- Masternode %s is banned till block %d now\n", vin.prevout.ToStringShort(), nPoSeBanHeight); return; } + // masternode doesn't meet payment protocol requirements ... + bool fRemove = nProtocolVersion < mnpayments.GetMinMasternodePaymentsProto() || + // or it's our own node and we just updated it to the new protocol but we are still waiting for activation ... + (pubKeyMasternode == activeMasternode.pubKeyMasternode && nProtocolVersion < PROTOCOL_VERSION); + if(fRemove) { // it should be removed from the list nActiveState = MASTERNODE_REMOVE; diff --git a/src/masternode.h b/src/masternode.h index 9f53c167f..7762ac5a9 100644 --- a/src/masternode.h +++ b/src/masternode.h @@ -21,7 +21,6 @@ static const int MASTERNODE_REMOVAL_SECONDS = 75 * 60; static const int MASTERNODE_CHECK_SECONDS = 5; static const int MASTERNODE_WATCHDOG_MAX_SECONDS = 2 * 60 * 60; -static const int MASTERNODE_POSE_BAN_SECONDS = 24 * 60 * 60; static const int MASTERNODE_POSE_BAN_MAX_SCORE = 5; // // The Masternode Ping Class : Contains a different serialize method for sending pings from masternodes throughout the network @@ -165,6 +164,7 @@ public: int nBlockLastPaid; int nProtocolVersion; int nPoSeBanScore; + int nPoSeBanHeight; bool fAllowMixingTx; bool fUnitTest; @@ -197,6 +197,7 @@ public: READWRITE(nBlockLastPaid); READWRITE(nProtocolVersion); READWRITE(nPoSeBanScore); + READWRITE(nPoSeBanHeight); READWRITE(fAllowMixingTx); READWRITE(fUnitTest); READWRITE(mapGovernanceObjectsVotedOn); @@ -225,6 +226,7 @@ public: swap(first.nBlockLastPaid, second.nBlockLastPaid); swap(first.nProtocolVersion, second.nProtocolVersion); swap(first.nPoSeBanScore, second.nPoSeBanScore); + swap(first.nPoSeBanHeight, second.nPoSeBanHeight); swap(first.fAllowMixingTx, second.fAllowMixingTx); swap(first.fUnitTest, second.fUnitTest); swap(first.mapGovernanceObjectsVotedOn, second.mapGovernanceObjectsVotedOn); @@ -258,6 +260,9 @@ public: bool IsValidNetAddr(); + void IncreasePoSeBanScore() { if(nPoSeBanScore < MASTERNODE_POSE_BAN_MAX_SCORE) nPoSeBanScore++; } + void DecreasePoSeBanScore() { if(nPoSeBanScore > -MASTERNODE_POSE_BAN_MAX_SCORE) nPoSeBanScore--; } + masternode_info_t GetInfo(); static std::string StateToString(int nStateIn); diff --git a/src/masternodeman.cpp b/src/masternodeman.cpp index 4d840dedd..3d1fdd425 100644 --- a/src/masternodeman.cpp +++ b/src/masternodeman.cpp @@ -862,7 +862,8 @@ void CMasternodeMan::CheckSameAddr() // ban duplicates BOOST_FOREACH(CMasternode* pmn, vBan) { - pmn->nPoSeBanScore++; + LogPrintf("CMasternodeMan::CheckSameAddr -- increasing PoSe ban score for masternode %s\n", pmn->vin.prevout.ToStringShort()); + pmn->IncreasePoSeBanScore(); } } @@ -892,7 +893,7 @@ bool CMasternodeMan::SendVerifyRequest(const CAddress& addr, const std::vectornPoSeBanScore++; + pmn->IncreasePoSeBanScore(); } return false; } @@ -992,7 +993,7 @@ void CMasternodeMan::ProcessVerifyReply(CNode* pnode, CMasternodeVerification& m // found it! prealMasternode = &(*it); if(!it->IsPoSeVerified()) { - it->nPoSeBanScore--; + it->DecreasePoSeBanScore(); } netfulfilledman.AddFulfilledRequest(pnode->addr, strprintf("%s", NetMsgType::MNVERIFY)+"-done"); @@ -1038,7 +1039,7 @@ void CMasternodeMan::ProcessVerifyReply(CNode* pnode, CMasternodeVerification& m prealMasternode->vin.prevout.ToStringShort(), pnode->addr.ToString()); // increase ban score for everyone else BOOST_FOREACH(CMasternode* pmn, vpMasternodesToBan) { - pmn->nPoSeBanScore++; + pmn->IncreasePoSeBanScore(); LogPrint("masternode", "CMasternodeMan::ProcessVerifyBroadcast -- increased PoSe ban score for %s addr %s, new score %d\n", prealMasternode->vin.prevout.ToStringShort(), pnode->addr.ToString(), pmn->nPoSeBanScore); } @@ -1122,7 +1123,7 @@ void CMasternodeMan::ProcessVerifyBroadcast(CNode* pnode, const CMasternodeVerif } if(!pmn1->IsPoSeVerified()) { - pmn1->nPoSeBanScore--; + pmn1->DecreasePoSeBanScore(); } mnv.Relay(); @@ -1133,7 +1134,7 @@ void CMasternodeMan::ProcessVerifyBroadcast(CNode* pnode, const CMasternodeVerif int nCount = 0; BOOST_FOREACH(CMasternode& mn, vMasternodes) { if(mn.addr != mnv.addr || mn.vin.prevout == mnv.vin1.prevout) continue; - mn.nPoSeBanScore++; + mn.IncreasePoSeBanScore(); nCount++; LogPrint("masternode", "CMasternodeMan::ProcessVerifyBroadcast -- increased PoSe ban score for %s addr %s, new score %d\n", mn.vin.prevout.ToStringShort(), mn.addr.ToString(), mn.nPoSeBanScore);