From 7101c951f8ea0a5df6b81fb018725d373d664c86 Mon Sep 17 00:00:00 2001 From: Evan Duffield Date: Thu, 16 Jul 2015 20:03:42 -0700 Subject: [PATCH] Budget Improvements - Client bump - Improved syncing logic (sholud stop hanging issues) - New spork for turning on super blocks - Fixed issue with sending old/invalid finalized budgets - Fixed issue with syncing clients and lack of confirmations with budget items (for IX) --- configure.ac | 2 +- src/clientversion.h | 2 +- src/masternode-budget.cpp | 51 ++++++++++++++++++++----------------- src/masternode-budget.h | 2 +- src/masternode-payments.cpp | 11 +++++++- src/masternode-sync.cpp | 24 ++++++++++++++--- src/masternode-sync.h | 7 ++--- src/spork.cpp | 4 +++ src/spork.h | 4 ++- 9 files changed, 72 insertions(+), 35 deletions(-) diff --git a/configure.ac b/configure.ac index 2644ce768fc3d..d506c3e6c4d68 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, 19) +define(_CLIENT_VERSION_BUILD, 20) 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/clientversion.h b/src/clientversion.h index e74626c9cb4f5..597ccaec9edc1 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 19 +#define CLIENT_VERSION_BUILD 20 //! Set to true for release, false for prerelease or test build #define CLIENT_VERSION_IS_RELEASE true diff --git a/src/masternode-budget.cpp b/src/masternode-budget.cpp index 5745c05e1a486..84ff54fa83e04 100644 --- a/src/masternode-budget.cpp +++ b/src/masternode-budget.cpp @@ -79,13 +79,14 @@ bool IsBudgetCollateralValid(uint256 nTxCollateralHash, uint256 nExpectedHash, s } } - if(conf < BUDGET_FEE_CONFIRMATIONS){ + //if we're syncing we won't have instantX information, so accept 1 confirmation + if(conf >= BUDGET_FEE_CONFIRMATIONS || (!masternodeSync.IsSynced() && conf >= 1)){ + return true; + } else { strError = strprintf("Collateral requires at least %d confirmations - %d confirmations", BUDGET_FEE_CONFIRMATIONS, conf); LogPrintf ("CBudgetProposalBroadcast::IsBudgetCollateralValid - %s - %d confirmations\n", strError, conf); return false; } - - return true; } void CBudgetManager::CheckOrphanVotes() @@ -179,8 +180,9 @@ void CBudgetManager::SubmitFinalBudget() //create the proposal incase we're the first to make it CFinalizedBudgetBroadcast finalizedBudgetBroadcast(strBudgetName, nBlockStart, vecTxBudgetPayments, tx.GetHash()); - if(!finalizedBudgetBroadcast.IsValid()){ - LogPrintf("SubmitFinalBudget - Invalid finalized budget broadcast (are all the hashes correct?)\n"); + std::string strError = ""; + if(!finalizedBudgetBroadcast.IsValid(strError)){ + LogPrintf("SubmitFinalBudget - Invalid finalized budget - %s \n", strError.c_str()); return; } @@ -342,7 +344,8 @@ void DumpBudgets() void CBudgetManager::AddFinalizedBudget(CFinalizedBudget& finalizedBudget) { LOCK(cs); - if(!finalizedBudget.IsValid()) return; + std::string strError = ""; + if(!finalizedBudget.IsValid(strError)) return; if(mapFinalizedBudgets.count(finalizedBudget.GetHash())) { return; @@ -374,7 +377,7 @@ void CBudgetManager::CheckAndRemove() while(it != mapFinalizedBudgets.end()) { CFinalizedBudget* pfinalizedBudget = &((*it).second); - if(!pfinalizedBudget->IsValid()){ + if(!pfinalizedBudget->IsValid(strError)){ pfinalizedBudget->fValid = false; } else { pfinalizedBudget->fValid = true; @@ -815,8 +818,8 @@ void CBudgetManager::ProcessMessage(CNode* pfrom, std::string& strCommand, CData mapSeenFinalizedBudgets.insert(make_pair(finalizedBudgetBroadcast.GetHash(), finalizedBudgetBroadcast)); - if(!finalizedBudgetBroadcast.IsValid()) { - LogPrintf("fbs - invalid finalized budget\n"); + if(!finalizedBudgetBroadcast.IsValid(strError)) { + LogPrintf("fbs - invalid finalized budget - %s\n", strError); return; } @@ -883,7 +886,7 @@ void CBudgetManager::Sync(CNode* pfrom, uint256 nProp) std::map::iterator it1 = mapSeenMasternodeBudgetProposals.begin(); while(it1 != mapSeenMasternodeBudgetProposals.end()){ CBudgetProposal* pbudgetProposal = budget.FindProposal((*it1).first); - if(pbudgetProposal && (nProp == 0 || (*it1).first == nProp)){ + if(pbudgetProposal && pbudgetProposal->fValid && (nProp == 0 || (*it1).first == nProp)){ pfrom->PushMessage("mprop", ((*it1).second)); //send votes @@ -902,7 +905,7 @@ void CBudgetManager::Sync(CNode* pfrom, uint256 nProp) std::map::iterator it3 = mapSeenFinalizedBudgets.begin(); while(it3 != mapSeenFinalizedBudgets.end()){ CFinalizedBudget* pfinalizedBudget = budget.FindFinalizedBudget((*it3).first); - if(pfinalizedBudget && (nProp == 0 || (*it3).first == nProp)){ + if(pfinalizedBudget && pfinalizedBudget->fValid && (nProp == 0 || (*it3).first == nProp)){ pfrom->PushMessage("fbs", ((*it3).second)); //send votes @@ -1424,23 +1427,23 @@ std::string CFinalizedBudget::GetStatus() return retBadHashes + retBadPayeeOrAmount; } -bool CFinalizedBudget::IsValid(bool fCheckCollateral) +bool CFinalizedBudget::IsValid(std::string& strError, bool fCheckCollateral) { //must be the correct block for payment to happen (once a month) - if(nBlockStart % GetBudgetPaymentCycleBlocks() != 0) return false; - if(GetBlockEnd() - nBlockStart > 100) return false; - if(vecProposals.size() > 100) return false; - if(strBudgetName == "") return false; - if(nBlockStart == 0) return false; - if(nFeeTXHash == 0) return false; + if(nBlockStart % GetBudgetPaymentCycleBlocks() != 0) {strError = "Invalid BlockStart"; return false;} + if(GetBlockEnd() - nBlockStart > 100) {strError = "Invalid BlockEnd"; return false;} + if(vecProposals.size() > 100) {strError = "Invalid Proposal Count (too many)"; return false;} + if(strBudgetName == "") {strError = "Invalid Budget Name"; return false;} + if(nBlockStart == 0) {strError = "Invalid BlockStart == 0"; return false;} + if(nFeeTXHash == 0) {strError = "Invalid FeeTx == 0"; return false;} //can only pay out 10% of the possible coins (min value of coins) - if(GetTotalPayout() > budget.GetTotalBudget(nBlockStart)) return false; + if(GetTotalPayout() > budget.GetTotalBudget(nBlockStart)) {strError = "Invalid Payout (more than max)"; return false;} - std::string strError = ""; + std::string strError2 = ""; if(fCheckCollateral){ - if(!IsBudgetCollateralValid(nFeeTXHash, GetHash(), strError)){ - return false; + if(!IsBudgetCollateralValid(nFeeTXHash, GetHash(), strError2)){ + {strError = "Invalid Collateral : " + strError2; return false;} } } @@ -1449,8 +1452,8 @@ bool CFinalizedBudget::IsValid(bool fCheckCollateral) CBlockIndex* pindexPrev = chainActive.Tip(); if(pindexPrev == NULL) return true; - if(nBlockStart < pindexPrev->nHeight) return false; - if(GetBlockEnd() < pindexPrev->nHeight - GetBudgetPaymentCycleBlocks()/2 ) return false; + if(nBlockStart < pindexPrev->nHeight) {strError = "Older than current blockHeight"; return false;} + if(GetBlockEnd() < pindexPrev->nHeight - GetBudgetPaymentCycleBlocks()/2 ) {strError = "BlockEnd is older than blockHeight - cycle/2"; return false;} return true; } diff --git a/src/masternode-budget.h b/src/masternode-budget.h index 014b44eba8091..e10051aa286f0 100644 --- a/src/masternode-budget.h +++ b/src/masternode-budget.h @@ -203,7 +203,7 @@ class CFinalizedBudget double GetScore(); bool HasMinimumRequiredSupport(); - bool IsValid(bool fCheckCollateral=true); + bool IsValid(std::string& strError, bool fCheckCollateral=true); std::string GetName() {return strBudgetName; } std::string GetProposals(); diff --git a/src/masternode-payments.cpp b/src/masternode-payments.cpp index 1992135293616..25b0da44de829 100644 --- a/src/masternode-payments.cpp +++ b/src/masternode-payments.cpp @@ -38,7 +38,16 @@ bool IsBlockValueValid(const CBlock& block, int64_t nExpectedValue){ LogPrintf("IsBlockValueValid() : WARNING: Couldn't find previous block"); } - if((budget.sizeFinalized() == 0 && budget.sizeProposals() == 0) || nHeight == 0) { //there is no budget data to use to check anything + //are these blocks even enabled? + if(!IsSporkActive(SPORK_13_ENABLE_SUPERBLOCKS)){ + if(block.vtx[0].GetValueOut() > nExpectedValue) { + return false; + } else { + return true; + } + } + + if(!masternodeSync.IsSynced()) { //there is no budget data to use to check anything //super blocks will always be on these blocks, max 100 per budgeting if(nHeight % GetBudgetPaymentCycleBlocks() < 100){ return true; diff --git a/src/masternode-sync.cpp b/src/masternode-sync.cpp index 40bffc5275ea9..ebb1e0943986c 100644 --- a/src/masternode-sync.cpp +++ b/src/masternode-sync.cpp @@ -48,6 +48,9 @@ void CMasternodeSync::GetNextAsset() switch(RequestedMasternodeAssets) { case(MASTERNODE_INITIAL): + RequestedMasternodeAssets = MASTERNODE_SPORK_SETTINGS; + break; + case(MASTERNODE_SPORK_SETTINGS): RequestedMasternodeAssets = MASTERNODE_SYNC_LIST; break; case(MASTERNODE_SYNC_LIST): @@ -79,6 +82,21 @@ void CMasternodeSync::Process() { if (pnode->nVersion >= MIN_POOL_PEER_PROTO_VERSION) { + + if(RequestedMasternodeAssets == MASTERNODE_SPORK_SETTINGS){ + if(pnode->HasFulfilledRequest("getspork")) continue; + pnode->FulfilledRequest("getspork"); + + if(RequestedMasternodeAttempt <= 2){ + pnode->PushMessage("getsporks"); //get current network sporks + if(RequestedMasternodeAttempt == 2) GetNextAsset(); + RequestedMasternodeAttempt++; + } + return; + } + + if(IsInitialBlockDownload()) return; + if(RequestedMasternodeAssets == MASTERNODE_SYNC_LIST){ if(lastMasternodeList > 0 && lastMasternodeList < GetTime() - 5){ //hasn't received a new item in the last five seconds, so we'll move to the GetNextAsset(); @@ -88,7 +106,7 @@ void CMasternodeSync::Process() if(pnode->HasFulfilledRequest("mnsync")) continue; pnode->FulfilledRequest("mnsync"); - if((lastMasternodeList == 0 || lastMasternodeList > GetTime() - 5) && RequestedMasternodeAttempt <= 2){ + if((lastMasternodeList == 0 || lastMasternodeList > GetTime() - 5) && RequestedMasternodeAttempt <= 4){ mnodeman.DsegUpdate(pnode); pnode->PushMessage("getsporks"); //get current network sporks AddedMasternodeList(); @@ -106,7 +124,7 @@ void CMasternodeSync::Process() if(pnode->HasFulfilledRequest("mnwsync")) continue; pnode->FulfilledRequest("mnwsync"); - if((lastMasternodeWinner == 0 || lastMasternodeWinner > GetTime() - 5) && RequestedMasternodeAttempt <= 4){ + if((lastMasternodeWinner == 0 || lastMasternodeWinner > GetTime() - 5) && RequestedMasternodeAttempt <= 6){ pnode->PushMessage("mnget"); //sync payees AddedMasternodeWinner(); RequestedMasternodeAttempt++; @@ -123,7 +141,7 @@ void CMasternodeSync::Process() if(pnode->HasFulfilledRequest("busync")) continue; pnode->FulfilledRequest("busync"); - if((lastBudgetItem == 0 || lastBudgetItem > GetTime() - 5) && RequestedMasternodeAttempt <= 6){ + if((lastBudgetItem == 0 || lastBudgetItem > GetTime() - 5) && RequestedMasternodeAttempt <= 8){ uint256 n = 0; pnode->PushMessage("mnvs", n); //sync masternode votes diff --git a/src/masternode-sync.h b/src/masternode-sync.h index de5664d0d91d2..178049d7da6a3 100644 --- a/src/masternode-sync.h +++ b/src/masternode-sync.h @@ -16,9 +16,10 @@ using namespace std; #define MASTERNODE_INITIAL 0 -#define MASTERNODE_SYNC_LIST 1 -#define MASTERNODE_SYNC_MNW 2 -#define MASTERNODE_SYNC_BUDGET 3 +#define MASTERNODE_SPORK_SETTINGS 1 +#define MASTERNODE_SYNC_LIST 2 +#define MASTERNODE_SYNC_MNW 3 +#define MASTERNODE_SYNC_BUDGET 4 #define MASTERNODE_LIST_SYNCED 999 class CMasternodeSync; diff --git a/src/spork.cpp b/src/spork.cpp index 7f20e00fc41f0..9833356293de2 100644 --- a/src/spork.cpp +++ b/src/spork.cpp @@ -91,6 +91,7 @@ bool IsSporkActive(int nSporkID) if(nSporkID == SPORK_10_MASTERNODE_PAY_NEWEST_NODES) r = SPORK_10_MASTERNODE_PAY_NEWEST_NODES_DEFAULT; if(nSporkID == SPORK_11_RESET_BUDGET) r = SPORK_11_RESET_BUDGET_DEFAULT; if(nSporkID == SPORK_12_RECONSIDER_BLOCKS) r = SPORK_12_RECONSIDER_BLOCKS_DEFAULT; + if(nSporkID == SPORK_13_ENABLE_SUPERBLOCKS) r = SPORK_13_ENABLE_SUPERBLOCKS_DEFAULT; if(r == -1) LogPrintf("GetSpork::Unknown Spork %d\n", nSporkID); } @@ -116,6 +117,7 @@ int GetSporkValue(int nSporkID) if(nSporkID == SPORK_10_MASTERNODE_PAY_NEWEST_NODES) r = SPORK_10_MASTERNODE_PAY_NEWEST_NODES_DEFAULT; if(nSporkID == SPORK_11_RESET_BUDGET) r = SPORK_11_RESET_BUDGET_DEFAULT; if(nSporkID == SPORK_12_RECONSIDER_BLOCKS) r = SPORK_12_RECONSIDER_BLOCKS_DEFAULT; + if(nSporkID == SPORK_13_ENABLE_SUPERBLOCKS) r = SPORK_13_ENABLE_SUPERBLOCKS_DEFAULT; if(r == 0) LogPrintf("GetSpork::Unknown Spork %d\n", nSporkID); } @@ -251,6 +253,7 @@ int CSporkManager::GetSporkIDByName(std::string strName) if(strName == "SPORK_10_MASTERNODE_PAY_NEWEST_NODES") return SPORK_10_MASTERNODE_PAY_NEWEST_NODES; if(strName == "SPORK_11_RESET_BUDGET") return SPORK_11_RESET_BUDGET; if(strName == "SPORK_12_RECONSIDER_BLOCKS") return SPORK_12_RECONSIDER_BLOCKS; + if(strName == "SPORK_13_ENABLE_SUPERBLOCKS") return SPORK_13_ENABLE_SUPERBLOCKS; return -1; } @@ -266,6 +269,7 @@ std::string CSporkManager::GetSporkNameByID(int id) if(id == SPORK_10_MASTERNODE_PAY_NEWEST_NODES) return "SPORK_10_MASTERNODE_PAY_NEWEST_NODES"; if(id == SPORK_11_RESET_BUDGET) return "SPORK_11_RESET_BUDGET"; if(id == SPORK_12_RECONSIDER_BLOCKS) return "SPORK_12_RECONSIDER_BLOCKS"; + if(id == SPORK_13_ENABLE_SUPERBLOCKS) return "SPORK_13_ENABLE_SUPERBLOCKS"; return "Unknown"; } diff --git a/src/spork.h b/src/spork.h index 6cdceade47cfe..0dfed83ee9433 100644 --- a/src/spork.h +++ b/src/spork.h @@ -24,7 +24,7 @@ using namespace boost; - This would result in old clients getting confused about which spork is for what */ #define SPORK_START 10001 -#define SPORK_END 10011 +#define SPORK_END 10012 #define SPORK_2_INSTANTX 10001 #define SPORK_3_INSTANTX_BLOCK_FILTERING 10002 @@ -35,6 +35,7 @@ using namespace boost; #define SPORK_10_MASTERNODE_PAY_NEWEST_NODES 10009 #define SPORK_11_RESET_BUDGET 10010 #define SPORK_12_RECONSIDER_BLOCKS 10011 +#define SPORK_13_ENABLE_SUPERBLOCKS 10012 #define SPORK_2_INSTANTX_DEFAULT 978307200 //2001-1-1 #define SPORK_3_INSTANTX_BLOCK_FILTERING_DEFAULT 1424217600 //2015-2-18 @@ -45,6 +46,7 @@ using namespace boost; #define SPORK_10_MASTERNODE_PAY_NEWEST_NODES_DEFAULT 1444217600 //OFF #define SPORK_11_RESET_BUDGET_DEFAULT 0 #define SPORK_12_RECONSIDER_BLOCKS_DEFAULT 0 +#define SPORK_13_ENABLE_SUPERBLOCKS_DEFAULT 978307200 //2001-1-1 class CSporkMessage; class CSporkManager;