Drop watchdogs, replace them with sentinel pings (#1949)

* Drop watchdogs, replace them with sentinel pings

* Address review comments

* revert `()`
This commit is contained in:
UdjinM6 2018-02-25 08:33:27 +03:00 committed by GitHub
parent ef9a9f2d67
commit 89380b4c92
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 85 additions and 239 deletions

View File

@ -98,7 +98,7 @@ bool CActiveMasternode::SendMasternodePing(CConnman& connman)
CMasternodePing mnp(outpoint);
mnp.nSentinelVersion = nSentinelVersion;
mnp.fSentinelIsCurrent =
(abs(GetAdjustedTime() - nSentinelPingTime) < MASTERNODE_WATCHDOG_MAX_SECONDS);
(abs(GetAdjustedTime() - nSentinelPingTime) < MASTERNODE_SENTINEL_PING_MAX_SECONDS);
if(!mnp.Sign(keyMasternode, pubKeyMasternode)) {
LogPrintf("CActiveMasternode::SendMasternodePing -- ERROR: Couldn't sign Masternode Ping\n");
return false;

View File

@ -447,9 +447,11 @@ bool CGovernanceObject::IsValidLocally(std::string& strError, bool& fMissingMast
}
switch(nObjectType) {
case GOVERNANCE_OBJECT_WATCHDOG:
// watchdogs are deprecated
return false;
case GOVERNANCE_OBJECT_PROPOSAL:
case GOVERNANCE_OBJECT_TRIGGER:
case GOVERNANCE_OBJECT_WATCHDOG:
if (vchData.size() > MAX_GOVERNANCE_OBJECT_DATA_SIZE) {
strError = strprintf("Invalid object size %d", vchData.size());
return false;
@ -465,7 +467,7 @@ bool CGovernanceObject::IsValidLocally(std::string& strError, bool& fMissingMast
// CHECK COLLATERAL IF REQUIRED (HIGH CPU USAGE)
if(fCheckCollateral) {
if((nObjectType == GOVERNANCE_OBJECT_TRIGGER) || (nObjectType == GOVERNANCE_OBJECT_WATCHDOG)) {
if(nObjectType == GOVERNANCE_OBJECT_TRIGGER) {
std::string strOutpoint = masternodeOutpoint.ToStringShort();
masternode_info_t infoMn;
if(!mnodeman.GetMasternodeInfo(masternodeOutpoint, infoMn)) {

View File

@ -42,7 +42,6 @@ static const int64_t GOVERNANCE_MIN_RELAY_FEE_CONFIRMATIONS = 1;
static const int64_t GOVERNANCE_UPDATE_MIN = 60*60;
static const int64_t GOVERNANCE_DELETION_DELAY = 10*60;
static const int64_t GOVERNANCE_ORPHAN_EXPIRATION_TIME = 10*60;
static const int64_t GOVERNANCE_WATCHDOG_EXPIRATION_TIME = 2*60*60;
// FOR SEEN MAP ARRAYS - GOVERNANCE OBJECTS AND VOTES
static const int SEEN_OBJECT_IS_VALID = 0;

View File

@ -29,9 +29,6 @@ CGovernanceManager::CGovernanceManager()
mapObjects(),
mapErasedGovernanceObjects(),
mapMasternodeOrphanObjects(),
mapWatchdogObjects(),
nHashWatchdogCurrent(),
nTimeWatchdogCurrent(0),
cmapVoteToObject(MAX_CACHE_SIZE),
cmapInvalidVotes(MAX_CACHE_SIZE),
cmmapOrphanVotes(MAX_CACHE_SIZE),
@ -321,26 +318,6 @@ void CGovernanceManager::AddGovernanceObject(CGovernanceObject& govobj, CConnman
LogPrint("gobject", "CGovernanceManager::AddGovernanceObject -- Adding object: hash = %s, type = %d\n", nHash.ToString(), govobj.GetObjectType());
if(govobj.nObjectType == GOVERNANCE_OBJECT_WATCHDOG) {
// If it's a watchdog, make sure it fits required time bounds
if((govobj.GetCreationTime() < GetAdjustedTime() - GOVERNANCE_WATCHDOG_EXPIRATION_TIME ||
govobj.GetCreationTime() > GetAdjustedTime() + GOVERNANCE_WATCHDOG_EXPIRATION_TIME)
) {
// drop it
LogPrint("gobject", "CGovernanceManager::AddGovernanceObject -- CreationTime is out of bounds: hash = %s\n", nHash.ToString());
return;
}
if(!UpdateCurrentWatchdog(govobj)) {
// Allow wd's which are not current to be reprocessed
if(pfrom && (nHashWatchdogCurrent != uint256())) {
pfrom->PushInventory(CInv(MSG_GOVERNANCE_OBJECT, nHashWatchdogCurrent));
}
LogPrint("gobject", "CGovernanceManager::AddGovernanceObject -- Watchdog not better than current: hash = %s\n", nHash.ToString());
return;
}
}
// INSERT INTO OUR GOVERNANCE OBJECT MEMORY
mapObjects.insert(std::make_pair(nHash, govobj));
@ -351,18 +328,10 @@ void CGovernanceManager::AddGovernanceObject(CGovernanceObject& govobj, CConnman
<< ", nObjectType = " << govobj.nObjectType
<< std::endl; );
switch(govobj.nObjectType) {
case GOVERNANCE_OBJECT_TRIGGER:
if (govobj.nObjectType == GOVERNANCE_OBJECT_TRIGGER) {
DBG( std::cout << "CGovernanceManager::AddGovernanceObject Before AddNewTrigger" << std::endl; );
triggerman.AddNewTrigger(nHash);
DBG( std::cout << "CGovernanceManager::AddGovernanceObject After AddNewTrigger" << std::endl; );
break;
case GOVERNANCE_OBJECT_WATCHDOG:
mapWatchdogObjects[nHash] = govobj.GetCreationTime() + GOVERNANCE_WATCHDOG_EXPIRATION_TIME;
LogPrint("gobject", "CGovernanceManager::AddGovernanceObject -- Added watchdog to map: hash = %s\n", nHash.ToString());
break;
default:
break;
}
LogPrintf("AddGovernanceObject -- %s new, received form %s\n", strHash, pfrom? pfrom->GetAddrName() : "NULL");
@ -381,40 +350,6 @@ void CGovernanceManager::AddGovernanceObject(CGovernanceObject& govobj, CConnman
DBG( std::cout << "CGovernanceManager::AddGovernanceObject END" << std::endl; );
}
bool CGovernanceManager::UpdateCurrentWatchdog(CGovernanceObject& watchdogNew)
{
bool fAccept = false;
arith_uint256 nHashNew = UintToArith256(watchdogNew.GetHash());
arith_uint256 nHashCurrent = UintToArith256(nHashWatchdogCurrent);
int64_t nExpirationDelay = GOVERNANCE_WATCHDOG_EXPIRATION_TIME / 2;
int64_t nNow = GetAdjustedTime();
if(nHashWatchdogCurrent == uint256() || // no known current OR
((nNow - watchdogNew.GetCreationTime() < nExpirationDelay) && // (new one is NOT expired AND
((nNow - nTimeWatchdogCurrent > nExpirationDelay) || (nHashNew > nHashCurrent)))// (current is expired OR
// its hash is lower))
) {
LOCK(cs);
object_m_it it = mapObjects.find(nHashWatchdogCurrent);
if(it != mapObjects.end()) {
LogPrint("gobject", "CGovernanceManager::UpdateCurrentWatchdog -- Expiring previous current watchdog, hash = %s\n", nHashWatchdogCurrent.ToString());
it->second.fExpired = true;
if(it->second.nDeletionTime == 0) {
it->second.nDeletionTime = nNow;
}
}
nHashWatchdogCurrent = watchdogNew.GetHash();
nTimeWatchdogCurrent = watchdogNew.GetCreationTime();
fAccept = true;
LogPrint("gobject", "CGovernanceManager::UpdateCurrentWatchdog -- Current watchdog updated to: hash = %s\n",
ArithToUint256(nHashNew).ToString());
}
return fAccept;
}
void CGovernanceManager::UpdateCachesAndClean()
{
LogPrint("gobject", "CGovernanceManager::UpdateCachesAndClean\n");
@ -423,34 +358,6 @@ void CGovernanceManager::UpdateCachesAndClean()
LOCK2(cs_main, cs);
// Flag expired watchdogs for removal
int64_t nNow = GetAdjustedTime();
LogPrint("gobject", "CGovernanceManager::UpdateCachesAndClean -- Number watchdogs in map: %d, current time = %d\n", mapWatchdogObjects.size(), nNow);
if(mapWatchdogObjects.size() > 1) {
hash_time_m_it it = mapWatchdogObjects.begin();
while(it != mapWatchdogObjects.end()) {
LogPrint("gobject", "CGovernanceManager::UpdateCachesAndClean -- Checking watchdog: %s, expiration time = %d\n", it->first.ToString(), it->second);
if(it->second < nNow) {
LogPrint("gobject", "CGovernanceManager::UpdateCachesAndClean -- Attempting to expire watchdog: %s, expiration time = %d\n", it->first.ToString(), it->second);
object_m_it it2 = mapObjects.find(it->first);
if(it2 != mapObjects.end()) {
LogPrint("gobject", "CGovernanceManager::UpdateCachesAndClean -- Expiring watchdog: %s, expiration time = %d\n", it->first.ToString(), it->second);
it2->second.fExpired = true;
if(it2->second.nDeletionTime == 0) {
it2->second.nDeletionTime = nNow;
}
}
if(it->first == nHashWatchdogCurrent) {
nHashWatchdogCurrent = uint256();
}
mapWatchdogObjects.erase(it++);
}
else {
++it;
}
}
}
for(size_t i = 0; i < vecDirtyHashes.size(); ++i) {
object_m_it it = mapObjects.find(vecDirtyHashes[i]);
if(it == mapObjects.end()) {
@ -469,6 +376,8 @@ void CGovernanceManager::UpdateCachesAndClean()
// Clean up any expired or invalid triggers
triggerman.CleanAndRemove();
int64_t nNow = GetAdjustedTime();
while(it != mapObjects.end())
{
CGovernanceObject* pObj = &((*it).second);
@ -490,13 +399,9 @@ void CGovernanceManager::UpdateCachesAndClean()
pObj->UpdateSentinelVariables();
}
if(pObj->IsSetCachedDelete() && (nHash == nHashWatchdogCurrent)) {
nHashWatchdogCurrent = uint256();
}
// IF DELETE=TRUE, THEN CLEAN THE MESS UP!
int64_t nTimeSinceDeletion = GetAdjustedTime() - pObj->GetDeletionTime();
int64_t nTimeSinceDeletion = nNow - pObj->GetDeletionTime();
LogPrint("gobject", "CGovernanceManager::UpdateCachesAndClean -- Checking object for deletion: %s, deletion time = %d, time since deletion = %d, delete flag = %d, expired flag = %d\n",
strHash, pObj->GetDeletionTime(), nTimeSinceDeletion, pObj->IsSetCachedDelete(), pObj->IsSetExpired());
@ -520,14 +425,14 @@ void CGovernanceManager::UpdateCachesAndClean()
}
}
int64_t nSuperblockCycleSeconds = Params().GetConsensus().nSuperblockCycle * Params().GetConsensus().nPowTargetSpacing;
int64_t nTimeExpired = pObj->GetCreationTime() + 2 * nSuperblockCycleSeconds + GOVERNANCE_DELETION_DELAY;
int64_t nTimeExpired{0};
if(pObj->GetObjectType() == GOVERNANCE_OBJECT_WATCHDOG) {
mapWatchdogObjects.erase(nHash);
} else if(pObj->GetObjectType() != GOVERNANCE_OBJECT_TRIGGER) {
if(pObj->GetObjectType() == GOVERNANCE_OBJECT_PROPOSAL) {
// keep hashes of deleted proposals forever
nTimeExpired = std::numeric_limits<int64_t>::max();
} else {
int64_t nSuperblockCycleSeconds = Params().GetConsensus().nSuperblockCycle * Params().GetConsensus().nPowTargetSpacing;
nTimeExpired = pObj->GetCreationTime() + 2 * nSuperblockCycleSeconds + GOVERNANCE_DELETION_DELAY;
}
mapErasedGovernanceObjects.insert(std::make_pair(nHash, nTimeExpired));
@ -824,8 +729,7 @@ void CGovernanceManager::SyncAll(CNode* pnode, CConnman& connman)
void CGovernanceManager::MasternodeRateUpdate(const CGovernanceObject& govobj)
{
int nObjectType = govobj.GetObjectType();
if((nObjectType != GOVERNANCE_OBJECT_TRIGGER) && (nObjectType != GOVERNANCE_OBJECT_WATCHDOG))
if(govobj.GetObjectType() != GOVERNANCE_OBJECT_TRIGGER)
return;
const COutPoint& masternodeOutpoint = govobj.GetMasternodeOutpoint();
@ -835,10 +739,7 @@ void CGovernanceManager::MasternodeRateUpdate(const CGovernanceObject& govobj)
it = mapLastMasternodeObject.insert(txout_m_t::value_type(masternodeOutpoint, last_object_rec(true))).first;
int64_t nTimestamp = govobj.GetCreationTime();
if (GOVERNANCE_OBJECT_TRIGGER == nObjectType)
it->second.triggerBuffer.AddTimestamp(nTimestamp);
else if (GOVERNANCE_OBJECT_WATCHDOG == nObjectType)
it->second.watchdogBuffer.AddTimestamp(nTimestamp);
it->second.triggerBuffer.AddTimestamp(nTimestamp);
if (nTimestamp > GetTime() + MAX_TIME_FUTURE_DEVIATION - RELIABLE_PROPAGATION_TIME) {
// schedule additional relay for the object
@ -868,8 +769,7 @@ bool CGovernanceManager::MasternodeRateCheck(const CGovernanceObject& govobj, bo
return true;
}
int nObjectType = govobj.GetObjectType();
if((nObjectType != GOVERNANCE_OBJECT_TRIGGER) && (nObjectType != GOVERNANCE_OBJECT_WATCHDOG)) {
if(govobj.GetObjectType() != GOVERNANCE_OBJECT_TRIGGER) {
return true;
}
@ -901,38 +801,26 @@ bool CGovernanceManager::MasternodeRateCheck(const CGovernanceObject& govobj, bo
return true;
}
double dMaxRate = 1.1 / nSuperblockCycleSeconds;
double dRate = 0.0;
CRateCheckBuffer buffer;
switch(nObjectType) {
case GOVERNANCE_OBJECT_TRIGGER:
// Allow 1 trigger per mn per cycle, with a small fudge factor
buffer = it->second.triggerBuffer;
dMaxRate = 2 * 1.1 / double(nSuperblockCycleSeconds);
break;
case GOVERNANCE_OBJECT_WATCHDOG:
buffer = it->second.watchdogBuffer;
dMaxRate = 2 * 1.1 / 3600.;
break;
default:
break;
}
// Allow 1 trigger per mn per cycle, with a small fudge factor
double dMaxRate = 2 * 1.1 / double(nSuperblockCycleSeconds);
// Temporary copy to check rate after new timestamp is added
CRateCheckBuffer buffer = it->second.triggerBuffer;
buffer.AddTimestamp(nTimestamp);
dRate = buffer.GetRate();
double dRate = buffer.GetRate();
bool fRateOK = ( dRate < dMaxRate );
if(!fRateOK)
{
LogPrintf("CGovernanceManager::MasternodeRateCheck -- Rate too high: object hash = %s, masternode = %s, object timestamp = %d, rate = %f, max rate = %f\n",
strHash, masternodeOutpoint.ToStringShort(), nTimestamp, dRate, dMaxRate);
if (fUpdateFailStatus)
it->second.fStatusOK = false;
if(dRate < dMaxRate) {
return true;
}
return fRateOK;
LogPrintf("CGovernanceManager::MasternodeRateCheck -- Rate too high: object hash = %s, masternode = %s, object timestamp = %d, rate = %f, max rate = %f\n",
strHash, masternodeOutpoint.ToStringShort(), nTimestamp, dRate, dMaxRate);
if (fUpdateFailStatus)
it->second.fStatusOK = false;
return false;
}
bool CGovernanceManager::ProcessVote(CNode* pfrom, const CGovernanceVote& vote, CGovernanceException& exception, CConnman& connman)
@ -985,10 +873,6 @@ bool CGovernanceManager::ProcessVote(CNode* pfrom, const CGovernanceVote& vote,
}
bool fOk = govobj.ProcessVote(pfrom, vote, exception, connman) && cmapVoteToObject.Insert(nHashVote, &govobj);
if(fOk && govobj.GetObjectType() == GOVERNANCE_OBJECT_WATCHDOG) {
mnodeman.UpdateWatchdogVoteTime(vote.GetMasternodeOutpoint());
LogPrint("gobject", "CGovernanceObject::ProcessVote -- GOVERNANCE_OBJECT_WATCHDOG vote %s for %s\n", nHashVote.ToString(), nHashGovobj.ToString());
}
LEAVE_CRITICAL_SECTION(cs);
return fOk;
}
@ -1051,8 +935,7 @@ void CGovernanceManager::CheckPostponedObjects(CConnman& connman)
const uint256& nHash = it->first;
CGovernanceObject& govobj = it->second;
assert(govobj.GetObjectType() != GOVERNANCE_OBJECT_WATCHDOG &&
govobj.GetObjectType() != GOVERNANCE_OBJECT_TRIGGER);
assert(govobj.GetObjectType() != GOVERNANCE_OBJECT_TRIGGER);
std::string strError;
bool fMissingConfirmations;
@ -1074,7 +957,7 @@ void CGovernanceManager::CheckPostponedObjects(CConnman& connman)
}
// Perform additional relays for triggers/watchdogs
// Perform additional relays for triggers
int64_t nNow = GetAdjustedTime();
int64_t nSuperblockCycleSeconds = Params().GetConsensus().nSuperblockCycle * Params().GetConsensus().nPowTargetSpacing;
@ -1323,7 +1206,6 @@ std::string CGovernanceManager::ToString() const
int nProposalCount = 0;
int nTriggerCount = 0;
int nWatchdogCount = 0;
int nOtherCount = 0;
object_m_cit it = mapObjects.begin();
@ -1336,9 +1218,6 @@ std::string CGovernanceManager::ToString() const
case GOVERNANCE_OBJECT_TRIGGER:
nTriggerCount++;
break;
case GOVERNANCE_OBJECT_WATCHDOG:
nWatchdogCount++;
break;
default:
nOtherCount++;
break;
@ -1346,9 +1225,9 @@ std::string CGovernanceManager::ToString() const
++it;
}
return strprintf("Governance Objects: %d (Proposals: %d, Triggers: %d, Watchdogs: %d/%d, Other: %d; Erased: %d), Votes: %d",
return strprintf("Governance Objects: %d (Proposals: %d, Triggers: %d, Other: %d; Erased: %d), Votes: %d",
(int)mapObjects.size(),
nProposalCount, nTriggerCount, nWatchdogCount, mapWatchdogObjects.size(), nOtherCount, (int)mapErasedGovernanceObjects.size(),
nProposalCount, nTriggerCount, nOtherCount, (int)mapErasedGovernanceObjects.size(),
(int)cmapVoteToObject.GetSize());
}

View File

@ -152,7 +152,6 @@ public: // Types
struct last_object_rec {
last_object_rec(bool fStatusOKIn = true)
: triggerBuffer(),
watchdogBuffer(),
fStatusOK(fStatusOKIn)
{}
@ -162,12 +161,10 @@ public: // Types
inline void SerializationOp(Stream& s, Operation ser_action)
{
READWRITE(triggerBuffer);
READWRITE(watchdogBuffer);
READWRITE(fStatusOK);
}
CRateCheckBuffer triggerBuffer;
CRateCheckBuffer watchdogBuffer;
bool fStatusOK;
};
@ -245,12 +242,6 @@ private:
object_m_t mapPostponedObjects;
hash_s_t setAdditionalRelayObjects;
hash_time_m_t mapWatchdogObjects;
uint256 nHashWatchdogCurrent;
int64_t nTimeWatchdogCurrent;
object_ref_cm_t cmapVoteToObject;
vote_cm_t cmapInvalidVotes;
@ -328,9 +319,6 @@ public:
LogPrint("gobject", "Governance object manager was cleared\n");
mapObjects.clear();
mapErasedGovernanceObjects.clear();
mapWatchdogObjects.clear();
nHashWatchdogCurrent = uint256();
nTimeWatchdogCurrent = 0;
cmapVoteToObject.Clear();
cmapInvalidVotes.Clear();
cmmapOrphanVotes.Clear();
@ -357,9 +345,6 @@ public:
READWRITE(cmapInvalidVotes);
READWRITE(cmmapOrphanVotes);
READWRITE(mapObjects);
READWRITE(mapWatchdogObjects);
READWRITE(nHashWatchdogCurrent);
READWRITE(nTimeWatchdogCurrent);
READWRITE(mapLastMasternodeObject);
if(ser_action.ForRead() && (strVersion != SERIALIZATION_VERSION_STRING)) {
Clear();
@ -453,8 +438,6 @@ private:
void AddCachedTriggers();
bool UpdateCurrentWatchdog(CGovernanceObject& watchdogNew);
void RequestOrphanObjects(CConnman& connman);
void CleanOrphanObjects();

View File

@ -46,8 +46,7 @@ CMasternode::CMasternode(const CMasternode& other) :
CMasternode::CMasternode(const CMasternodeBroadcast& mnb) :
masternode_info_t{ mnb.nActiveState, mnb.nProtocolVersion, mnb.sigTime,
mnb.outpoint, mnb.addr, mnb.pubKeyCollateralAddress, mnb.pubKeyMasternode,
mnb.sigTime /*nTimeLastWatchdogVote*/},
mnb.outpoint, mnb.addr, mnb.pubKeyCollateralAddress, mnb.pubKeyMasternode},
lastPing(mnb.lastPing),
vchSig(mnb.vchSig),
fAllowMixingTx(true)
@ -194,7 +193,7 @@ void CMasternode::Check(bool fForce)
if(fWaitForPing && !fOurMasternode) {
// ...but if it was already expired before the initial check - return right away
if(IsExpired() || IsWatchdogExpired() || IsNewStartRequired()) {
if(IsExpired() || IsSentinelPingExpired() || IsNewStartRequired()) {
LogPrint("masternode", "CMasternode::Check -- Masternode %s is in %s state, waiting for ping\n", outpoint.ToStringShort(), GetStateString());
return;
}
@ -211,14 +210,14 @@ void CMasternode::Check(bool fForce)
return;
}
bool fWatchdogActive = masternodeSync.IsSynced() && mnodeman.IsWatchdogActive();
bool fWatchdogExpired = (fWatchdogActive && ((GetAdjustedTime() - nTimeLastWatchdogVote) > MASTERNODE_WATCHDOG_MAX_SECONDS));
bool fSentinelPingActive = masternodeSync.IsSynced() && mnodeman.IsSentinelPingActive();
bool fSentinelPingExpired = fSentinelPingActive && (!lastPing.fSentinelIsCurrent || !IsPingedWithin(MASTERNODE_SENTINEL_PING_MAX_SECONDS));
LogPrint("masternode", "CMasternode::Check -- outpoint=%s, nTimeLastWatchdogVote=%d, GetAdjustedTime()=%d, fWatchdogExpired=%d\n",
outpoint.ToStringShort(), nTimeLastWatchdogVote, GetAdjustedTime(), fWatchdogExpired);
LogPrint("masternode", "CMasternode::Check -- outpoint=%s, GetAdjustedTime()=%d, fSentinelPingExpired=%d\n",
outpoint.ToStringShort(), GetAdjustedTime(), fSentinelPingExpired);
if(fWatchdogExpired) {
nActiveState = MASTERNODE_WATCHDOG_EXPIRED;
if(fSentinelPingExpired) {
nActiveState = MASTERNODE_SENTINEL_PING_EXPIRED;
if(nActiveStatePrev != nActiveState) {
LogPrint("masternode", "CMasternode::Check -- Masternode %s is in %s state now\n", outpoint.ToStringShort(), GetStateString());
}
@ -281,7 +280,7 @@ std::string CMasternode::StateToString(int nStateIn)
case MASTERNODE_EXPIRED: return "EXPIRED";
case MASTERNODE_OUTPOINT_SPENT: return "OUTPOINT_SPENT";
case MASTERNODE_UPDATE_REQUIRED: return "UPDATE_REQUIRED";
case MASTERNODE_WATCHDOG_EXPIRED: return "WATCHDOG_EXPIRED";
case MASTERNODE_SENTINEL_PING_EXPIRED: return "SENTINEL_PING_EXPIRED";
case MASTERNODE_NEW_START_REQUIRED: return "NEW_START_REQUIRED";
case MASTERNODE_POSE_BAN: return "POSE_BAN";
default: return "UNKNOWN";
@ -890,8 +889,8 @@ bool CMasternodePing::CheckAndUpdate(CMasternode* pmn, bool fFromNewBroadcast, i
// force update, ignoring cache
pmn->Check(true);
// relay ping for nodes in ENABLED/EXPIRED/WATCHDOG_EXPIRED state only, skip everyone else
if (!pmn->IsEnabled() && !pmn->IsExpired() && !pmn->IsWatchdogExpired()) return false;
// relay ping for nodes in ENABLED/EXPIRED/SENTINEL_PING_EXPIRED state only, skip everyone else
if (!pmn->IsEnabled() && !pmn->IsExpired() && !pmn->IsSentinelPingExpired()) return false;
LogPrint("masternode", "CMasternodePing::CheckAndUpdate -- Masternode ping acceepted and relayed, masternode=%s\n", masternodeOutpoint.ToStringShort());
Relay(connman);
@ -929,12 +928,6 @@ void CMasternode::RemoveGovernanceObject(uint256 nGovernanceObjectHash)
mapGovernanceObjectsVotedOn.erase(it);
}
void CMasternode::UpdateWatchdogVoteTime(uint64_t nVoteTime)
{
LOCK(cs);
nTimeLastWatchdogVote = (nVoteTime == 0) ? GetAdjustedTime() : nVoteTime;
}
/**
* FLAG GOVERNANCE ITEMS AS DIRTY
*

View File

@ -17,7 +17,7 @@ static const int MASTERNODE_CHECK_SECONDS = 5;
static const int MASTERNODE_MIN_MNB_SECONDS = 5 * 60;
static const int MASTERNODE_MIN_MNP_SECONDS = 10 * 60;
static const int MASTERNODE_EXPIRATION_SECONDS = 65 * 60;
static const int MASTERNODE_WATCHDOG_MAX_SECONDS = 120 * 60;
static const int MASTERNODE_SENTINEL_PING_MAX_SECONDS = 120 * 60;
static const int MASTERNODE_NEW_START_REQUIRED_SECONDS = 180 * 60;
static const int MASTERNODE_POSE_BAN_MAX_SCORE = 5;
@ -129,12 +129,10 @@ struct masternode_info_t
masternode_info_t(int activeState, int protoVer, int64_t sTime,
COutPoint const& outpnt, CService const& addr,
CPubKey const& pkCollAddr, CPubKey const& pkMN,
int64_t tWatchdogV = 0) :
CPubKey const& pkCollAddr, CPubKey const& pkMN) :
nActiveState{activeState}, nProtocolVersion{protoVer}, sigTime{sTime},
outpoint{outpnt}, addr{addr},
pubKeyCollateralAddress{pkCollAddr}, pubKeyMasternode{pkMN},
nTimeLastWatchdogVote{tWatchdogV} {}
pubKeyCollateralAddress{pkCollAddr}, pubKeyMasternode{pkMN} {}
int nActiveState = 0;
int nProtocolVersion = 0;
@ -144,7 +142,6 @@ struct masternode_info_t
CService addr{};
CPubKey pubKeyCollateralAddress{};
CPubKey pubKeyMasternode{};
int64_t nTimeLastWatchdogVote = 0;
int64_t nLastDsq = 0; //the dsq count from the last dsq broadcast of this node
int64_t nTimeLastChecked = 0;
@ -170,7 +167,7 @@ public:
MASTERNODE_EXPIRED,
MASTERNODE_OUTPOINT_SPENT,
MASTERNODE_UPDATE_REQUIRED,
MASTERNODE_WATCHDOG_EXPIRED,
MASTERNODE_SENTINEL_PING_EXPIRED,
MASTERNODE_NEW_START_REQUIRED,
MASTERNODE_POSE_BAN
};
@ -230,7 +227,6 @@ public:
READWRITE(nLastDsq);
READWRITE(nTimeLastChecked);
READWRITE(nTimeLastPaid);
READWRITE(nTimeLastWatchdogVote);
READWRITE(nActiveState);
READWRITE(nCollateralMinConfBlockHash);
READWRITE(nBlockLastPaid);
@ -271,7 +267,7 @@ public:
bool IsExpired() const { return nActiveState == MASTERNODE_EXPIRED; }
bool IsOutpointSpent() const { return nActiveState == MASTERNODE_OUTPOINT_SPENT; }
bool IsUpdateRequired() const { return nActiveState == MASTERNODE_UPDATE_REQUIRED; }
bool IsWatchdogExpired() const { return nActiveState == MASTERNODE_WATCHDOG_EXPIRED; }
bool IsSentinelPingExpired() const { return nActiveState == MASTERNODE_SENTINEL_PING_EXPIRED; }
bool IsNewStartRequired() const { return nActiveState == MASTERNODE_NEW_START_REQUIRED; }
static bool IsValidStateForAutoStart(int nActiveStateIn)
@ -279,7 +275,7 @@ public:
return nActiveStateIn == MASTERNODE_ENABLED ||
nActiveStateIn == MASTERNODE_PRE_ENABLED ||
nActiveStateIn == MASTERNODE_EXPIRED ||
nActiveStateIn == MASTERNODE_WATCHDOG_EXPIRED;
nActiveStateIn == MASTERNODE_SENTINEL_PING_EXPIRED;
}
bool IsValidForPayment() const
@ -288,7 +284,7 @@ public:
return true;
}
if(!sporkManager.IsSporkActive(SPORK_14_REQUIRE_SENTINEL_FLAG) &&
(nActiveState == MASTERNODE_WATCHDOG_EXPIRED)) {
(nActiveState == MASTERNODE_SENTINEL_PING_EXPIRED)) {
return true;
}
@ -319,8 +315,6 @@ public:
void RemoveGovernanceObject(uint256 nGovernanceObjectHash);
void UpdateWatchdogVoteTime(uint64_t nVoteTime = 0);
CMasternode& operator=(CMasternode const& from)
{
static_cast<masternode_info_t&>(*this)=from;

View File

@ -63,7 +63,7 @@ CMasternodeMan::CMasternodeMan():
fMasternodesAdded(false),
fMasternodesRemoved(false),
vecDirtyGovernanceObjectHashes(),
nLastWatchdogVoteTime(0),
nLastSentinelPingTime(0),
mapSeenMasternodeBroadcast(),
mapSeenMasternodePing(),
nDsqCount(0)
@ -157,7 +157,7 @@ void CMasternodeMan::Check()
{
LOCK(cs);
LogPrint("masternode", "CMasternodeMan::Check -- nLastWatchdogVoteTime=%d, IsWatchdogActive()=%d\n", nLastWatchdogVoteTime, IsWatchdogActive());
LogPrint("masternode", "CMasternodeMan::Check -- nLastSentinelPingTime=%d, IsSentinelPingActive()=%d\n", nLastSentinelPingTime, IsSentinelPingActive());
for (auto& mnpair : mapMasternodes) {
// NOTE: internally it checks only every MASTERNODE_CHECK_SECONDS seconds
@ -359,7 +359,7 @@ void CMasternodeMan::Clear()
mapSeenMasternodeBroadcast.clear();
mapSeenMasternodePing.clear();
nDsqCount = 0;
nLastWatchdogVoteTime = 0;
nLastSentinelPingTime = 0;
}
int CMasternodeMan::CountMasternodes(int nProtocolVersion)
@ -846,11 +846,8 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, const std::string& strCommand,
// see if we have this Masternode
CMasternode* pmn = Find(mnp.masternodeOutpoint);
// if masternode uses sentinel ping instead of watchdog
// we shoud update nTimeLastWatchdogVote here if sentinel
// ping flag is actual
if(pmn && mnp.fSentinelIsCurrent)
UpdateWatchdogVoteTime(mnp.masternodeOutpoint, mnp.sigTime);
UpdateLastSentinelPingTime();
// too late, new MNANNOUNCE is required
if(pmn && pmn->IsNewStartRequired()) return;
@ -1609,22 +1606,17 @@ void CMasternodeMan::UpdateLastPaid(const CBlockIndex* pindex)
IsFirstRun = false;
}
void CMasternodeMan::UpdateWatchdogVoteTime(const COutPoint& outpoint, uint64_t nVoteTime)
void CMasternodeMan::UpdateLastSentinelPingTime()
{
LOCK(cs);
CMasternode* pmn = Find(outpoint);
if(!pmn) {
return;
}
pmn->UpdateWatchdogVoteTime(nVoteTime);
nLastWatchdogVoteTime = GetTime();
nLastSentinelPingTime = GetTime();
}
bool CMasternodeMan::IsWatchdogActive()
bool CMasternodeMan::IsSentinelPingActive()
{
LOCK(cs);
// Check if any masternodes have voted recently, otherwise return false
return (GetTime() - nLastWatchdogVoteTime) <= MASTERNODE_WATCHDOG_MAX_SECONDS;
return (GetTime() - nLastSentinelPingTime) <= MASTERNODE_SENTINEL_PING_MAX_SECONDS;
}
bool CMasternodeMan::AddGovernanceVote(const COutPoint& outpoint, uint256 nGovernanceObjectHash)
@ -1672,11 +1664,8 @@ void CMasternodeMan::SetMasternodeLastPing(const COutPoint& outpoint, const CMas
return;
}
pmn->lastPing = mnp;
// if masternode uses sentinel ping instead of watchdog
// we shoud update nTimeLastWatchdogVote here if sentinel
// ping flag is actual
if(mnp.fSentinelIsCurrent) {
UpdateWatchdogVoteTime(mnp.masternodeOutpoint, mnp.sigTime);
UpdateLastSentinelPingTime();
}
mapSeenMasternodePing.insert(std::make_pair(mnp.GetHash(), mnp));

View File

@ -73,7 +73,7 @@ private:
std::vector<uint256> vecDirtyGovernanceObjectHashes;
int64_t nLastWatchdogVoteTime;
int64_t nLastSentinelPingTime;
friend class CMasternodeSync;
/// Find an entry
@ -117,7 +117,7 @@ public:
READWRITE(mWeAskedForMasternodeListEntry);
READWRITE(mMnbRecoveryRequests);
READWRITE(mMnbRecoveryGoodReplies);
READWRITE(nLastWatchdogVoteTime);
READWRITE(nLastSentinelPingTime);
READWRITE(nDsqCount);
READWRITE(mapSeenMasternodeBroadcast);
@ -223,8 +223,8 @@ public:
return vecTmp;;
}
bool IsWatchdogActive();
void UpdateWatchdogVoteTime(const COutPoint& outpoint, uint64_t nVoteTime = 0);
bool IsSentinelPingActive();
void UpdateLastSentinelPingTime();
bool AddGovernanceVote(const COutPoint& outpoint, uint256 nGovernanceObjectHash);
void RemoveGovernanceObject(uint256 nGovernanceObjectHash);

View File

@ -157,9 +157,12 @@ UniValue gobject(const JSONRPCRequest& request)
}
}
if((govobj.GetObjectType() == GOVERNANCE_OBJECT_TRIGGER) ||
(govobj.GetObjectType() == GOVERNANCE_OBJECT_WATCHDOG)) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Trigger and watchdog objects need not be prepared (however only masternodes can create them)");
if(govobj.GetObjectType() == GOVERNANCE_OBJECT_TRIGGER) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Trigger objects need not be prepared (however only masternodes can create them)");
}
if(govobj.GetObjectType() == GOVERNANCE_OBJECT_WATCHDOG) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Watchdogs are deprecated");
}
{
@ -247,9 +250,12 @@ UniValue gobject(const JSONRPCRequest& request)
}
}
if(govobj.GetObjectType() == GOVERNANCE_OBJECT_WATCHDOG) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Watchdogs are deprecated");
}
// Attempt to sign triggers if we are a MN
if((govobj.GetObjectType() == GOVERNANCE_OBJECT_TRIGGER) ||
(govobj.GetObjectType() == GOVERNANCE_OBJECT_WATCHDOG)) {
if(govobj.GetObjectType() == GOVERNANCE_OBJECT_TRIGGER) {
if(fMnFound) {
govobj.SetMasternodeOutpoint(activeMasternode.outpoint);
govobj.Sign(activeMasternode.keyMasternode, activeMasternode.pubKeyMasternode);
@ -622,8 +628,8 @@ UniValue gobject(const JSONRPCRequest& request)
std::string strType = "all";
if (request.params.size() == 3) strType = request.params[2].get_str();
if (strType != "proposals" && strType != "triggers" && strType != "watchdogs" && strType != "all")
return "Invalid type, should be 'proposals', 'triggers', 'watchdogs' or 'all'";
if (strType != "proposals" && strType != "triggers" && strType != "all")
return "Invalid type, should be 'proposals', 'triggers' or 'all'";
// GET STARTING TIME TO QUERY SYSTEM WITH
@ -652,7 +658,6 @@ UniValue gobject(const JSONRPCRequest& request)
if(strType == "proposals" && pGovObj->GetObjectType() != GOVERNANCE_OBJECT_PROPOSAL) continue;
if(strType == "triggers" && pGovObj->GetObjectType() != GOVERNANCE_OBJECT_TRIGGER) continue;
if(strType == "watchdogs" && pGovObj->GetObjectType() != GOVERNANCE_OBJECT_WATCHDOG) continue;
UniValue bObj(UniValue::VOBJ);
bObj.push_back(Pair("DataHex", pGovObj->GetDataAsHexString()));
@ -915,7 +920,8 @@ UniValue getgovernanceinfo(const JSONRPCRequest& request)
"\nResult:\n"
"{\n"
" \"governanceminquorum\": xxxxx, (numeric) the absolute minimum number of votes needed to trigger a governance action\n"
" \"masternodewatchdogmaxseconds\": xxxxx, (numeric) sentinel watchdog expiration time in seconds\n"
" \"masternodewatchdogmaxseconds\": xxxxx, (numeric) sentinel watchdog expiration time in seconds (DEPRECATED)\n"
" \"sentinelpingmaxseconds\": xxxxx, (numeric) sentinel ping expiration time in seconds\n"
" \"proposalfee\": xxx.xx, (numeric) the collateral transaction fee which must be paid to create a proposal in " + CURRENCY_UNIT + "\n"
" \"superblockcycle\": xxxxx, (numeric) the number of blocks between superblocks\n"
" \"lastsuperblock\": xxxxx, (numeric) the block number of the last superblock\n"
@ -937,7 +943,8 @@ UniValue getgovernanceinfo(const JSONRPCRequest& request)
UniValue obj(UniValue::VOBJ);
obj.push_back(Pair("governanceminquorum", Params().GetConsensus().nGovernanceMinQuorum));
obj.push_back(Pair("masternodewatchdogmaxseconds", MASTERNODE_WATCHDOG_MAX_SECONDS));
obj.push_back(Pair("masternodewatchdogmaxseconds", MASTERNODE_SENTINEL_PING_MAX_SECONDS));
obj.push_back(Pair("sentinelpingmaxseconds", MASTERNODE_SENTINEL_PING_MAX_SECONDS));
obj.push_back(Pair("proposalfee", ValueFromAmount(GOVERNANCE_PROPOSAL_FEE_TX)));
obj.push_back(Pair("superblockcycle", Params().GetConsensus().nSuperblockCycle));
obj.push_back(Pair("lastsuperblock", nLastSuperblock));

View File

@ -501,7 +501,7 @@ UniValue masternodelist(const JSONRPCRequest& request)
" protocol - Print protocol of a masternode (can be additionally filtered, exact match)\n"
" pubkey - Print the masternode (not collateral) public key\n"
" rank - Print rank of a masternode based on current block\n"
" status - Print masternode status: PRE_ENABLED / ENABLED / EXPIRED / WATCHDOG_EXPIRED / NEW_START_REQUIRED /\n"
" status - Print masternode status: PRE_ENABLED / ENABLED / EXPIRED / SENTINEL_PING_EXPIRED / NEW_START_REQUIRED /\n"
" UPDATE_REQUIRED / POSE_BAN / OUTPOINT_SPENT (can be additionally filtered, partial match)\n"
);
}