Skip to content

Commit 8652560

Browse files
tgflynnUdjinM6
authored andcommitted
V0.12.1.x multiple wd rate check (#1426)
* Modify MasternodeRateCheck to support updating buffers only on failure * Update rate check buffer only when fAddToSeen is true
1 parent d7fbaf9 commit 8652560

File tree

3 files changed

+48
-30
lines changed

3 files changed

+48
-30
lines changed

src/governance.cpp

+39-27
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
}
@@ -229,6 +229,8 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, std::string& strCommand, C
229229
if(fAddToSeen) {
230230
// UPDATE THAT WE'VE SEEN THIS OBJECT
231231
mapSeenGovernanceObjects.insert(std::make_pair(nHash, SEEN_OBJECT_IS_VALID));
232+
// Update the rate buffer
233+
MasternodeRateCheck(govobj, UPDATE_TRUE, true, fRateCheckBypassed);
232234
}
233235

234236
masternodeSync.AddedGovernanceItem();
@@ -814,13 +816,13 @@ void CGovernanceManager::Sync(CNode* pfrom, const uint256& nProp, const CBloomFi
814816
LogPrintf("CGovernanceManager::Sync -- sent %d objects and %d votes to peer=%d\n", nObjCount, nVoteCount, pfrom->id);
815817
}
816818

817-
bool CGovernanceManager::MasternodeRateCheck(const CGovernanceObject& govobj, bool fUpdateLast)
819+
bool CGovernanceManager::MasternodeRateCheck(const CGovernanceObject& govobj, update_mode_enum_t eUpdateLast)
818820
{
819821
bool fRateCheckBypassed = false;
820-
return MasternodeRateCheck(govobj, fUpdateLast, true, fRateCheckBypassed);
822+
return MasternodeRateCheck(govobj, eUpdateLast, true, fRateCheckBypassed);
821823
}
822824

823-
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)
824826
{
825827
LOCK(cs);
826828

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

850852
if(it == mapLastMasternodeObject.end()) {
851-
if(fUpdateLast) {
853+
if(eUpdateLast == UPDATE_TRUE) {
852854
it = mapLastMasternodeObject.insert(txout_m_t::value_type(vin.prevout, last_object_rec(true))).first;
853855
switch(nObjectType) {
854856
case GOVERNANCE_OBJECT_TRIGGER:
@@ -886,44 +888,54 @@ bool CGovernanceManager::MasternodeRateCheck(const CGovernanceObject& govobj, bo
886888
double dMaxRate = 1.1 / nSuperblockCycleSeconds;
887889
double dRate = 0.0;
888890
CRateCheckBuffer buffer;
891+
CRateCheckBuffer* pBuffer = NULL;
889892
switch(nObjectType) {
890893
case GOVERNANCE_OBJECT_TRIGGER:
891894
// Allow 1 trigger per mn per cycle, with a small fudge factor
895+
pBuffer = &it->second.triggerBuffer;
892896
dMaxRate = 2 * 1.1 / double(nSuperblockCycleSeconds);
893-
buffer = it->second.triggerBuffer;
894-
buffer.AddTimestamp(nTimestamp);
895-
dRate = buffer.GetRate();
896-
if(fUpdateLast) {
897-
it->second.triggerBuffer.AddTimestamp(nTimestamp);
898-
}
899897
break;
900898
case GOVERNANCE_OBJECT_WATCHDOG:
899+
pBuffer = &it->second.watchdogBuffer;
901900
dMaxRate = 2 * 1.1 / 3600.;
902-
buffer = it->second.watchdogBuffer;
903-
buffer.AddTimestamp(nTimestamp);
904-
dRate = buffer.GetRate();
905-
if(fUpdateLast) {
906-
it->second.watchdogBuffer.AddTimestamp(nTimestamp);
907-
}
908901
break;
909902
default:
910903
break;
911904
}
912905

913-
if(dRate < dMaxRate) {
914-
if(fUpdateLast) {
915-
it->second.fStatusOK = true;
916-
}
917-
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;
918910
}
919-
else {
920-
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);
921926
it->second.fStatusOK = false;
922927
}
928+
default:
929+
return true;
923930
}
924931

925-
LogPrintf("CGovernanceManager::MasternodeRateCheck -- Rate too high: object hash = %s, masternode vin = %s, object timestamp = %d, rate = %f, max rate = %f\n",
926-
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+
}
927939
return false;
928940
}
929941

src/governance.h

+8-2
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
//
@@ -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/rpcgovernance.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ 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
}

0 commit comments

Comments
 (0)