diff --git a/configure.ac b/configure.ac index 24cae2ce2d..69cdb53e04 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 0) define(_CLIENT_VERSION_MINOR, 12) define(_CLIENT_VERSION_REVISION, 0) -define(_CLIENT_VERSION_BUILD, 28) +define(_CLIENT_VERSION_BUILD, 29) define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2015) AC_INIT([Dash Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[info@dashpay.io],[dash]) diff --git a/src/activemasternode.cpp b/src/activemasternode.cpp index fa4c56e5dc..ff6552feb5 100644 --- a/src/activemasternode.cpp +++ b/src/activemasternode.cpp @@ -17,7 +17,7 @@ void CActiveMasternode::ManageStatus() if (fDebug) LogPrintf("CActiveMasternode::ManageStatus() - Begin\n"); //need correct blocks to send ping - if(!masternodeSync.IsSynced()) { + if(Params().NetworkID() != CBaseChainParams::REGTEST && !masternodeSync.IsSynced()) { status = ACTIVE_MASTERNODE_SYNC_IN_PROCESS; LogPrintf("CActiveMasternode::ManageStatus() - %s\n", GetStatus()); return; diff --git a/src/clientversion.h b/src/clientversion.h index d652249655..f0138c8187 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -17,7 +17,7 @@ #define CLIENT_VERSION_MAJOR 0 #define CLIENT_VERSION_MINOR 12 #define CLIENT_VERSION_REVISION 0 -#define CLIENT_VERSION_BUILD 28 +#define CLIENT_VERSION_BUILD 29 //! Set to true for release, false for prerelease or test build #define CLIENT_VERSION_IS_RELEASE true diff --git a/src/instantx.h b/src/instantx.h index 2b44e069cc..e89328812a 100644 --- a/src/instantx.h +++ b/src/instantx.h @@ -15,7 +15,11 @@ /* At 15 signatures, 1/2 of the masternode network can be owned by one party without comprimising the security of InstantX - (1000/2150.0)**15 = 1.031e-05 + (1000/2150.0)**10 = 0.00047382219560689856 + (1000/2900.0)**10 = 2.3769498616783657e-05 + + ### getting 5 of 10 signatures w/ 1000 nodes of 2900 + (1000/2900.0)**5 = 0.004875397277841433 */ #define INSTANTX_SIGNATURES_REQUIRED 5 #define INSTANTX_SIGNATURES_TOTAL 10 @@ -27,7 +31,7 @@ class CConsensusVote; class CTransaction; class CTransactionLock; -static const int MIN_INSTANTX_PROTO_VERSION = 70096; +static const int MIN_INSTANTX_PROTO_VERSION = 70097; extern map mapTxLockReq; extern map mapTxLockReqRejected; diff --git a/src/main.cpp b/src/main.cpp index 5c907f6ca0..26ba00e0bb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3266,6 +3266,17 @@ bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDis darkSendPool.NewBlock(); masternodePayments.ProcessBlock(GetHeight()+10); budget.NewBlock(); + + //allow clients to ask for syncing again if they need it + if(GetHeight() % 100 == 0) { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) { + pnode->ClearFulfilledRequest("getspork"); + pnode->ClearFulfilledRequest("mnsync"); + pnode->ClearFulfilledRequest("mnwsync"); + pnode->ClearFulfilledRequest("busync"); + } + } } } @@ -3970,25 +3981,25 @@ bool static AlreadyHave(const CInv& inv) } return false; case MSG_BUDGET_VOTE: - if(mapSeenMasternodeBudgetVotes.count(inv.hash)) { + if(budget.mapSeenMasternodeBudgetVotes.count(inv.hash)) { masternodeSync.AddedBudgetItem(); return true; } return false; case MSG_BUDGET_PROPOSAL: - if(mapSeenMasternodeBudgetProposals.count(inv.hash)) { + if(budget.mapSeenMasternodeBudgetProposals.count(inv.hash)) { masternodeSync.AddedBudgetItem(); return true; } return false; case MSG_BUDGET_FINALIZED_VOTE: - if(mapSeenFinalizedBudgetVotes.count(inv.hash)) { + if(budget.mapSeenFinalizedBudgetVotes.count(inv.hash)) { masternodeSync.AddedBudgetItem(); return true; } return false; case MSG_BUDGET_FINALIZED: - if(mapSeenFinalizedBudgets.count(inv.hash)) { + if(budget.mapSeenFinalizedBudgets.count(inv.hash)) { masternodeSync.AddedBudgetItem(); return true; } @@ -4161,40 +4172,40 @@ void static ProcessGetData(CNode* pfrom) } } if (!pushed && inv.type == MSG_BUDGET_VOTE) { - if(mapSeenMasternodeBudgetVotes.count(inv.hash)){ + if(budget.mapSeenMasternodeBudgetVotes.count(inv.hash)){ CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss.reserve(1000); - ss << mapSeenMasternodeBudgetVotes[inv.hash]; + ss << budget.mapSeenMasternodeBudgetVotes[inv.hash]; pfrom->PushMessage("mvote", ss); pushed = true; } } if (!pushed && inv.type == MSG_BUDGET_PROPOSAL) { - if(mapSeenMasternodeBudgetProposals.count(inv.hash)){ + if(budget.mapSeenMasternodeBudgetProposals.count(inv.hash)){ CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss.reserve(1000); - ss << mapSeenMasternodeBudgetProposals[inv.hash]; + ss << budget.mapSeenMasternodeBudgetProposals[inv.hash]; pfrom->PushMessage("mprop", ss); pushed = true; } } if (!pushed && inv.type == MSG_BUDGET_FINALIZED_VOTE) { - if(mapSeenFinalizedBudgetVotes.count(inv.hash)){ + if(budget.mapSeenFinalizedBudgetVotes.count(inv.hash)){ CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss.reserve(1000); - ss << mapSeenFinalizedBudgetVotes[inv.hash]; + ss << budget.mapSeenFinalizedBudgetVotes[inv.hash]; pfrom->PushMessage("fbvote", ss); pushed = true; } } if (!pushed && inv.type == MSG_BUDGET_FINALIZED) { - if(mapSeenFinalizedBudgets.count(inv.hash)){ + if(budget.mapSeenFinalizedBudgets.count(inv.hash)){ CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss.reserve(1000); - ss << mapSeenFinalizedBudgets[inv.hash]; + ss << budget.mapSeenFinalizedBudgets[inv.hash]; pfrom->PushMessage("fbs", ss); pushed = true; } @@ -4818,7 +4829,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (state.IsInvalid(nDoS)) { if (nDoS > 0) Misbehaving(pfrom->GetId(), nDoS); - return error("invalid header received"); + std::string strError = "invalid header received " + header.GetHash().ToString(); + return error(strError.c_str()); } } } diff --git a/src/masternode-budget.cpp b/src/masternode-budget.cpp index dd9a6737c9..08fcf3265b 100644 --- a/src/masternode-budget.cpp +++ b/src/masternode-budget.cpp @@ -18,13 +18,6 @@ CBudgetManager budget; CCriticalSection cs_budget; -std::map mapSeenMasternodeBudgetProposals; -std::map mapSeenMasternodeBudgetVotes; -std::map mapOrphanMasternodeBudgetVotes; -std::map mapSeenFinalizedBudgets; -std::map mapSeenFinalizedBudgetVotes; -std::map mapOrphanFinalizedBudgetVotes; - std::map askedForSourceProposalOrBudget; int nSubmittedFinalBudget; @@ -514,6 +507,19 @@ bool CBudgetManager::IsBudgetPaymentBlock(int nBlockHeight){ return false; } +bool CBudgetManager::HasNextFinalizedBudget() +{ + CBlockIndex* pindexPrev = chainActive.Tip(); + if(!pindexPrev) return false; + + int nBlockStart = pindexPrev->nHeight - pindexPrev->nHeight % GetBudgetPaymentCycleBlocks() + GetBudgetPaymentCycleBlocks(); + if(nBlockStart - pindexPrev->nHeight > 576*2) return false; //we wouldn't have the budget yet + + if(budget.IsBudgetPaymentBlock(nBlockStart)) return true; + + return false; +} + bool CBudgetManager::IsTransactionValid(const CTransaction& txNew, int nBlockHeight) { int nHighestCount = 0; @@ -771,7 +777,6 @@ void CBudgetManager::ProcessMessage(CNode* pfrom, std::string& strCommand, CData uint256 nProp; vRecv >> nProp; - if(Params().NetworkID() == CBaseChainParams::MAIN){ if(pfrom->HasFulfilledRequest("mnvs")) { LogPrintf("mnvs - peer already asked me for the list\n"); @@ -810,6 +815,8 @@ void CBudgetManager::ProcessMessage(CNode* pfrom, std::string& strCommand, CData budgetProposalBroadcast.Relay(); masternodeSync.AddedBudgetItem(); + LogPrintf("mprop - new budget - %s\n", budgetProposalBroadcast.GetHash().ToString()); + //We might have active votes for this proposal that are valid now CheckOrphanVotes(); } @@ -843,6 +850,8 @@ void CBudgetManager::ProcessMessage(CNode* pfrom, std::string& strCommand, CData vote.Relay(); if(!masternodeSync.IsSynced()) pmn->nVotedTimes++; masternodeSync.AddedBudgetItem(); + + LogPrintf("mvote - new budget vote - %s\n", vote.GetHash().ToString()); } else { LogPrintf("mvote - masternode can't vote again - vin: %s\n", pmn->vin.ToString()); return; @@ -871,6 +880,8 @@ void CBudgetManager::ProcessMessage(CNode* pfrom, std::string& strCommand, CData return; } + LogPrintf("fbs - new finalized budget - %s\n", finalizedBudgetBroadcast.GetHash().ToString()); + CFinalizedBudget finalizedBudget(finalizedBudgetBroadcast); AddFinalizedBudget(finalizedBudget); finalizedBudgetBroadcast.Relay(); @@ -908,6 +919,9 @@ void CBudgetManager::ProcessMessage(CNode* pfrom, std::string& strCommand, CData vote.Relay(); if(!masternodeSync.IsSynced()) pmn->nVotedTimes++; masternodeSync.AddedBudgetItem(); + + if(fDebug) LogPrintf("fbs - new finalized budget vote - %s\n", vote.GetHash().ToString()); + } else { LogPrintf("fbvote - masternode can't vote again - vin: %s\n", pmn->vin.ToString()); return; @@ -953,7 +967,6 @@ void CBudgetManager::Sync(CNode* pfrom, uint256 nProp) ++it1; } - std::map::iterator it3 = mapSeenFinalizedBudgets.begin(); while(it3 != mapSeenFinalizedBudgets.end()){ CFinalizedBudget* pfinalizedBudget = FindFinalizedBudget((*it3).first); @@ -1576,7 +1589,7 @@ void CFinalizedBudget::SubmitVote() return; } - mapSeenFinalizedBudgetVotes.insert(make_pair(vote.GetHash(), vote)); + budget.mapSeenFinalizedBudgetVotes.insert(make_pair(vote.GetHash(), vote)); vote.Relay(); budget.UpdateFinalizedBudget(vote, NULL); } @@ -1690,7 +1703,11 @@ std::string CBudgetManager::ToString() const std::ostringstream info; info << "Proposals: " << (int)mapProposals.size() << - ", Budgets: " << (int)mapFinalizedBudgets.size(); + ", Budgets: " << (int)mapFinalizedBudgets.size() << + ", Seen Budgets: " << (int)mapSeenMasternodeBudgetProposals.size() << + ", Seen Budget Votes: " << (int)mapSeenMasternodeBudgetVotes.size() << + ", Seen Final Budgets: " << (int)mapSeenFinalizedBudgets.size() << + ", Seen Final Budget Votes: " << (int)mapSeenFinalizedBudgetVotes.size(); return info.str(); } diff --git a/src/masternode-budget.h b/src/masternode-budget.h index 2801631aa0..1080e640c5 100644 --- a/src/masternode-budget.h +++ b/src/masternode-budget.h @@ -33,11 +33,6 @@ class CTxBudgetPayment; static const CAmount BUDGET_FEE_TX = (0.5*COIN); static const int64_t BUDGET_FEE_CONFIRMATIONS = 6; -extern std::map mapSeenMasternodeBudgetProposals; -extern std::map mapSeenMasternodeBudgetVotes; -extern std::map mapSeenFinalizedBudgets; -extern std::map mapSeenFinalizedBudgetVotes; - extern CBudgetManager budget; void DumpBudgets(); @@ -88,6 +83,13 @@ public: map mapProposals; map mapFinalizedBudgets; + std::map mapSeenMasternodeBudgetProposals; + std::map mapSeenMasternodeBudgetVotes; + std::map mapOrphanMasternodeBudgetVotes; + std::map mapSeenFinalizedBudgets; + std::map mapSeenFinalizedBudgetVotes; + std::map mapOrphanFinalizedBudgetVotes; + CBudgetManager() { mapProposals.clear(); mapFinalizedBudgets.clear(); @@ -114,6 +116,7 @@ public: void AddProposal(CBudgetProposal& budgetProposal); void AddFinalizedBudget(CFinalizedBudget& finalizedBudget); void SubmitFinalBudget(); + bool HasNextFinalizedBudget(); bool UpdateProposal(CBudgetVote& vote, CNode* pfrom); bool UpdateFinalizedBudget(CFinalizedBudgetVote& vote, CNode* pfrom); @@ -131,6 +134,8 @@ public: mapSeenMasternodeBudgetVotes.clear(); mapSeenFinalizedBudgets.clear(); mapSeenFinalizedBudgetVotes.clear(); + mapOrphanMasternodeBudgetVotes.clear(); + mapOrphanFinalizedBudgetVotes.clear(); } void CheckAndRemove(); std::string ToString() const; @@ -144,6 +149,8 @@ public: READWRITE(mapSeenMasternodeBudgetVotes); READWRITE(mapSeenFinalizedBudgets); READWRITE(mapSeenFinalizedBudgetVotes); + READWRITE(mapOrphanMasternodeBudgetVotes); + READWRITE(mapOrphanFinalizedBudgetVotes); READWRITE(mapProposals); READWRITE(mapFinalizedBudgets); diff --git a/src/masternode-sync.cpp b/src/masternode-sync.cpp index 167ee3d223..3f9244156f 100644 --- a/src/masternode-sync.cpp +++ b/src/masternode-sync.cpp @@ -5,6 +5,7 @@ #include "main.h" #include "masternode-sync.h" #include "masternode-payments.h" +#include "masternode-budget.h" #include "masternode.h" #include "masternodeman.h" #include "util.h" @@ -47,6 +48,7 @@ void CMasternodeSync::GetNextAsset() switch(RequestedMasternodeAssets) { case(MASTERNODE_SYNC_INITIAL): + case(MASTERNODE_SYNC_FAILED): lastMasternodeList = 0; lastMasternodeWinner = 0; lastBudgetItem = 0; @@ -97,6 +99,13 @@ void CMasternodeSync::Process() return; } + //try syncing again in an hour + if(RequestedMasternodeAssets == MASTERNODE_SYNC_FAILED && lastFailure + (60*60) < GetTime()) { + GetNextAsset(); + } else if (RequestedMasternodeAssets == MASTERNODE_SYNC_FAILED) { + return; + } + if(fDebug) LogPrintf("CMasternodeSync::Process() - tick %d RequestedMasternodeAssets %d\n", tick, RequestedMasternodeAssets); if(RequestedMasternodeAssets == MASTERNODE_SYNC_INITIAL) GetNextAsset(); @@ -185,7 +194,14 @@ void CMasternodeSync::Process() if(RequestedMasternodeAssets == MASTERNODE_SYNC_BUDGET){ if(lastBudgetItem > 0 && lastBudgetItem < GetTime() - MASTERNODE_SYNC_TIMEOUT){ //hasn't received a new item in the last five seconds, so we'll move to the - GetNextAsset(); + if(budget.HasNextFinalizedBudget()) { + GetNextAsset(); + } else { //we've failed to sync, this state will reject the next budget block + LogPrintf("CMasternodeSync::Process - ERROR - Sync has failed, will retry later\n"); + RequestedMasternodeAssets = MASTERNODE_SYNC_FAILED; + RequestedMasternodeAttempt = 0; + lastFailure = GetTime(); + } return; } diff --git a/src/masternode-sync.h b/src/masternode-sync.h index 677f4abb7c..0326a14d48 100644 --- a/src/masternode-sync.h +++ b/src/masternode-sync.h @@ -10,9 +10,10 @@ #define MASTERNODE_SYNC_LIST 2 #define MASTERNODE_SYNC_MNW 3 #define MASTERNODE_SYNC_BUDGET 4 +#define MASTERNODE_SYNC_FAILED 998 #define MASTERNODE_SYNC_FINISHED 999 -#define MASTERNODE_SYNC_TIMEOUT 5 +#define MASTERNODE_SYNC_TIMEOUT 15 class CMasternodeSync; extern CMasternodeSync masternodeSync; @@ -27,6 +28,7 @@ public: int64_t lastMasternodeList; int64_t lastMasternodeWinner; int64_t lastBudgetItem; + int64_t lastFailure; // Count peers we've requested the list from int RequestedMasternodeAssets; diff --git a/src/rpcmasternode-budget.cpp b/src/rpcmasternode-budget.cpp index c2749bdaec..6d2505d175 100644 --- a/src/rpcmasternode-budget.cpp +++ b/src/rpcmasternode-budget.cpp @@ -180,7 +180,7 @@ Value mnbudget(const Array& params, bool fHelp) return "Proposal is not valid - " + budgetProposalBroadcast.GetHash().ToString() + " - " + strError; } - mapSeenMasternodeBudgetProposals.insert(make_pair(budgetProposalBroadcast.GetHash(), budgetProposalBroadcast)); + budget.mapSeenMasternodeBudgetProposals.insert(make_pair(budgetProposalBroadcast.GetHash(), budgetProposalBroadcast)); budgetProposalBroadcast.Relay(); budget.AddProposal(budgetProposalBroadcast); @@ -248,7 +248,7 @@ Value mnbudget(const Array& params, bool fHelp) continue; } - mapSeenMasternodeBudgetVotes.insert(make_pair(vote.GetHash(), vote)); + budget.mapSeenMasternodeBudgetVotes.insert(make_pair(vote.GetHash(), vote)); vote.Relay(); budget.UpdateProposal(vote, NULL); @@ -292,7 +292,7 @@ Value mnbudget(const Array& params, bool fHelp) return "Failure to sign."; } - mapSeenMasternodeBudgetVotes.insert(make_pair(vote.GetHash(), vote)); + budget.mapSeenMasternodeBudgetVotes.insert(make_pair(vote.GetHash(), vote)); vote.Relay(); budget.UpdateProposal(vote, NULL); @@ -538,7 +538,7 @@ Value mnfinalbudget(const Array& params, bool fHelp) continue; } - mapSeenFinalizedBudgetVotes.insert(make_pair(vote.GetHash(), vote)); + budget.mapSeenFinalizedBudgetVotes.insert(make_pair(vote.GetHash(), vote)); vote.Relay(); budget.UpdateFinalizedBudget(vote, NULL); @@ -577,7 +577,7 @@ Value mnfinalbudget(const Array& params, bool fHelp) return "Failure to sign."; } - mapSeenFinalizedBudgetVotes.insert(make_pair(vote.GetHash(), vote)); + budget.mapSeenFinalizedBudgetVotes.insert(make_pair(vote.GetHash(), vote)); vote.Relay(); budget.UpdateFinalizedBudget(vote, NULL); diff --git a/src/version.h b/src/version.h index 2c5b5c3a72..788c2d62f6 100644 --- a/src/version.h +++ b/src/version.h @@ -10,7 +10,7 @@ * network protocol versioning */ -static const int PROTOCOL_VERSION = 70096; +static const int PROTOCOL_VERSION = 70097; //! initial proto version, to be increased after version/verack negotiation static const int INIT_PROTO_VERSION = 209; @@ -22,19 +22,19 @@ static const int GETHEADERS_VERSION = 70077; static const int MIN_PEER_PROTO_VERSION = 70066; //! minimum peer version accepted by DarksendPool -static const int MIN_POOL_PEER_PROTO_VERSION = 70096; +static const int MIN_POOL_PEER_PROTO_VERSION = 70097; //! minimum peer version for masternode budgets -static const int MIN_BUDGET_PEER_PROTO_VERSION = 70096; +static const int MIN_BUDGET_PEER_PROTO_VERSION = 70097; //! minimum peer version for masternode winner broadcasts -static const int MIN_MNW_PEER_PROTO_VERSION = 70096; +static const int MIN_MNW_PEER_PROTO_VERSION = 70097; //! minimum peer version that can receive masternode payments // V1 - Last protocol version before update // V2 - Newest protocol version static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_1 = 70066; -static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_2 = 70096; +static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_2 = 70097; //! nTime field added to CAddress, starting with this version; //! if possible, avoid requesting addresses nodes older than this