Fix some gov sync issues (#1191)

* Don't relay objects and votes until synced

* fix sync timeout for govobjs

* count objs and votes separately

* reuse GetHash() value, adjust log messages
This commit is contained in:
UdjinM6 2016-12-06 20:40:37 +04:00 committed by GitHub
parent 0e28de7e10
commit 6a3550b94f
5 changed files with 41 additions and 40 deletions

View File

@ -651,6 +651,7 @@ bool CGovernanceObject::GetCurrentMNVotes(const CTxIn& mnCollateralOutpoint, vot
void CGovernanceObject::Relay() void CGovernanceObject::Relay()
{ {
if(!masternodeSync.IsSynced()) return;
CInv inv(MSG_GOVERNANCE_OBJECT, GetHash()); CInv inv(MSG_GOVERNANCE_OBJECT, GetHash());
RelayInv(inv, PROTOCOL_VERSION); RelayInv(inv, PROTOCOL_VERSION);
} }

View File

@ -235,6 +235,7 @@ CGovernanceVote::CGovernanceVote(CTxIn vinMasternodeIn, uint256 nParentHashIn, v
void CGovernanceVote::Relay() const void CGovernanceVote::Relay() const
{ {
if(!masternodeSync.IsSynced()) return;
CInv inv(MSG_GOVERNANCE_OBJECT_VOTE, GetHash()); CInv inv(MSG_GOVERNANCE_OBJECT_VOTE, GetHash());
RelayInv(inv, PROTOCOL_VERSION); RelayInv(inv, PROTOCOL_VERSION);
} }

View File

@ -145,7 +145,7 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, std::string& strCommand, C
// MAKE SURE WE HAVE A VALID REFERENCE TO THE TIP BEFORE CONTINUING // MAKE SURE WE HAVE A VALID REFERENCE TO THE TIP BEFORE CONTINUING
if(!pCurrentBlockIndex) { if(!pCurrentBlockIndex) {
LogPrintf("CGovernanceManager::ProcessMessage MNGOVERNANCEOBJECT -- pCurrentBlockIndex is NULL\n"); LogPrintf("MNGOVERNANCEOBJECT -- pCurrentBlockIndex is NULL\n");
return; return;
} }
@ -155,10 +155,10 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, std::string& strCommand, C
uint256 nHash = govobj.GetHash(); uint256 nHash = govobj.GetHash();
std::string strHash = nHash.ToString(); std::string strHash = nHash.ToString();
LogPrint("gobject", "CGovernanceManager -- Received object: %s\n", strHash); LogPrint("gobject", "MNGOVERNANCEOBJECT -- Received object: %s\n", strHash);
if(!AcceptObjectMessage(nHash)) { if(!AcceptObjectMessage(nHash)) {
LogPrintf("CGovernanceManager -- Received unrequested object: %s\n", strHash); LogPrintf("MNGOVERNANCEOBJECT -- Received unrequested object: %s\n", strHash);
Misbehaving(pfrom->GetId(), 20); Misbehaving(pfrom->GetId(), 20);
return; return;
} }
@ -167,7 +167,7 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, std::string& strCommand, C
if(mapSeenGovernanceObjects.count(nHash)) { if(mapSeenGovernanceObjects.count(nHash)) {
// TODO - print error code? what if it's GOVOBJ_ERROR_IMMATURE? // TODO - print error code? what if it's GOVOBJ_ERROR_IMMATURE?
LogPrint("gobject", "CGovernanceManager -- Received already seen object: %s\n", strHash); LogPrint("gobject", "MNGOVERNANCEOBJECT -- Received already seen object: %s\n", strHash);
return; return;
} }
@ -178,8 +178,8 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, std::string& strCommand, C
bool fIsValid = govobj.IsValidLocally(pCurrentBlockIndex, strError, fMasternodeMissing, true); bool fIsValid = govobj.IsValidLocally(pCurrentBlockIndex, strError, fMasternodeMissing, true);
if(fMasternodeMissing) { if(fMasternodeMissing) {
mapMasternodeOrphanObjects.insert(std::make_pair(govobj.GetHash(), object_time_pair_t(govobj, GetAdjustedTime() + GOVERNANCE_ORPHAN_EXPIRATION_TIME))); mapMasternodeOrphanObjects.insert(std::make_pair(nHash, object_time_pair_t(govobj, GetAdjustedTime() + GOVERNANCE_ORPHAN_EXPIRATION_TIME)));
LogPrint("gobject", "CGovernanceManager -- Missing masternode for: %s\n", strHash); LogPrint("gobject", "MNGOVERNANCEOBJECT -- Missing masternode for: %s\n", strHash);
// fIsValid must also be false here so we will return early in the next if block // fIsValid must also be false here so we will return early in the next if block
} }
if(!fIsValid) { if(!fIsValid) {
@ -199,8 +199,8 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, std::string& strCommand, C
} }
// UPDATE THAT WE'VE SEEN THIS OBJECT // UPDATE THAT WE'VE SEEN THIS OBJECT
mapSeenGovernanceObjects.insert(std::make_pair(govobj.GetHash(), SEEN_OBJECT_IS_VALID)); mapSeenGovernanceObjects.insert(std::make_pair(nHash, SEEN_OBJECT_IS_VALID));
masternodeSync.AddedBudgetItem(govobj.GetHash()); masternodeSync.AddedGovernanceItem();
// WE MIGHT HAVE PENDING/ORPHAN VOTES FOR THIS OBJECT // WE MIGHT HAVE PENDING/ORPHAN VOTES FOR THIS OBJECT
@ -214,30 +214,32 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, std::string& strCommand, C
{ {
// Ignore such messages until masternode list is synced // Ignore such messages until masternode list is synced
if(!masternodeSync.IsMasternodeListSynced()) { if(!masternodeSync.IsMasternodeListSynced()) {
LogPrint("gobject", "CGovernanceManager::ProcessMessage MNGOVERNANCEOBJECTVOTE -- masternode list not synced\n"); LogPrint("gobject", "MNGOVERNANCEOBJECTVOTE -- masternode list not synced\n");
return; return;
} }
CGovernanceVote vote; CGovernanceVote vote;
vRecv >> vote; vRecv >> vote;
LogPrint("gobject", "CGovernanceManager -- Received vote: %s\n", vote.ToString()); LogPrint("gobject", "MNGOVERNANCEOBJECTVOTE -- Received vote: %s\n", vote.ToString());
if(!AcceptVoteMessage(vote.GetHash())) { uint256 nHash = vote.GetHash();
LogPrintf("CGovernanceManager -- Received unrequested vote object: %s, hash: %s, peer = %d\n", std::string strHash = nHash.ToString();
vote.ToString(),
vote.GetHash().ToString(), if(!AcceptVoteMessage(nHash)) {
pfrom->GetId()); LogPrint("gobject", "MNGOVERNANCEOBJECTVOTE -- Received unrequested vote object: %s, hash: %s, peer = %d\n",
vote.ToString(), strHash, pfrom->GetId());
//Misbehaving(pfrom->GetId(), 20); //Misbehaving(pfrom->GetId(), 20);
return; return;
} }
CGovernanceException exception; CGovernanceException exception;
if(ProcessVote(pfrom, vote, exception)) { if(ProcessVote(pfrom, vote, exception)) {
LogPrint("gobject", "CGovernanceManager -- Accepted vote\n"); LogPrint("gobject", "MNGOVERNANCEOBJECTVOTE -- %s new\n", strHash);
masternodeSync.AddedGovernanceItem();
} }
else { else {
LogPrint("gobject", "CGovernanceManager -- Rejected vote, error = %s\n", exception.what()); LogPrint("gobject", "MNGOVERNANCEOBJECTVOTE -- Rejected vote, error = %s\n", exception.what());
if((exception.GetNodePenalty() != 0) && masternodeSync.IsSynced()) { if((exception.GetNodePenalty() != 0) && masternodeSync.IsSynced()) {
Misbehaving(pfrom->GetId(), exception.GetNodePenalty()); Misbehaving(pfrom->GetId(), exception.GetNodePenalty());
} }
@ -625,7 +627,8 @@ void CGovernanceManager::Sync(CNode* pfrom, uint256 nProp)
budget object to see if they're OK. If all checks pass, we'll send it to the peer. budget object to see if they're OK. If all checks pass, we'll send it to the peer.
*/ */
int nInvCount = 0; int nObjCount = 0;
int nVoteCount = 0;
// SYNC GOVERNANCE OBJECTS WITH OTHER CLIENT // SYNC GOVERNANCE OBJECTS WITH OTHER CLIENT
@ -643,26 +646,28 @@ void CGovernanceManager::Sync(CNode* pfrom, uint256 nProp)
continue; continue;
} }
LogPrint("gobject", "CGovernanceManager::Sync -- attempting to sync govobj: %s, peer=%d\n", govobj.GetHash().ToString(), pfrom->id); std::string strHash = h.ToString();
LogPrint("gobject", "CGovernanceManager::Sync -- attempting to sync govobj: %s, peer=%d\n", strHash, pfrom->id);
std::string strError; std::string strError;
bool fIsValid = govobj.IsValidLocally(pCurrentBlockIndex, strError, true); bool fIsValid = govobj.IsValidLocally(pCurrentBlockIndex, strError, true);
if(!fIsValid) { if(!fIsValid) {
LogPrintf("CGovernanceManager::Sync -- not syncing invalid govobj: %s, strError = %s, fCachedValid = %d, peer=%d\n", LogPrintf("CGovernanceManager::Sync -- not syncing invalid govobj: %s, strError = %s, fCachedValid = %d, peer=%d\n",
govobj.GetHash().ToString(), strError, govobj.IsSetCachedValid(), pfrom->id); strHash, strError, govobj.IsSetCachedValid(), pfrom->id);
continue; continue;
} }
if(!govobj.IsSetCachedValid()) { if(!govobj.IsSetCachedValid()) {
LogPrintf("CGovernanceManager::Sync -- invalid flag cached, not syncing govobj: %s, fCachedValid = %d, peer=%d\n", LogPrintf("CGovernanceManager::Sync -- invalid flag cached, not syncing govobj: %s, fCachedValid = %d, peer=%d\n",
govobj.GetHash().ToString(), govobj.IsSetCachedValid(), pfrom->id); strHash, govobj.IsSetCachedValid(), pfrom->id);
continue; continue;
} }
// Push the inventory budget proposal message over to the other client // Push the inventory budget proposal message over to the other client
LogPrint("gobject", "CGovernanceManager::Sync -- syncing govobj: %s, peer=%d\n", govobj.GetHash().ToString(), pfrom->id); LogPrint("gobject", "CGovernanceManager::Sync -- syncing govobj: %s, peer=%d\n", strHash, pfrom->id);
pfrom->PushInventory(CInv(MSG_GOVERNANCE_OBJECT, h)); pfrom->PushInventory(CInv(MSG_GOVERNANCE_OBJECT, h));
++nInvCount; ++nObjCount;
std::vector<CGovernanceVote> vecVotes = govobj.GetVoteFile().GetVotes(); std::vector<CGovernanceVote> vecVotes = govobj.GetVoteFile().GetVotes();
for(size_t i = 0; i < vecVotes.size(); ++i) { for(size_t i = 0; i < vecVotes.size(); ++i) {
@ -670,14 +675,15 @@ void CGovernanceManager::Sync(CNode* pfrom, uint256 nProp)
continue; continue;
} }
pfrom->PushInventory(CInv(MSG_GOVERNANCE_OBJECT_VOTE, vecVotes[i].GetHash())); pfrom->PushInventory(CInv(MSG_GOVERNANCE_OBJECT_VOTE, vecVotes[i].GetHash()));
++nInvCount; ++nVoteCount;
} }
} }
fRateChecksEnabled = true; fRateChecksEnabled = true;
} }
pfrom->PushMessage(NetMsgType::SYNCSTATUSCOUNT, MASTERNODE_SYNC_GOVOBJ, nInvCount); pfrom->PushMessage(NetMsgType::SYNCSTATUSCOUNT, MASTERNODE_SYNC_GOVOBJ, nObjCount);
LogPrintf("CGovernanceManager::Sync -- sent %d items, peer=%d\n", nInvCount, pfrom->id); pfrom->PushMessage(NetMsgType::SYNCSTATUSCOUNT, MASTERNODE_SYNC_GOVOBJ_VOTE, nVoteCount);
LogPrintf("CGovernanceManager::Sync -- sent %d objects and %d votes to peer=%d\n", nObjCount, nVoteCount, pfrom->id);
} }
bool CGovernanceManager::MasternodeRateCheck(const CTxIn& vin, int nObjectType) bool CGovernanceManager::MasternodeRateCheck(const CTxIn& vin, int nObjectType)
@ -749,7 +755,7 @@ bool CGovernanceManager::ProcessVote(CNode* pfrom, const CGovernanceVote& vote,
CGovernanceObject& govobj = it->second; CGovernanceObject& govobj = it->second;
bool fOk = govobj.ProcessVote(pfrom, vote, exception); bool fOk = govobj.ProcessVote(pfrom, vote, exception);
if(fOk) { if(fOk) {
mapVoteToObject.Insert(vote.GetHash(), &govobj); mapVoteToObject.Insert(nHashVote, &govobj);
if(govobj.GetObjectType() == GOVERNANCE_OBJECT_WATCHDOG) { if(govobj.GetObjectType() == GOVERNANCE_OBJECT_WATCHDOG) {
mnodeman.UpdateWatchdogVoteTime(vote.GetVinMasternode()); mnodeman.UpdateWatchdogVoteTime(vote.GetVinMasternode());

View File

@ -55,7 +55,7 @@ void CMasternodeSync::Reset()
nTimeAssetSyncStarted = GetTime(); nTimeAssetSyncStarted = GetTime();
nTimeLastMasternodeList = GetTime(); nTimeLastMasternodeList = GetTime();
nTimeLastPaymentVote = GetTime(); nTimeLastPaymentVote = GetTime();
nTimeLastBudgetItem = GetTime(); nTimeLastGovernanceItem = GetTime();
nTimeLastFailure = 0; nTimeLastFailure = 0;
nCountFailures = 0; nCountFailures = 0;
} }
@ -95,7 +95,7 @@ void CMasternodeSync::SwitchToNextAsset()
nRequestedMasternodeAssets = MASTERNODE_SYNC_MNW; nRequestedMasternodeAssets = MASTERNODE_SYNC_MNW;
break; break;
case(MASTERNODE_SYNC_MNW): case(MASTERNODE_SYNC_MNW):
nTimeLastBudgetItem = GetTime(); nTimeLastGovernanceItem = GetTime();
nRequestedMasternodeAssets = MASTERNODE_SYNC_GOVERNANCE; nRequestedMasternodeAssets = MASTERNODE_SYNC_GOVERNANCE;
break; break;
case(MASTERNODE_SYNC_GOVERNANCE): case(MASTERNODE_SYNC_GOVERNANCE):
@ -374,7 +374,7 @@ void CMasternodeSync::ProcessTick()
LogPrint("mnpayments", "CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d nTimeLastPaymentVote %lld GetTime() %lld diff %lld\n", nTick, nRequestedMasternodeAssets, nTimeLastPaymentVote, GetTime(), GetTime() - nTimeLastPaymentVote); LogPrint("mnpayments", "CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d nTimeLastPaymentVote %lld GetTime() %lld diff %lld\n", nTick, nRequestedMasternodeAssets, nTimeLastPaymentVote, GetTime(), GetTime() - nTimeLastPaymentVote);
// check for timeout first // check for timeout first
if(nTimeLastBudgetItem < GetTime() - MASTERNODE_SYNC_TIMEOUT_SECONDS){ if(GetTime() - nTimeLastGovernanceItem > MASTERNODE_SYNC_TIMEOUT_SECONDS) {
LogPrintf("CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d -- timeout\n", nTick, nRequestedMasternodeAssets); LogPrintf("CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d -- timeout\n", nTick, nRequestedMasternodeAssets);
if(nRequestedMasternodeAttempt == 0) { if(nRequestedMasternodeAttempt == 0) {
LogPrintf("CMasternodeSync::ProcessTick -- WARNING: failed to sync %s\n", GetAssetName()); LogPrintf("CMasternodeSync::ProcessTick -- WARNING: failed to sync %s\n", GetAssetName());
@ -420,10 +420,3 @@ void CMasternodeSync::UpdatedBlockTip(const CBlockIndex *pindex)
{ {
pCurrentBlockIndex = pindex; pCurrentBlockIndex = pindex;
} }
void CMasternodeSync::AddedBudgetItem(uint256 hash)
{
// skip this for now
return;
}

View File

@ -18,7 +18,7 @@ static const int MASTERNODE_SYNC_LIST = 2;
static const int MASTERNODE_SYNC_MNW = 3; static const int MASTERNODE_SYNC_MNW = 3;
static const int MASTERNODE_SYNC_GOVERNANCE = 4; static const int MASTERNODE_SYNC_GOVERNANCE = 4;
static const int MASTERNODE_SYNC_GOVOBJ = 10; static const int MASTERNODE_SYNC_GOVOBJ = 10;
static const int MASTERNODE_SYNC_GOVERNANCE_FIN = 11; static const int MASTERNODE_SYNC_GOVOBJ_VOTE = 11;
static const int MASTERNODE_SYNC_FINISHED = 999; static const int MASTERNODE_SYNC_FINISHED = 999;
static const int MASTERNODE_SYNC_TIMEOUT_SECONDS = 30; // our blocks are 2.5 minutes so 30 seconds should be fine static const int MASTERNODE_SYNC_TIMEOUT_SECONDS = 30; // our blocks are 2.5 minutes so 30 seconds should be fine
@ -43,7 +43,7 @@ private:
// Last time when we received some masternode asset ... // Last time when we received some masternode asset ...
int64_t nTimeLastMasternodeList; int64_t nTimeLastMasternodeList;
int64_t nTimeLastPaymentVote; int64_t nTimeLastPaymentVote;
int64_t nTimeLastBudgetItem; int64_t nTimeLastGovernanceItem;
// ... or failed // ... or failed
int64_t nTimeLastFailure; int64_t nTimeLastFailure;
@ -61,7 +61,7 @@ public:
void AddedMasternodeList() { nTimeLastMasternodeList = GetTime(); } void AddedMasternodeList() { nTimeLastMasternodeList = GetTime(); }
void AddedPaymentVote() { nTimeLastPaymentVote = GetTime(); } void AddedPaymentVote() { nTimeLastPaymentVote = GetTime(); }
void AddedBudgetItem(uint256 hash); void AddedGovernanceItem() { nTimeLastGovernanceItem = GetTime(); };
bool IsFailed() { return nRequestedMasternodeAssets == MASTERNODE_SYNC_FAILED; } bool IsFailed() { return nRequestedMasternodeAssets == MASTERNODE_SYNC_FAILED; }
bool IsBlockchainSynced(); bool IsBlockchainSynced();