Merge #911: Fix sync process: (#911)

- mn hash compatibility with 70103
- ignore some requests while syncing
- fix locking/initializing in sync
- do not ban for old mnw
- split budget/governance messages/invs
This commit is contained in:
UdjinM6 2016-08-05 20:25:03 +04:00 committed by Holger Schinzel
parent d2c6b2a74e
commit b4cb1e2610
10 changed files with 199 additions and 157 deletions

View File

@ -43,7 +43,7 @@ CGovernanceVote::CGovernanceVote(CTxIn vinMasternodeIn, uint256 nParentHashIn, i
void CGovernanceVote::Relay() void CGovernanceVote::Relay()
{ {
CInv inv(MSG_GOVERNANCE_VOTE, GetHash()); CInv inv(MSG_GOVERNANCE_OBJECT_VOTE, GetHash());
RelayInv(inv, MSG_GOVERNANCE_PEER_PROTO_VERSION); RelayInv(inv, MSG_GOVERNANCE_PEER_PROTO_VERSION);
} }

View File

@ -103,12 +103,23 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, std::string& strCommand, C
if(fLiteMode) return; if(fLiteMode) return;
if(!masternodeSync.IsBlockchainSynced()) return; if(!masternodeSync.IsBlockchainSynced()) return;
//
// REMOVE AFTER MIGRATION TO 12.1
//
if(pfrom->nVersion < 70201) return;
//
// END REMOVE
//
LOCK(cs_budget); LOCK(cs_budget);
// GOVERANCE SYNCING FUNCTIONALITY // GOVERANCE SYNCING FUNCTIONALITY
if (strCommand == NetMsgType::MNGOVERNANCESYNC) if (strCommand == NetMsgType::MNGOVERNANCESYNC)
{ {
// ignore such request until we are fully synced
if (!masternodeSync.IsSynced()) return;
uint256 nProp; uint256 nProp;
vRecv >> nProp; vRecv >> nProp;
@ -169,15 +180,14 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, std::string& strCommand, C
mapSeenGovernanceObjects.insert(make_pair(govobj.GetHash(), SEEN_OBJECT_IS_VALID)); mapSeenGovernanceObjects.insert(make_pair(govobj.GetHash(), SEEN_OBJECT_IS_VALID));
masternodeSync.AddedBudgetItem(govobj.GetHash()); masternodeSync.AddedBudgetItem(govobj.GetHash());
LogPrintf("Governance object - new! - %s\n", govobj.GetHash().ToString()); LogPrintf("MNGOVERNANCEOBJECT -- %s new\n", govobj.GetHash().ToString());
//We might have active votes for this proposal that are valid now //We might have active votes for this proposal that are valid now
CheckOrphanVotes(); CheckOrphanVotes();
} }
// NEW GOVERNANCE OBJECT VOTE // NEW GOVERNANCE OBJECT VOTE
else if (strCommand == NetMsgType::MNGOVERNANCEVOTE) else if (strCommand == NetMsgType::MNGOVERNANCEOBJECTVOTE)
{ {
CGovernanceVote vote; CGovernanceVote vote;
@ -466,7 +476,7 @@ void CGovernanceManager::Sync(CNode* pfrom, uint256 nProp)
std::map<uint256, CGovernanceVote>::iterator it2 = mapVotesByHash.begin(); std::map<uint256, CGovernanceVote>::iterator it2 = mapVotesByHash.begin();
while(it2 != mapVotesByHash.end()) { while(it2 != mapVotesByHash.end()) {
pfrom->PushInventory(CInv(MSG_GOVERNANCE_VOTE, (*it2).first)); pfrom->PushInventory(CInv(MSG_GOVERNANCE_OBJECT_VOTE, (*it2).first));
nInvCount++; nInvCount++;
++it2; ++it2;
} }

View File

@ -4686,12 +4686,6 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
case MSG_MASTERNODE_WINNER: case MSG_MASTERNODE_WINNER:
return mnpayments.mapMasternodePayeeVotes.count(inv.hash); return mnpayments.mapMasternodePayeeVotes.count(inv.hash);
case MSG_GOVERNANCE_VOTE:
return governance.mapVotesByHash.count(inv.hash);
case MSG_GOVERNANCE_OBJECT:
return governance.mapObjects.count(inv.hash);
case MSG_MASTERNODE_ANNOUNCE: case MSG_MASTERNODE_ANNOUNCE:
return mnodeman.mapSeenMasternodeBroadcast.count(inv.hash); return mnodeman.mapSeenMasternodeBroadcast.count(inv.hash);
@ -4700,7 +4694,14 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
case MSG_DSTX: case MSG_DSTX:
return mapDarksendBroadcastTxes.count(inv.hash); return mapDarksendBroadcastTxes.count(inv.hash);
case MSG_GOVERNANCE_OBJECT:
return governance.mapObjects.count(inv.hash);
case MSG_GOVERNANCE_OBJECT_VOTE:
return governance.mapVotesByHash.count(inv.hash);
} }
// Don't know what it is, just say we already got one // Don't know what it is, just say we already got one
return true; return true;
} }
@ -4862,26 +4863,6 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
} }
} }
if (!pushed && inv.type == MSG_GOVERNANCE_VOTE) {
if(governance.mapVotesByHash.count(inv.hash)) {
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss.reserve(1000);
ss << governance.mapVotesByHash[inv.hash];
pfrom->PushMessage(NetMsgType::MNGOVERNANCEVOTE, ss);
pushed = true;
}
}
if (!pushed && inv.type == MSG_GOVERNANCE_OBJECT) {
if(governance.mapObjects.count(inv.hash)) {
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss.reserve(1000);
ss << governance.mapObjects[inv.hash];
pfrom->PushMessage(NetMsgType::MNGOVERNANCEOBJECT, ss);
pushed = true;
}
}
if (!pushed && inv.type == MSG_MASTERNODE_ANNOUNCE) { if (!pushed && inv.type == MSG_MASTERNODE_ANNOUNCE) {
if(mnodeman.mapSeenMasternodeBroadcast.count(inv.hash)){ if(mnodeman.mapSeenMasternodeBroadcast.count(inv.hash)){
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
@ -4917,6 +4898,25 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
} }
} }
if (!pushed && inv.type == MSG_GOVERNANCE_OBJECT) {
if(governance.mapObjects.count(inv.hash)) {
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss.reserve(1000);
ss << governance.mapObjects[inv.hash];
pfrom->PushMessage(NetMsgType::MNGOVERNANCEOBJECT, ss);
pushed = true;
}
}
if (!pushed && inv.type == MSG_GOVERNANCE_OBJECT_VOTE) {
if(governance.mapVotesByHash.count(inv.hash)) {
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss.reserve(1000);
ss << governance.mapVotesByHash[inv.hash];
pfrom->PushMessage(NetMsgType::MNGOVERNANCEOBJECTVOTE, ss);
pushed = true;
}
}
if (!pushed) if (!pushed)
vNotFound.push_back(inv); vNotFound.push_back(inv);

View File

@ -194,7 +194,9 @@ void CMasternodePayments::ProcessMessage(CNode* pfrom, std::string& strCommand,
if (strCommand == NetMsgType::MNWINNERSSYNC) { //Masternode Payments Request Sync if (strCommand == NetMsgType::MNWINNERSSYNC) { //Masternode Payments Request Sync
if(fLiteMode) return; //disable all Darksend/Masternode related functionality
// ignore such request until we are fully synced
if (!masternodeSync.IsSynced()) return;
int nCountNeeded; int nCountNeeded;
vRecv >> nCountNeeded; vRecv >> nCountNeeded;
@ -220,32 +222,38 @@ void CMasternodePayments::ProcessMessage(CNode* pfrom, std::string& strCommand,
if(!pCurrentBlockIndex) return; if(!pCurrentBlockIndex) return;
if(mapMasternodePayeeVotes.count(winner.GetHash())){ // can't really verify it until masternode list is synced, reject it for now
LogPrint("mnpayments", "mnw - Already seen - %s bestHeight %d\n", winner.GetHash().ToString(), pCurrentBlockIndex->nHeight); if (masternodeSync.RequestedMasternodeAssets < MASTERNODE_SYNC_MNW) return;
if(mapMasternodePayeeVotes.count(winner.GetHash())) {
LogPrint("mnpayments", "MNWINNER -- Already seen: hash=%s, nHeight=%d\n", winner.GetHash().ToString(), pCurrentBlockIndex->nHeight);
masternodeSync.AddedMasternodeWinner(winner.GetHash()); masternodeSync.AddedMasternodeWinner(winner.GetHash());
return; return;
} }
int nFirstBlock = pCurrentBlockIndex->nHeight - (mnodeman.CountEnabled()*1.25); int nFirstBlock = pCurrentBlockIndex->nHeight - mnodeman.CountEnabled()*1.25;
if(winner.nBlockHeight < nFirstBlock || winner.nBlockHeight > pCurrentBlockIndex->nHeight+20){ if(winner.nBlockHeight < nFirstBlock || winner.nBlockHeight > pCurrentBlockIndex->nHeight+20) {
LogPrint("mnpayments", "mnw - winner out of range - FirstBlock %d Height %d bestHeight %d\n", nFirstBlock, winner.nBlockHeight, pCurrentBlockIndex->nHeight); LogPrint("mnpayments", "MNWINNER -- winner out of range: nFirstBlock=%d, nBlockHeight=%d, nHeight=%d\n", nFirstBlock, winner.nBlockHeight, pCurrentBlockIndex->nHeight);
return; return;
} }
std::string strError = ""; std::string strError = "";
if(!winner.IsValid(pfrom, strError)){ if(!winner.IsValid(pfrom, pCurrentBlockIndex->nHeight, strError)) {
if(strError != "") LogPrint("mnpayments", "mnw - invalid message - %s\n", strError); LogPrint("mnpayments", "MNWINNER -- invalid message, error: %s\n", strError);
return; return;
} }
if(!CanVote(winner.vinMasternode.prevout, winner.nBlockHeight)){ if(!CanVote(winner.vinMasternode.prevout, winner.nBlockHeight)){
LogPrintf("mnw - masternode already voted - %s\n", winner.vinMasternode.prevout.ToStringShort()); LogPrintf("MNWINNER -- masternode already voted: prevout=%s\n", winner.vinMasternode.prevout.ToStringShort());
return; return;
} }
if(!winner.SignatureValid()){ if(!winner.SignatureValid()) {
LogPrintf("mnw - invalid signature\n"); // do not ban for old mnw, MN simply might be not active anymore
if(masternodeSync.IsSynced()) Misbehaving(pfrom->GetId(), 20); if(masternodeSync.IsSynced() && winner.nBlockHeight > pCurrentBlockIndex->nHeight) {
LogPrintf("MNWINNER -- invalid signature\n");
Misbehaving(pfrom->GetId(), 20);
}
// it could just be a non-synced masternode // it could just be a non-synced masternode
mnodeman.AskForMN(pfrom, winner.vinMasternode); mnodeman.AskForMN(pfrom, winner.vinMasternode);
return; return;
@ -255,7 +263,7 @@ void CMasternodePayments::ProcessMessage(CNode* pfrom, std::string& strCommand,
ExtractDestination(winner.payee, address1); ExtractDestination(winner.payee, address1);
CBitcoinAddress address2(address1); CBitcoinAddress address2(address1);
LogPrint("mnpayments", "mnw - winning vote - Addr %s Height %d bestHeight %d - %s\n", address2.ToString(), winner.nBlockHeight, pCurrentBlockIndex->nHeight, winner.vinMasternode.prevout.ToStringShort()); LogPrint("mnpayments", "MNWINNER -- winning vote: address=%s, nBlockHeight=%d, nHeight=%d, prevout=%s\n", address2.ToString(), winner.nBlockHeight, pCurrentBlockIndex->nHeight, winner.vinMasternode.prevout.ToStringShort());
if(AddWinningMasternode(winner)){ if(AddWinningMasternode(winner)){
winner.Relay(); winner.Relay();
@ -464,37 +472,34 @@ void CMasternodePayments::CheckAndRemove()
LogPrintf("CMasternodePayments::CleanPaymentList() - %s mapSeenSyncMNW %lld\n", ToString(), masternodeSync.mapSeenSyncMNW.size()); LogPrintf("CMasternodePayments::CleanPaymentList() - %s mapSeenSyncMNW %lld\n", ToString(), masternodeSync.mapSeenSyncMNW.size());
} }
bool CMasternodePaymentWinner::IsValid(CNode* pnode, std::string& strError) bool CMasternodePaymentWinner::IsValid(CNode* pnode, int nValidationHeight, std::string& strError)
{ {
CMasternode* pmn = mnodeman.Find(vinMasternode); CMasternode* pmn = mnodeman.Find(vinMasternode);
if(!pmn) if(!pmn) {
{ strError = strprintf("Unknown Masternode: prevout=%s", vinMasternode.prevout.ToStringShort());
strError = strprintf("Unknown Masternode %s", vinMasternode.prevout.ToStringShort()); // Only ask if we are already synced and still have no idea about that Masternode
LogPrint("mnpayments", "CMasternodePaymentWinner::IsValid - %s\n", strError); if (masternodeSync.IsSynced()) mnodeman.AskForMN(pnode, vinMasternode);
mnodeman.AskForMN(pnode, vinMasternode);
return false; return false;
} }
if(pmn->protocolVersion < MIN_MNW_PEER_PROTO_VERSION) if(pmn->protocolVersion < MIN_MNW_PEER_PROTO_VERSION) {
{ strError = strprintf("Masternode protocol is too old: protocolVersion=%d, MIN_MNW_PEER_PROTO_VERSION=%d", pmn->protocolVersion, MIN_MNW_PEER_PROTO_VERSION);
strError = strprintf("Masternode protocol too old %d - req %d", pmn->protocolVersion, MIN_MNW_PEER_PROTO_VERSION);
LogPrint("mnpayments", "CMasternodePaymentWinner::IsValid - %s\n", strError);
return false; return false;
} }
int n = mnodeman.GetMasternodeRank(vinMasternode, nBlockHeight-100, MIN_MNW_PEER_PROTO_VERSION); int nRank = mnodeman.GetMasternodeRank(vinMasternode, nBlockHeight - 100, MIN_MNW_PEER_PROTO_VERSION);
if(n > MNPAYMENTS_SIGNATURES_TOTAL) if(nRank > MNPAYMENTS_SIGNATURES_TOTAL) {
{ // It's common to have masternodes mistakenly think they are in the top 10
//It's common to have masternodes mistakenly think they are in the top 10 // We don't want to print all of these messages in normal mode, debug mode should print though
// We don't want to print all of these messages, or punish them unless they're way off strError = strprintf("Masternode is not in the top %d (%d)\n", MNPAYMENTS_SIGNATURES_TOTAL, nRank);
if(n > MNPAYMENTS_SIGNATURES_TOTAL*2) // Only ban for new mnw which is out of bounds, for old mnw MN list itself might be way too much off
{ if(nRank > MNPAYMENTS_SIGNATURES_TOTAL*2 && nBlockHeight > nValidationHeight) {
strError = strprintf("Masternode not in the top %d (%d)", MNPAYMENTS_SIGNATURES_TOTAL, n); LogPrintf("CMasternodePaymentWinner::IsValid -- Error: Masternode is not in the top %d (%d)\n", MNPAYMENTS_SIGNATURES_TOTAL*2, nRank);
LogPrint("mnpayments", "CMasternodePaymentWinner::IsValid - %s\n", strError); Misbehaving(pnode->GetId(), 20);
if(masternodeSync.IsSynced()) Misbehaving(pnode->GetId(), 20);
} }
// Still invalid however
return false; return false;
} }

View File

@ -161,7 +161,7 @@ public:
} }
bool Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode); bool Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode);
bool IsValid(CNode* pnode, std::string& strError); bool IsValid(CNode* pnode, int nValidationHeight, std::string& strError);
bool SignatureValid(); bool SignatureValid();
void Relay(); void Relay();

View File

@ -149,6 +149,8 @@ void CMasternodeSync::GetNextAsset()
LogPrintf("CMasternodeSync::GetNextAsset - Sync has finished\n"); LogPrintf("CMasternodeSync::GetNextAsset - Sync has finished\n");
RequestedMasternodeAssets = MASTERNODE_SYNC_FINISHED; RequestedMasternodeAssets = MASTERNODE_SYNC_FINISHED;
uiInterface.NotifyAdditionalDataSyncProgressChanged(1); uiInterface.NotifyAdditionalDataSyncProgressChanged(1);
//try to activate our masternode if possible
activeMasternode.ManageStatus();
break; break;
} }
RequestedMasternodeAttempt = 0; RequestedMasternodeAttempt = 0;
@ -253,20 +255,18 @@ void CMasternodeSync::Process()
} }
// INITIAL SYNC SETUP / LOG REPORTING // INITIAL SYNC SETUP / LOG REPORTING
{ double nSyncProgress = double(RequestedMasternodeAttempt + (RequestedMasternodeAssets - 1) * 8) / (8*4);
double nSyncProgress = double(RequestedMasternodeAttempt + (RequestedMasternodeAssets - 1) * 8) / (8*4); LogPrintf("CMasternodeSync::Process() - tick %d RequestedMasternodeAttempt %d RequestedMasternodeAssets %d nSyncProgress %f\n", tick, RequestedMasternodeAttempt, RequestedMasternodeAssets, nSyncProgress);
LogPrintf("CMasternodeSync::Process() - tick %d RequestedMasternodeAttempt %d RequestedMasternodeAssets %d nSyncProgress %f\n", tick, RequestedMasternodeAttempt, RequestedMasternodeAssets, nSyncProgress); uiInterface.NotifyAdditionalDataSyncProgressChanged(nSyncProgress);
uiInterface.NotifyAdditionalDataSyncProgressChanged(nSyncProgress);
if(RequestedMasternodeAssets == MASTERNODE_SYNC_INITIAL) GetNextAsset(); // sporks synced but blockchain is not, wait until we're almost at a recent block to continue
if(Params().NetworkIDString() != CBaseChainParams::REGTEST &&
!IsBlockchainSynced() && RequestedMasternodeAssets > MASTERNODE_SYNC_SPORKS) return;
// sporks synced but blockchain is not, wait until we're almost at a recent block to continue TRY_LOCK(cs_vNodes, lockRecv);
if(Params().NetworkIDString() != CBaseChainParams::REGTEST && if(!lockRecv) return;
!IsBlockchainSynced() && RequestedMasternodeAssets > MASTERNODE_SYNC_SPORKS) return;
TRY_LOCK(cs_vNodes, lockRecv); if(RequestedMasternodeAssets == MASTERNODE_SYNC_INITIAL) GetNextAsset();
if(!lockRecv) return;
}
BOOST_FOREACH(CNode* pnode, vNodes) BOOST_FOREACH(CNode* pnode, vNodes)
{ {
@ -293,91 +293,103 @@ void CMasternodeSync::Process()
{ {
// SPORK : ALWAYS ASK FOR SPORKS AS WE SYNC (we skip this mode now) // SPORK : ALWAYS ASK FOR SPORKS AS WE SYNC (we skip this mode now)
if(!pnode->HasFulfilledRequest("spork-sync")) if(!pnode->HasFulfilledRequest("spork-sync")) {
{ // only request once from each peer
pnode->FulfilledRequest("spork-sync"); pnode->FulfilledRequest("spork-sync");
// get current network sporks // get current network sporks
pnode->PushMessage(NetMsgType::GETSPORKS); pnode->PushMessage(NetMsgType::GETSPORKS);
// we always ask for sporks, so just skip this // we always ask for sporks, so just skip this
if(RequestedMasternodeAssets == MASTERNODE_SYNC_SPORKS){ if(RequestedMasternodeAssets == MASTERNODE_SYNC_SPORKS) GetNextAsset();
GetNextAsset();
return; continue; // always get sporks first, switch to the next node without waiting for the next tick
}
} }
// MNLIST : SYNC MASTERNODE LIST FROM OTHER CONNECTED CLIENTS // MNLIST : SYNC MASTERNODE LIST FROM OTHER CONNECTED CLIENTS
if(RequestedMasternodeAssets == MASTERNODE_SYNC_LIST) if(RequestedMasternodeAssets == MASTERNODE_SYNC_LIST) {
{ // check for timeout first
if (pnode->nVersion < mnpayments.GetMinMasternodePaymentsProto()) continue; if(lastMasternodeList < GetTime() - MASTERNODE_SYNC_TIMEOUT) {
LogPrintf("CMasternodeSync::Process -- tick %d asset %d -- timeout\n", tick, RequestedMasternodeAssets);
// shall we move onto the next asset? if(RequestedMasternodeAttempt == 0)
if(nMnCount > mnodeman.GetEstimatedMasternodes(pCurrentBlockIndex->nHeight)*0.9) LogPrintf("CMasternodeSync::Process -- WARNING: failed to sync %s\n", GetAssetName());
{
GetNextAsset(); GetNextAsset();
return; return;
} }
if(lastMasternodeList < GetTime() - MASTERNODE_SYNC_TIMEOUT){ //hasn't received a new item in the last five seconds, so we'll move to the // check for data
// if we have enough masternodes in or list, switch to the next asset
/* Note: Is this activing up? It's probably related to int CMasternodeMan::GetEstimatedMasternodes(int nBlock)
Surely doesn't work right for testnet currently */
// try to fetch data from at least one peer though
if(RequestedMasternodeAssets > 0 && nMnCount > mnodeman.GetEstimatedMasternodes(pCurrentBlockIndex->nHeight)*0.9) {
LogPrintf("CMasternodeSync::Process -- tick %d asset %d -- found enough data\n", tick, RequestedMasternodeAssets);
GetNextAsset(); GetNextAsset();
return; return;
} }
// requesting is the last thing we do (incase we needed to move to the next asset and we've requested from each peer already) // only request once from each peer
if(pnode->HasFulfilledRequest("masternode-sync")) continue; if(pnode->HasFulfilledRequest("masternode-sync")) continue;
pnode->FulfilledRequest("masternode-sync"); pnode->FulfilledRequest("masternode-sync");
//see if we've synced the masternode list if (pnode->nVersion < mnpayments.GetMinMasternodePaymentsProto()) continue;
/* note: Is this activing up? It's probably related to int CMasternodeMan::GetEstimatedMasternodes(int nBlock) */ RequestedMasternodeAttempt++;
mnodeman.DsegUpdate(pnode); mnodeman.DsegUpdate(pnode);
RequestedMasternodeAttempt++;
return; //this will cause each peer to get one request each six seconds for the various assets we need return; //this will cause each peer to get one request each six seconds for the various assets we need
} }
// MNW : SYNC MASTERNODE WINNERS FROM OTHER CONNECTED CLIENTS // MNW : SYNC MASTERNODE WINNERS FROM OTHER CONNECTED CLIENTS
if(RequestedMasternodeAssets == MASTERNODE_SYNC_MNW) if(RequestedMasternodeAssets == MASTERNODE_SYNC_MNW) {
{ // check for timeout first
if (pnode->nVersion < mnpayments.GetMinMasternodePaymentsProto()) continue; // This might take a lot longer than MASTERNODE_SYNC_TIMEOUT minutes due to new blocks,
// but that should be OK and it should timeout eventually.
// Shall we move onto the next asset? if(lastMasternodeWinner < GetTime() - MASTERNODE_SYNC_TIMEOUT) {
// -- LogPrintf("CMasternodeSync::Process -- tick %d asset %d -- timeout\n", tick, RequestedMasternodeAssets);
// This might take a lot longer than 2 minutes due to new blocks, but that's OK. It will eventually time out if needed if(RequestedMasternodeAttempt == 0)
if(lastMasternodeWinner < GetTime() - MASTERNODE_SYNC_TIMEOUT){ //hasn't received a new item in the last five seconds, so we'll move to the LogPrintf("CMasternodeSync::Process -- WARNING: failed to sync %s\n", GetAssetName());
GetNextAsset(); GetNextAsset();
return; return;
} }
// check for data
// if mnpayments already has enough blocks and votes, move to the next asset // if mnpayments already has enough blocks and votes, move to the next asset
if(mnpayments.IsEnoughData(nMnCount)) { // try to fetch data from at least one peer though
if(RequestedMasternodeAssets > 0 && mnpayments.IsEnoughData(nMnCount)) {
LogPrintf("CMasternodeSync::Process -- tick %d asset %d -- found enough data\n", tick, RequestedMasternodeAssets);
GetNextAsset(); GetNextAsset();
return; return;
} }
// requesting is the last thing we do (incase we needed to move to the next asset and we've requested from each peer already) // only request once from each peer
if(pnode->HasFulfilledRequest("masternode-winner-sync")) continue; if(pnode->HasFulfilledRequest("masternode-winner-sync")) continue;
pnode->FulfilledRequest("masternode-winner-sync"); pnode->FulfilledRequest("masternode-winner-sync");
pnode->PushMessage(NetMsgType::MNWINNERSSYNC, nMnCount); //sync payees if (pnode->nVersion < mnpayments.GetMinMasternodePaymentsProto()) continue;
RequestedMasternodeAttempt++; RequestedMasternodeAttempt++;
pnode->PushMessage(NetMsgType::MNWINNERSSYNC, nMnCount); //sync payees
return; //this will cause each peer to get one request each six seconds for the various assets we need return; //this will cause each peer to get one request each six seconds for the various assets we need
} }
// GOVOBJ : SYNC GOVERNANCE ITEMS FROM OUR PEERS // GOVOBJ : SYNC GOVERNANCE ITEMS FROM OUR PEERS
if(RequestedMasternodeAssets == MASTERNODE_SYNC_GOVERNANCE){ if(RequestedMasternodeAssets == MASTERNODE_SYNC_GOVERNANCE) {
if (pnode->nVersion < MSG_GOVERNANCE_PEER_PROTO_VERSION) continue; // check for timeout first
if(lastBudgetItem < GetTime() - MASTERNODE_SYNC_TIMEOUT){
LogPrintf("CMasternodeSync::Process -- tick %d asset %d -- timeout\n", tick, RequestedMasternodeAssets);
if(RequestedMasternodeAttempt == 0)
LogPrintf("CMasternodeSync::Process -- WARNING: failed to sync %s\n", GetAssetName());
GetNextAsset();
return;
}
// check for data
// shall we move onto the next asset
// if(countBudgetItemProp > 0 && countBudgetItemFin) // if(countBudgetItemProp > 0 && countBudgetItemFin)
// { // {
// if(governance.CountProposalInventoryItems() >= (sumBudgetItemProp / countBudgetItemProp)*0.9) // if(governance.CountProposalInventoryItems() >= (sumBudgetItemProp / countBudgetItemProp)*0.9)
@ -390,24 +402,17 @@ void CMasternodeSync::Process()
// } // }
// } // }
//we'll start rejecting votes if we accidentally get set as synced too soon, this allows plenty of time if (pnode->nVersion < MSG_GOVERNANCE_PEER_PROTO_VERSION) continue;
if(lastBudgetItem < GetTime() - MASTERNODE_SYNC_TIMEOUT){
GetNextAsset();
//try to activate our masternode if possible
activeMasternode.ManageStatus();
return;
}
// requesting is the last thing we do, incase we needed to move to the next asset and we've requested from each peer already
// only request once from each peer
if(pnode->HasFulfilledRequest("governance-sync")) continue; if(pnode->HasFulfilledRequest("governance-sync")) continue;
pnode->FulfilledRequest("governance-sync"); pnode->FulfilledRequest("governance-sync");
uint256 n = uint256(); if (pnode->nVersion < MSG_GOVERNANCE_PEER_PROTO_VERSION) continue;
pnode->PushMessage(NetMsgType::MNGOVERNANCESYNC, n); //sync masternode votes
RequestedMasternodeAttempt++; RequestedMasternodeAttempt++;
pnode->PushMessage(NetMsgType::MNGOVERNANCESYNC, uint256()); //sync masternode votes
return; //this will cause each peer to get one request each six seconds for the various assets we need return; //this will cause each peer to get one request each six seconds for the various assets we need
} }
} }

View File

@ -317,9 +317,20 @@ public:
uint256 GetHash(){ uint256 GetHash(){
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION); CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
ss << vin; //
ss << pubkey; // REMOVE AFTER MIGRATION TO 12.1
ss << sigTime; //
if(protocolVersion < 70201) {
ss << sigTime;
ss << pubkey;
} else {
//
// END REMOVE
//
ss << vin;
ss << pubkey;
ss << sigTime;
}
return ss.GetHash(); return ss.GetHash();
} }

View File

@ -586,6 +586,9 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
} else if (strCommand == NetMsgType::DSEG) { //Get Masternode list or specific entry } else if (strCommand == NetMsgType::DSEG) { //Get Masternode list or specific entry
// ignore such request until we are fully synced
if (!masternodeSync.IsSynced()) return;
CTxIn vin; CTxIn vin;
vRecv >> vin; vRecv >> vin;

View File

@ -43,11 +43,11 @@ const char *GETSPORKS="getsporks";
const char *MNWINNER="mnw"; const char *MNWINNER="mnw";
const char *MNWINNERSSYNC="mnget"; const char *MNWINNERSSYNC="mnget";
const char *MNSCANERROR="mn scan error"; // not implemented const char *MNSCANERROR="mn scan error"; // not implemented
const char *MNGOVERNANCESYNC="mnvs"; const char *MNBUDGETSYNC="mnvs"; // depreciated since 12.1
const char *MNGOVERNANCEVOTE="mvote"; const char *MNBUDGETVOTE="mvote"; // depreciated since 12.1
const char *MNGOVERNANCEOBJECT="mprop"; const char *MNBUDGETPROPOSAL="mprop"; // depreciated since 12.1
const char *MNGOVERNANCEFINAL="fbs"; const char *MNBUDGETFINAL="fbs"; // depreciated since 12.1
const char *MNGOVERNANCEFINALVOTE="fbvote"; const char *MNBUDGETFINALVOTE="fbvote"; // depreciated since 12.1
const char *MNQUORUM="mn quorum"; // not implemented const char *MNQUORUM="mn quorum"; // not implemented
const char *MNANNOUNCE="mnb"; const char *MNANNOUNCE="mnb";
const char *MNPING="mnp"; const char *MNPING="mnp";
@ -61,6 +61,9 @@ const char *DSTX="dstx";
const char *DSQUEUE="dsq"; const char *DSQUEUE="dsq";
const char *DSEG="dseg"; const char *DSEG="dseg";
const char *SYNCSTATUSCOUNT="ssc"; const char *SYNCSTATUSCOUNT="ssc";
const char *MNGOVERNANCESYNC="govsync";
const char *MNGOVERNANCEOBJECT="govobj";
const char *MNGOVERNANCEOBJECTVOTE="govobjvote";
}; };
static const char* ppszTypeName[] = static const char* ppszTypeName[] =
@ -69,20 +72,23 @@ static const char* ppszTypeName[] =
NetMsgType::TX, NetMsgType::TX,
NetMsgType::BLOCK, NetMsgType::BLOCK,
"filtered block", // Should never occur "filtered block", // Should never occur
// Dash message types // Dash message types
// NOTE: include non-implmented here, we must keep this list in sync with enum in protocol.h
NetMsgType::IX, NetMsgType::IX,
NetMsgType::IXLOCKVOTE, NetMsgType::IXLOCKVOTE,
NetMsgType::SPORK, NetMsgType::SPORK,
NetMsgType::MNWINNER, NetMsgType::MNWINNER,
NetMsgType::MNSCANERROR, // not implemented NetMsgType::MNSCANERROR, // not implemented
NetMsgType::MNGOVERNANCEVOTE, NetMsgType::MNBUDGETVOTE, // depreciated since 12.1
NetMsgType::MNGOVERNANCEOBJECT, NetMsgType::MNBUDGETPROPOSAL, // depreciated since 12.1
NetMsgType::MNGOVERNANCEFINAL, NetMsgType::MNBUDGETFINAL, // depreciated since 12.1
NetMsgType::MNGOVERNANCEFINALVOTE, NetMsgType::MNBUDGETFINALVOTE, // depreciated since 12.1
NetMsgType::MNQUORUM, // not implemented NetMsgType::MNQUORUM, // not implemented
NetMsgType::MNANNOUNCE, NetMsgType::MNANNOUNCE,
NetMsgType::MNPING, NetMsgType::MNPING,
NetMsgType::DSTX NetMsgType::DSTX,
NetMsgType::MNGOVERNANCEOBJECT,
NetMsgType::MNGOVERNANCEOBJECTVOTE
}; };
/** All known message types. Keep this in the same order as the list of /** All known message types. Keep this in the same order as the list of
@ -111,18 +117,14 @@ const static std::string allNetMessageTypes[] = {
NetMsgType::FILTERCLEAR, NetMsgType::FILTERCLEAR,
NetMsgType::REJECT, NetMsgType::REJECT,
NetMsgType::SENDHEADERS, NetMsgType::SENDHEADERS,
// Dash message types // Dash message types
// NOTE: do NOT include non-implmented here, we want them to be "Unknown command" in ProcessMessage()
NetMsgType::IX, NetMsgType::IX,
NetMsgType::IXLOCKVOTE, NetMsgType::IXLOCKVOTE,
NetMsgType::SPORK, NetMsgType::SPORK,
NetMsgType::GETSPORKS, NetMsgType::GETSPORKS,
NetMsgType::MNWINNER, NetMsgType::MNWINNER,
NetMsgType::MNWINNERSSYNC, NetMsgType::MNWINNERSSYNC,
NetMsgType::MNGOVERNANCESYNC,
NetMsgType::MNGOVERNANCEVOTE,
NetMsgType::MNGOVERNANCEOBJECT,
NetMsgType::MNGOVERNANCEFINAL,
NetMsgType::MNGOVERNANCEFINALVOTE,
NetMsgType::MNANNOUNCE, NetMsgType::MNANNOUNCE,
NetMsgType::MNPING, NetMsgType::MNPING,
NetMsgType::DSACCEPT, NetMsgType::DSACCEPT,
@ -134,7 +136,10 @@ const static std::string allNetMessageTypes[] = {
NetMsgType::DSTX, NetMsgType::DSTX,
NetMsgType::DSQUEUE, NetMsgType::DSQUEUE,
NetMsgType::DSEG, NetMsgType::DSEG,
NetMsgType::SYNCSTATUSCOUNT NetMsgType::SYNCSTATUSCOUNT,
NetMsgType::MNGOVERNANCESYNC,
NetMsgType::MNGOVERNANCEOBJECT,
NetMsgType::MNGOVERNANCEOBJECTVOTE
}; };
const static std::vector<std::string> allNetMessageTypesVec(allNetMessageTypes, allNetMessageTypes+ARRAYLEN(allNetMessageTypes)); const static std::vector<std::string> allNetMessageTypesVec(allNetMessageTypes, allNetMessageTypes+ARRAYLEN(allNetMessageTypes));

View File

@ -220,6 +220,7 @@ extern const char *REJECT;
extern const char *SENDHEADERS; extern const char *SENDHEADERS;
// Dash message types // Dash message types
// NOTE: do NOT declare non-implmented here, we don't want them to be exposed to the outside
// TODO: add description // TODO: add description
extern const char *IX; extern const char *IX;
extern const char *IXLOCKVOTE; extern const char *IXLOCKVOTE;
@ -227,11 +228,6 @@ extern const char *SPORK;
extern const char *GETSPORKS; extern const char *GETSPORKS;
extern const char *MNWINNER; extern const char *MNWINNER;
extern const char *MNWINNERSSYNC; extern const char *MNWINNERSSYNC;
extern const char *MNGOVERNANCESYNC;
extern const char *MNGOVERNANCEVOTE;
extern const char *MNGOVERNANCEOBJECT;
extern const char *MNGOVERNANCEFINAL;
extern const char *MNGOVERNANCEFINALVOTE;
extern const char *MNANNOUNCE; extern const char *MNANNOUNCE;
extern const char *MNPING; extern const char *MNPING;
extern const char *DSACCEPT; extern const char *DSACCEPT;
@ -244,6 +240,9 @@ extern const char *DSTX;
extern const char *DSQUEUE; extern const char *DSQUEUE;
extern const char *DSEG; extern const char *DSEG;
extern const char *SYNCSTATUSCOUNT; extern const char *SYNCSTATUSCOUNT;
extern const char *MNGOVERNANCESYNC;
extern const char *MNGOVERNANCEOBJECT;
extern const char *MNGOVERNANCEOBJECTVOTE;
}; };
/* Get a vector of all valid message types (see above) */ /* Get a vector of all valid message types (see above) */
@ -343,17 +342,21 @@ enum {
MSG_FILTERED_BLOCK, MSG_FILTERED_BLOCK,
MSG_TXLOCK_REQUEST, MSG_TXLOCK_REQUEST,
MSG_TXLOCK_VOTE, MSG_TXLOCK_VOTE,
// Dash message types
// NOTE: declare non-implmented here, we must keep this enum consistent and backwards compatible
MSG_SPORK, MSG_SPORK,
MSG_MASTERNODE_WINNER, MSG_MASTERNODE_WINNER,
MSG_MASTERNODE_SCANNING_ERROR, // not implemented MSG_MASTERNODE_SCANNING_ERROR, // not implemented
MSG_GOVERNANCE_VOTE, MSG_BUDGET_VOTE, // depreciated since 12.1
MSG_GOVERNANCE_OBJECT, MSG_BUDGET_PROPOSAL, // depreciated since 12.1
MSG_BUDGET_FINALIZED, MSG_BUDGET_FINALIZED, // depreciated since 12.1
MSG_BUDGET_FINALIZED_VOTE, MSG_BUDGET_FINALIZED_VOTE, // depreciated since 12.1
MSG_MASTERNODE_QUORUM, // not implemented MSG_MASTERNODE_QUORUM, // not implemented
MSG_MASTERNODE_ANNOUNCE, MSG_MASTERNODE_ANNOUNCE,
MSG_MASTERNODE_PING, MSG_MASTERNODE_PING,
MSG_DSTX MSG_DSTX,
MSG_GOVERNANCE_OBJECT,
MSG_GOVERNANCE_OBJECT_VOTE
}; };
#endif // BITCOIN_PROTOCOL_H #endif // BITCOIN_PROTOCOL_H