mirror of
https://github.com/dashpay/dash.git
synced 2024-12-24 19:42:46 +01:00
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
This commit is contained in:
parent
d7fbaf907f
commit
86525601d5
@ -186,7 +186,7 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, std::string& strCommand, C
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool fRateCheckBypassed = false;
|
bool fRateCheckBypassed = false;
|
||||||
if(!MasternodeRateCheck(govobj, true, false, fRateCheckBypassed)) {
|
if(!MasternodeRateCheck(govobj, UPDATE_FAIL_ONLY, false, fRateCheckBypassed)) {
|
||||||
LogPrintf("MNGOVERNANCEOBJECT -- masternode rate check failed - %s - (current block height %d) \n", strHash, nCachedBlockHeight);
|
LogPrintf("MNGOVERNANCEOBJECT -- masternode rate check failed - %s - (current block height %d) \n", strHash, nCachedBlockHeight);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -209,7 +209,7 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, std::string& strCommand, C
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(fRateCheckBypassed) {
|
if(fRateCheckBypassed) {
|
||||||
if(!MasternodeRateCheck(govobj, true, true, fRateCheckBypassed)) {
|
if(!MasternodeRateCheck(govobj, UPDATE_FAIL_ONLY, true, fRateCheckBypassed)) {
|
||||||
LogPrintf("MNGOVERNANCEOBJECT -- masternode rate check failed (after signature verification) - %s - (current block height %d) \n", strHash, nCachedBlockHeight);
|
LogPrintf("MNGOVERNANCEOBJECT -- masternode rate check failed (after signature verification) - %s - (current block height %d) \n", strHash, nCachedBlockHeight);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -229,6 +229,8 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, std::string& strCommand, C
|
|||||||
if(fAddToSeen) {
|
if(fAddToSeen) {
|
||||||
// UPDATE THAT WE'VE SEEN THIS OBJECT
|
// UPDATE THAT WE'VE SEEN THIS OBJECT
|
||||||
mapSeenGovernanceObjects.insert(std::make_pair(nHash, SEEN_OBJECT_IS_VALID));
|
mapSeenGovernanceObjects.insert(std::make_pair(nHash, SEEN_OBJECT_IS_VALID));
|
||||||
|
// Update the rate buffer
|
||||||
|
MasternodeRateCheck(govobj, UPDATE_TRUE, true, fRateCheckBypassed);
|
||||||
}
|
}
|
||||||
|
|
||||||
masternodeSync.AddedGovernanceItem();
|
masternodeSync.AddedGovernanceItem();
|
||||||
@ -814,13 +816,13 @@ void CGovernanceManager::Sync(CNode* pfrom, const uint256& nProp, const CBloomFi
|
|||||||
LogPrintf("CGovernanceManager::Sync -- sent %d objects and %d votes to peer=%d\n", nObjCount, nVoteCount, pfrom->id);
|
LogPrintf("CGovernanceManager::Sync -- sent %d objects and %d votes to peer=%d\n", nObjCount, nVoteCount, pfrom->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CGovernanceManager::MasternodeRateCheck(const CGovernanceObject& govobj, bool fUpdateLast)
|
bool CGovernanceManager::MasternodeRateCheck(const CGovernanceObject& govobj, update_mode_enum_t eUpdateLast)
|
||||||
{
|
{
|
||||||
bool fRateCheckBypassed = false;
|
bool fRateCheckBypassed = false;
|
||||||
return MasternodeRateCheck(govobj, fUpdateLast, true, fRateCheckBypassed);
|
return MasternodeRateCheck(govobj, eUpdateLast, true, fRateCheckBypassed);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CGovernanceManager::MasternodeRateCheck(const CGovernanceObject& govobj, bool fUpdateLast, bool fForce, bool& fRateCheckBypassed)
|
bool CGovernanceManager::MasternodeRateCheck(const CGovernanceObject& govobj, update_mode_enum_t eUpdateLast, bool fForce, bool& fRateCheckBypassed)
|
||||||
{
|
{
|
||||||
LOCK(cs);
|
LOCK(cs);
|
||||||
|
|
||||||
@ -848,7 +850,7 @@ bool CGovernanceManager::MasternodeRateCheck(const CGovernanceObject& govobj, bo
|
|||||||
txout_m_it it = mapLastMasternodeObject.find(vin.prevout);
|
txout_m_it it = mapLastMasternodeObject.find(vin.prevout);
|
||||||
|
|
||||||
if(it == mapLastMasternodeObject.end()) {
|
if(it == mapLastMasternodeObject.end()) {
|
||||||
if(fUpdateLast) {
|
if(eUpdateLast == UPDATE_TRUE) {
|
||||||
it = mapLastMasternodeObject.insert(txout_m_t::value_type(vin.prevout, last_object_rec(true))).first;
|
it = mapLastMasternodeObject.insert(txout_m_t::value_type(vin.prevout, last_object_rec(true))).first;
|
||||||
switch(nObjectType) {
|
switch(nObjectType) {
|
||||||
case GOVERNANCE_OBJECT_TRIGGER:
|
case GOVERNANCE_OBJECT_TRIGGER:
|
||||||
@ -886,44 +888,54 @@ bool CGovernanceManager::MasternodeRateCheck(const CGovernanceObject& govobj, bo
|
|||||||
double dMaxRate = 1.1 / nSuperblockCycleSeconds;
|
double dMaxRate = 1.1 / nSuperblockCycleSeconds;
|
||||||
double dRate = 0.0;
|
double dRate = 0.0;
|
||||||
CRateCheckBuffer buffer;
|
CRateCheckBuffer buffer;
|
||||||
|
CRateCheckBuffer* pBuffer = NULL;
|
||||||
switch(nObjectType) {
|
switch(nObjectType) {
|
||||||
case GOVERNANCE_OBJECT_TRIGGER:
|
case GOVERNANCE_OBJECT_TRIGGER:
|
||||||
// Allow 1 trigger per mn per cycle, with a small fudge factor
|
// Allow 1 trigger per mn per cycle, with a small fudge factor
|
||||||
|
pBuffer = &it->second.triggerBuffer;
|
||||||
dMaxRate = 2 * 1.1 / double(nSuperblockCycleSeconds);
|
dMaxRate = 2 * 1.1 / double(nSuperblockCycleSeconds);
|
||||||
buffer = it->second.triggerBuffer;
|
|
||||||
buffer.AddTimestamp(nTimestamp);
|
|
||||||
dRate = buffer.GetRate();
|
|
||||||
if(fUpdateLast) {
|
|
||||||
it->second.triggerBuffer.AddTimestamp(nTimestamp);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case GOVERNANCE_OBJECT_WATCHDOG:
|
case GOVERNANCE_OBJECT_WATCHDOG:
|
||||||
|
pBuffer = &it->second.watchdogBuffer;
|
||||||
dMaxRate = 2 * 1.1 / 3600.;
|
dMaxRate = 2 * 1.1 / 3600.;
|
||||||
buffer = it->second.watchdogBuffer;
|
|
||||||
buffer.AddTimestamp(nTimestamp);
|
|
||||||
dRate = buffer.GetRate();
|
|
||||||
if(fUpdateLast) {
|
|
||||||
it->second.watchdogBuffer.AddTimestamp(nTimestamp);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dRate < dMaxRate) {
|
if(!pBuffer) {
|
||||||
if(fUpdateLast) {
|
LogPrintf("CGovernanceManager::MasternodeRateCheck -- Internal Error returning false, NULL ptr found for object %s masternode vin = %s, timestamp = %d, current time = %d\n",
|
||||||
it->second.fStatusOK = true;
|
strHash, vin.prevout.ToStringShort(), nTimestamp, nNow);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buffer = *pBuffer;
|
||||||
|
buffer.AddTimestamp(nTimestamp);
|
||||||
|
dRate = buffer.GetRate();
|
||||||
|
|
||||||
|
bool fRateOK = ( dRate < dMaxRate );
|
||||||
|
|
||||||
|
switch(eUpdateLast) {
|
||||||
|
case UPDATE_TRUE:
|
||||||
|
pBuffer->AddTimestamp(nTimestamp);
|
||||||
|
it->second.fStatusOK = fRateOK;
|
||||||
|
break;
|
||||||
|
case UPDATE_FAIL_ONLY:
|
||||||
|
if(!fRateOK) {
|
||||||
|
pBuffer->AddTimestamp(nTimestamp);
|
||||||
|
it->second.fStatusOK = false;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fRateOK) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(fUpdateLast) {
|
|
||||||
it->second.fStatusOK = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LogPrintf("CGovernanceManager::MasternodeRateCheck -- Rate too high: object hash = %s, masternode vin = %s, object timestamp = %d, rate = %f, max rate = %f\n",
|
LogPrintf("CGovernanceManager::MasternodeRateCheck -- Rate too high: object hash = %s, masternode vin = %s, object timestamp = %d, rate = %f, max rate = %f\n",
|
||||||
strHash, vin.prevout.ToStringShort(), nTimestamp, dRate, dMaxRate);
|
strHash, vin.prevout.ToStringShort(), nTimestamp, dRate, dMaxRate);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,6 +134,12 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum update_mode_enum_t {
|
||||||
|
UPDATE_FALSE,
|
||||||
|
UPDATE_TRUE,
|
||||||
|
UPDATE_FAIL_ONLY
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// Governance Manager : Contains all proposals for the budget
|
// Governance Manager : Contains all proposals for the budget
|
||||||
//
|
//
|
||||||
@ -362,9 +368,9 @@ public:
|
|||||||
|
|
||||||
void AddSeenVote(uint256 nHash, int status);
|
void AddSeenVote(uint256 nHash, int status);
|
||||||
|
|
||||||
bool MasternodeRateCheck(const CGovernanceObject& govobj, bool fUpdateLast = false);
|
bool MasternodeRateCheck(const CGovernanceObject& govobj, update_mode_enum_t eUpdateLast = UPDATE_FALSE);
|
||||||
|
|
||||||
bool MasternodeRateCheck(const CGovernanceObject& govobj, bool fUpdateLast, bool fForce, bool& fRateCheckBypassed);
|
bool MasternodeRateCheck(const CGovernanceObject& govobj, update_mode_enum_t eUpdateLast, bool fForce, bool& fRateCheckBypassed);
|
||||||
|
|
||||||
bool ProcessVoteAndRelay(const CGovernanceVote& vote, CGovernanceException& exception) {
|
bool ProcessVoteAndRelay(const CGovernanceVote& vote, CGovernanceException& exception) {
|
||||||
bool fOK = ProcessVote(NULL, vote, exception);
|
bool fOK = ProcessVote(NULL, vote, exception);
|
||||||
|
@ -214,7 +214,7 @@ UniValue gobject(const UniValue& params, bool fHelp)
|
|||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Object creation rate limit exceeded");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Object creation rate limit exceeded");
|
||||||
}
|
}
|
||||||
// This check should always pass, update buffer
|
// This check should always pass, update buffer
|
||||||
if(!governance.MasternodeRateCheck(govobj, true)) {
|
if(!governance.MasternodeRateCheck(govobj, UPDATE_TRUE)) {
|
||||||
LogPrintf("gobject(submit) -- Object submission rejected because of rate check failure (buffer updated) - hash = %s\n", strHash);
|
LogPrintf("gobject(submit) -- Object submission rejected because of rate check failure (buffer updated) - hash = %s\n", strHash);
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Object creation rate limit exceeded");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Object creation rate limit exceeded");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user