Skip to content

Commit 7a5943c

Browse files
authored
Merge pull request #1431 from dashpay/v0.12.2.x-merge_upstream
V0.12.2.x merge upstream
2 parents 1a528d9 + b815a7b commit 7a5943c

File tree

8 files changed

+110
-47
lines changed

8 files changed

+110
-47
lines changed

src/governance-object.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,19 @@ bool CGovernanceObject::ProcessVote(CNode* pfrom,
178178
governance.AddInvalidVote(vote);
179179
return false;
180180
}
181+
if(!mnodeman.AddGovernanceVote(vote.GetVinMasternode(), vote.GetParentHash())) {
182+
std::ostringstream ostr;
183+
ostr << "CGovernanceObject::ProcessVote -- Unable to add governance vote "
184+
<< ", MN outpoint = " << vote.GetVinMasternode().prevout.ToStringShort()
185+
<< ", governance object hash = " << GetHash().ToString() << "\n";
186+
LogPrint("gobject", ostr.str().c_str());
187+
exception = CGovernanceException(ostr.str(), GOVERNANCE_EXCEPTION_PERMANENT_ERROR);
188+
return false;
189+
}
181190
voteInstance = vote_instance_t(vote.GetOutcome(), nVoteTimeUpdate, vote.GetTimestamp());
182-
fileVotes.AddVote(vote);
183-
mnodeman.AddGovernanceVote(vote.GetVinMasternode(), vote.GetParentHash());
191+
if(!fileVotes.HasVote(vote.GetHash())) {
192+
fileVotes.AddVote(vote);
193+
}
184194
fDirtyCache = true;
185195
return true;
186196
}

src/governance-votedb.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ void CGovernanceObjectVoteFile::RemoveVotesFromMasternode(const CTxIn& vinMaster
5858
vote_l_it it = listVotes.begin();
5959
while(it != listVotes.end()) {
6060
if(it->GetVinMasternode() == vinMasternode) {
61+
--nMemoryVotes;
6162
mapVoteIndex.erase(it->GetHash());
6263
listVotes.erase(it++);
6364
}
@@ -78,8 +79,18 @@ CGovernanceObjectVoteFile& CGovernanceObjectVoteFile::operator=(const CGovernanc
7879
void CGovernanceObjectVoteFile::RebuildIndex()
7980
{
8081
mapVoteIndex.clear();
81-
for(vote_l_it it = listVotes.begin(); it != listVotes.end(); ++it) {
82+
nMemoryVotes = 0;
83+
vote_l_it it = listVotes.begin();
84+
while(it != listVotes.end()) {
8285
CGovernanceVote& vote = *it;
83-
mapVoteIndex[vote.GetHash()] = it;
86+
uint256 nHash = vote.GetHash();
87+
if(mapVoteIndex.find(nHash) == mapVoteIndex.end()) {
88+
mapVoteIndex[nHash] = it;
89+
++nMemoryVotes;
90+
++it;
91+
}
92+
else {
93+
listVotes.erase(it++);
94+
}
8495
}
8596
}

src/governance.cpp

Lines changed: 53 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, std::string& strCommand, C
186186
}
187187

188188
bool fRateCheckBypassed = false;
189-
if(!MasternodeRateCheck(govobj, true, false, fRateCheckBypassed)) {
189+
if(!MasternodeRateCheck(govobj, UPDATE_FAIL_ONLY, false, fRateCheckBypassed)) {
190190
LogPrintf("MNGOVERNANCEOBJECT -- masternode rate check failed - %s - (current block height %d) \n", strHash, nCachedBlockHeight);
191191
return;
192192
}
@@ -209,7 +209,7 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, std::string& strCommand, C
209209
}
210210

211211
if(fRateCheckBypassed) {
212-
if(!MasternodeRateCheck(govobj, true, true, fRateCheckBypassed)) {
212+
if(!MasternodeRateCheck(govobj, UPDATE_FAIL_ONLY, true, fRateCheckBypassed)) {
213213
LogPrintf("MNGOVERNANCEOBJECT -- masternode rate check failed (after signature verification) - %s - (current block height %d) \n", strHash, nCachedBlockHeight);
214214
return;
215215
}
@@ -219,14 +219,20 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, std::string& strCommand, C
219219

220220
govobj.UpdateSentinelVariables(); //this sets local vars in object
221221

222-
if(AddGovernanceObject(govobj, pfrom))
222+
bool fAddToSeen = true;
223+
if(AddGovernanceObject(govobj, fAddToSeen, pfrom))
223224
{
224225
LogPrintf("MNGOVERNANCEOBJECT -- %s new\n", strHash);
225226
govobj.Relay();
226227
}
227228

228-
// UPDATE THAT WE'VE SEEN THIS OBJECT
229-
mapSeenGovernanceObjects.insert(std::make_pair(nHash, SEEN_OBJECT_IS_VALID));
229+
if(fAddToSeen) {
230+
// UPDATE THAT WE'VE SEEN THIS OBJECT
231+
mapSeenGovernanceObjects.insert(std::make_pair(nHash, SEEN_OBJECT_IS_VALID));
232+
// Update the rate buffer
233+
MasternodeRateCheck(govobj, UPDATE_TRUE, true, fRateCheckBypassed);
234+
}
235+
230236
masternodeSync.AddedGovernanceItem();
231237

232238

@@ -305,13 +311,15 @@ void CGovernanceManager::CheckOrphanVotes(CGovernanceObject& govobj, CGovernance
305311
fRateChecksEnabled = true;
306312
}
307313

308-
bool CGovernanceManager::AddGovernanceObject(CGovernanceObject& govobj, CNode* pfrom)
314+
bool CGovernanceManager::AddGovernanceObject(CGovernanceObject& govobj, bool& fAddToSeen, CNode* pfrom)
309315
{
310316
LOCK2(cs_main, cs);
311317
std::string strError = "";
312318

313319
DBG( cout << "CGovernanceManager::AddGovernanceObject START" << endl; );
314320

321+
fAddToSeen = true;
322+
315323
uint256 nHash = govobj.GetHash();
316324

317325
// MAKE SURE THIS OBJECT IS OK
@@ -341,6 +349,8 @@ bool CGovernanceManager::AddGovernanceObject(CGovernanceObject& govobj, CNode* p
341349
}
342350

343351
if(!UpdateCurrentWatchdog(govobj)) {
352+
// Allow wd's which are not current to be reprocessed
353+
fAddToSeen = false;
344354
if(pfrom && (nHashWatchdogCurrent != uint256())) {
345355
pfrom->PushInventory(CInv(MSG_GOVERNANCE_OBJECT, nHashWatchdogCurrent));
346356
}
@@ -806,13 +816,13 @@ void CGovernanceManager::Sync(CNode* pfrom, const uint256& nProp, const CBloomFi
806816
LogPrintf("CGovernanceManager::Sync -- sent %d objects and %d votes to peer=%d\n", nObjCount, nVoteCount, pfrom->id);
807817
}
808818

809-
bool CGovernanceManager::MasternodeRateCheck(const CGovernanceObject& govobj, bool fUpdateLast)
819+
bool CGovernanceManager::MasternodeRateCheck(const CGovernanceObject& govobj, update_mode_enum_t eUpdateLast)
810820
{
811821
bool fRateCheckBypassed = false;
812-
return MasternodeRateCheck(govobj, fUpdateLast, true, fRateCheckBypassed);
822+
return MasternodeRateCheck(govobj, eUpdateLast, true, fRateCheckBypassed);
813823
}
814824

815-
bool CGovernanceManager::MasternodeRateCheck(const CGovernanceObject& govobj, bool fUpdateLast, bool fForce, bool& fRateCheckBypassed)
825+
bool CGovernanceManager::MasternodeRateCheck(const CGovernanceObject& govobj, update_mode_enum_t eUpdateLast, bool fForce, bool& fRateCheckBypassed)
816826
{
817827
LOCK(cs);
818828

@@ -840,7 +850,7 @@ bool CGovernanceManager::MasternodeRateCheck(const CGovernanceObject& govobj, bo
840850
txout_m_it it = mapLastMasternodeObject.find(vin.prevout);
841851

842852
if(it == mapLastMasternodeObject.end()) {
843-
if(fUpdateLast) {
853+
if(eUpdateLast == UPDATE_TRUE) {
844854
it = mapLastMasternodeObject.insert(txout_m_t::value_type(vin.prevout, last_object_rec(true))).first;
845855
switch(nObjectType) {
846856
case GOVERNANCE_OBJECT_TRIGGER:
@@ -878,44 +888,54 @@ bool CGovernanceManager::MasternodeRateCheck(const CGovernanceObject& govobj, bo
878888
double dMaxRate = 1.1 / nSuperblockCycleSeconds;
879889
double dRate = 0.0;
880890
CRateCheckBuffer buffer;
891+
CRateCheckBuffer* pBuffer = NULL;
881892
switch(nObjectType) {
882893
case GOVERNANCE_OBJECT_TRIGGER:
883894
// Allow 1 trigger per mn per cycle, with a small fudge factor
895+
pBuffer = &it->second.triggerBuffer;
884896
dMaxRate = 2 * 1.1 / double(nSuperblockCycleSeconds);
885-
buffer = it->second.triggerBuffer;
886-
buffer.AddTimestamp(nTimestamp);
887-
dRate = buffer.GetRate();
888-
if(fUpdateLast) {
889-
it->second.triggerBuffer.AddTimestamp(nTimestamp);
890-
}
891897
break;
892898
case GOVERNANCE_OBJECT_WATCHDOG:
899+
pBuffer = &it->second.watchdogBuffer;
893900
dMaxRate = 2 * 1.1 / 3600.;
894-
buffer = it->second.watchdogBuffer;
895-
buffer.AddTimestamp(nTimestamp);
896-
dRate = buffer.GetRate();
897-
if(fUpdateLast) {
898-
it->second.watchdogBuffer.AddTimestamp(nTimestamp);
899-
}
900901
break;
901902
default:
902903
break;
903904
}
904905

905-
if(dRate < dMaxRate) {
906-
if(fUpdateLast) {
907-
it->second.fStatusOK = true;
908-
}
909-
return true;
906+
if(!pBuffer) {
907+
LogPrintf("CGovernanceManager::MasternodeRateCheck -- Internal Error returning false, NULL ptr found for object %s masternode vin = %s, timestamp = %d, current time = %d\n",
908+
strHash, vin.prevout.ToStringShort(), nTimestamp, nNow);
909+
return false;
910910
}
911-
else {
912-
if(fUpdateLast) {
911+
912+
buffer = *pBuffer;
913+
buffer.AddTimestamp(nTimestamp);
914+
dRate = buffer.GetRate();
915+
916+
bool fRateOK = ( dRate < dMaxRate );
917+
918+
switch(eUpdateLast) {
919+
case UPDATE_TRUE:
920+
pBuffer->AddTimestamp(nTimestamp);
921+
it->second.fStatusOK = fRateOK;
922+
break;
923+
case UPDATE_FAIL_ONLY:
924+
if(!fRateOK) {
925+
pBuffer->AddTimestamp(nTimestamp);
913926
it->second.fStatusOK = false;
914927
}
928+
default:
929+
return true;
915930
}
916931

917-
LogPrintf("CGovernanceManager::MasternodeRateCheck -- Rate too high: object hash = %s, masternode vin = %s, object timestamp = %d, rate = %f, max rate = %f\n",
918-
strHash, vin.prevout.ToStringShort(), nTimestamp, dRate, dMaxRate);
932+
if(fRateOK) {
933+
return true;
934+
}
935+
else {
936+
LogPrintf("CGovernanceManager::MasternodeRateCheck -- Rate too high: object hash = %s, masternode vin = %s, object timestamp = %d, rate = %f, max rate = %f\n",
937+
strHash, vin.prevout.ToStringShort(), nTimestamp, dRate, dMaxRate);
938+
}
919939
return false;
920940
}
921941

@@ -1007,7 +1027,8 @@ void CGovernanceManager::CheckMasternodeOrphanObjects()
10071027
continue;
10081028
}
10091029

1010-
if(AddGovernanceObject(govobj)) {
1030+
bool fAddToSeen = true;
1031+
if(AddGovernanceObject(govobj, fAddToSeen)) {
10111032
LogPrintf("CGovernanceManager::CheckMasternodeOrphanObjects -- %s new\n", govobj.GetHash().ToString());
10121033
govobj.Relay();
10131034
mapMasternodeOrphanObjects.erase(it++);

src/governance.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,12 @@ class CRateCheckBuffer {
134134
}
135135
};
136136

137+
enum update_mode_enum_t {
138+
UPDATE_FALSE,
139+
UPDATE_TRUE,
140+
UPDATE_FAIL_ONLY
141+
};
142+
137143
//
138144
// Governance Manager : Contains all proposals for the budget
139145
//
@@ -288,7 +294,7 @@ class CGovernanceManager
288294
std::vector<CGovernanceObject*> GetAllNewerThan(int64_t nMoreThanTime);
289295

290296
bool IsBudgetPaymentBlock(int nBlockHeight);
291-
bool AddGovernanceObject(CGovernanceObject& govobj, CNode* pfrom = NULL);
297+
bool AddGovernanceObject(CGovernanceObject& govobj, bool& fAddToSeen, CNode* pfrom = NULL);
292298

293299
std::string GetRequiredPaymentsString(int nBlockHeight);
294300

@@ -362,9 +368,9 @@ class CGovernanceManager
362368

363369
void AddSeenVote(uint256 nHash, int status);
364370

365-
bool MasternodeRateCheck(const CGovernanceObject& govobj, bool fUpdateLast = false);
371+
bool MasternodeRateCheck(const CGovernanceObject& govobj, update_mode_enum_t eUpdateLast = UPDATE_FALSE);
366372

367-
bool MasternodeRateCheck(const CGovernanceObject& govobj, bool fUpdateLast, bool fForce, bool& fRateCheckBypassed);
373+
bool MasternodeRateCheck(const CGovernanceObject& govobj, update_mode_enum_t eUpdateLast, bool fForce, bool& fRateCheckBypassed);
368374

369375
bool ProcessVoteAndRelay(const CGovernanceVote& vote, CGovernanceException& exception) {
370376
bool fOK = ProcessVote(NULL, vote, exception);

src/masternode-payments.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,12 @@ bool CMasternodePaymentVote::IsValid(CNode* pnode, int nValidationHeight, std::s
687687

688688
int nRank = mnodeman.GetMasternodeRank(vinMasternode, nBlockHeight - 101, nMinRequiredProtocol, false);
689689

690+
if(nRank == -1) {
691+
LogPrint("mnpayments", "CMasternodePaymentVote::IsValid -- Can't calculate rank for masternode %s\n",
692+
vinMasternode.prevout.ToStringShort());
693+
return false;
694+
}
695+
690696
if(nRank > MNPAYMENTS_SIGNATURES_TOTAL) {
691697
// It's common to have masternodes mistakenly think they are in the top 10
692698
// We don't want to print all of these messages in normal mode, debug mode should print though

src/masternodeman.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,9 +1293,16 @@ void CMasternodeMan::ProcessVerifyBroadcast(CNode* pnode, const CMasternodeVerif
12931293
}
12941294

12951295
int nRank = GetMasternodeRank(mnv.vin2, mnv.nBlockHeight, MIN_POSE_PROTO_VERSION);
1296-
if(nRank < MAX_POSE_RANK) {
1297-
LogPrint("masternode", "MasternodeMan::ProcessVerifyBroadcast -- Mastrernode is not in top %d, current rank %d, peer=%d\n",
1298-
(int)MAX_POSE_RANK, nRank, pnode->id);
1296+
1297+
if (nRank == -1) {
1298+
LogPrint("masternode", "CMasternodeMan::ProcessVerifyBroadcast -- Can't calculate rank for masternode %s\n",
1299+
mnv.vin2.prevout.ToStringShort());
1300+
return;
1301+
}
1302+
1303+
if(nRank > MAX_POSE_RANK) {
1304+
LogPrint("masternode", "CMasternodeMan::ProcessVerifyBroadcast -- Mastrernode %s is not in top %d, current rank %d, peer=%d\n",
1305+
mnv.vin2.prevout.ToStringShort(), (int)MAX_POSE_RANK, nRank, pnode->id);
12991306
return;
13001307
}
13011308

@@ -1548,14 +1555,15 @@ bool CMasternodeMan::IsWatchdogActive()
15481555
return (GetTime() - nLastWatchdogVoteTime) <= MASTERNODE_WATCHDOG_MAX_SECONDS;
15491556
}
15501557

1551-
void CMasternodeMan::AddGovernanceVote(const CTxIn& vin, uint256 nGovernanceObjectHash)
1558+
bool CMasternodeMan::AddGovernanceVote(const CTxIn& vin, uint256 nGovernanceObjectHash)
15521559
{
15531560
LOCK(cs);
15541561
CMasternode* pMN = Find(vin);
15551562
if(!pMN) {
1556-
return;
1563+
return false;
15571564
}
15581565
pMN->AddGovernanceVote(nGovernanceObjectHash);
1566+
return true;
15591567
}
15601568

15611569
void CMasternodeMan::RemoveGovernanceObject(uint256 nGovernanceObjectHash)

src/masternodeman.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ class CMasternodeMan
341341

342342
bool IsWatchdogActive();
343343
void UpdateWatchdogVoteTime(const CTxIn& vin);
344-
void AddGovernanceVote(const CTxIn& vin, uint256 nGovernanceObjectHash);
344+
bool AddGovernanceVote(const CTxIn& vin, uint256 nGovernanceObjectHash);
345345
void RemoveGovernanceObject(uint256 nGovernanceObjectHash);
346346

347347
void CheckMasternode(const CTxIn& vin, bool fForce = false);

src/rpcgovernance.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,14 +214,15 @@ UniValue gobject(const UniValue& params, bool fHelp)
214214
throw JSONRPCError(RPC_INVALID_PARAMETER, "Object creation rate limit exceeded");
215215
}
216216
// This check should always pass, update buffer
217-
if(!governance.MasternodeRateCheck(govobj, true)) {
217+
if(!governance.MasternodeRateCheck(govobj, UPDATE_TRUE)) {
218218
LogPrintf("gobject(submit) -- Object submission rejected because of rate check failure (buffer updated) - hash = %s\n", strHash);
219219
throw JSONRPCError(RPC_INVALID_PARAMETER, "Object creation rate limit exceeded");
220220
}
221221
governance.AddSeenGovernanceObject(govobj.GetHash(), SEEN_OBJECT_IS_VALID);
222222
govobj.Relay();
223223
LogPrintf("gobject(submit) -- Adding locally created governance object - %s\n", strHash);
224-
governance.AddGovernanceObject(govobj);
224+
bool fAddToSeen = true;
225+
governance.AddGovernanceObject(govobj, fAddToSeen);
225226

226227
return govobj.GetHash().ToString();
227228
}

0 commit comments

Comments
 (0)