diff --git a/src/main.cpp b/src/main.cpp index 413a396c2..e15bd9fbb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4036,9 +4036,7 @@ void static ProcessGetData(CNode* pfrom) vector vNotFound; - //if we can't lock cs_main, return and do this later - TRY_LOCK(cs_main, fCsMainLock); - if(!fCsMainLock) return; + LOCK(cs_main); while (it != pfrom->vRecvGetData.end()) { // Don't bother if send buffer is too full to respond anyway diff --git a/src/masternode-budget.cpp b/src/masternode-budget.cpp index a6370a364..974f1aa92 100644 --- a/src/masternode-budget.cpp +++ b/src/masternode-budget.cpp @@ -19,6 +19,8 @@ CBudgetManager budget; CCriticalSection cs_budget; std::map askedForSourceProposalOrBudget; +std::vector vecImmatureBudgetProposals; +std::vector vecImmatureFinalizedBudgets; int nSubmittedFinalBudget; @@ -30,7 +32,7 @@ int GetBudgetPaymentCycleBlocks(){ return 50; } -bool IsBudgetCollateralValid(uint256 nTxCollateralHash, uint256 nExpectedHash, std::string& strError, int64_t& nTime) +bool IsBudgetCollateralValid(uint256 nTxCollateralHash, uint256 nExpectedHash, std::string& strError, int64_t& nTime, int& nConf) { CTransaction txCollateral; uint256 nBlockHash; @@ -74,6 +76,8 @@ bool IsBudgetCollateralValid(uint256 nTxCollateralHash, uint256 nExpectedHash, s } } + nConf = conf; + //if we're syncing we won't have instantX information, so accept 1 confirmation if(conf >= BUDGET_FEE_CONFIRMATIONS){ return true; @@ -799,6 +803,54 @@ void CBudgetManager::NewBlock() (*it3).second.CleanAndRemove(false); ++it3; } + + std::vector::iterator it4 = vecImmatureBudgetProposals.begin(); + while(it4 != vecImmatureBudgetProposals.end()) + { + std::string strError = ""; + int nConf = 0; + if(!IsBudgetCollateralValid((*it4).nFeeTXHash, (*it4).GetHash(), strError, (*it4).nTime, nConf)){ + ++it4; + continue; + } + + if(!(*it4).IsValid(strError)) { + LogPrintf("mprop (immature) - invalid budget proposal - %s\n", strError); + it4 = vecImmatureBudgetProposals.erase(it4); + continue; + } + + CBudgetProposal budgetProposal((*it4)); + if(AddProposal(budgetProposal)) {(*it4).Relay();} + + LogPrintf("mprop (immature) - new budget - %s\n", (*it4).GetHash().ToString()); + it4 = vecImmatureBudgetProposals.erase(it4); + } + + std::vector::iterator it5 = vecImmatureFinalizedBudgets.begin(); + while(it5 != vecImmatureFinalizedBudgets.end()) + { + std::string strError = ""; + int nConf = 0; + if(!IsBudgetCollateralValid((*it5).nFeeTXHash, (*it5).GetHash(), strError, (*it5).nTime, nConf)){ + ++it5; + continue; + } + + if(!(*it5).IsValid(strError)) { + LogPrintf("fbs (immature) - invalid finalized budget - %s\n", strError); + it5 = vecImmatureFinalizedBudgets.erase(it5); + continue; + } + + LogPrintf("fbs (immature) - new finalized budget - %s\n", (*it5).GetHash().ToString()); + + CFinalizedBudget finalizedBudget((*it5)); + if(AddFinalizedBudget(finalizedBudget)) {(*it5).Relay();} + + it5 = vecImmatureFinalizedBudgets.erase(it5); + } + } void CBudgetManager::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv) @@ -813,12 +865,14 @@ void CBudgetManager::ProcessMessage(CNode* pfrom, std::string& strCommand, CData vRecv >> nProp; if(Params().NetworkID() == CBaseChainParams::MAIN){ - if(pfrom->HasFulfilledRequest("mnvs")) { - LogPrintf("mnvs - peer already asked me for the list\n"); - Misbehaving(pfrom->GetId(), 20); - return; + if(nProp == 0) { + if(pfrom->HasFulfilledRequest("mnvs")) { + LogPrintf("mnvs - peer already asked me for the list\n"); + Misbehaving(pfrom->GetId(), 20); + return; + } + pfrom->FulfilledRequest("mnvs"); } - pfrom->FulfilledRequest("mnvs"); } Sync(pfrom, nProp); @@ -835,8 +889,10 @@ void CBudgetManager::ProcessMessage(CNode* pfrom, std::string& strCommand, CData } std::string strError = ""; - if(!IsBudgetCollateralValid(budgetProposalBroadcast.nFeeTXHash, budgetProposalBroadcast.GetHash(), strError, budgetProposalBroadcast.nTime)){ + int nConf = 0; + if(!IsBudgetCollateralValid(budgetProposalBroadcast.nFeeTXHash, budgetProposalBroadcast.GetHash(), strError, budgetProposalBroadcast.nTime, nConf)){ LogPrintf("Proposal FeeTX is not valid - %s - %s\n", budgetProposalBroadcast.nFeeTXHash.ToString(), strError); + if(nConf >= 1) vecImmatureBudgetProposals.push_back(budgetProposalBroadcast); return; } @@ -900,8 +956,11 @@ void CBudgetManager::ProcessMessage(CNode* pfrom, std::string& strCommand, CData } std::string strError = ""; - if(!IsBudgetCollateralValid(finalizedBudgetBroadcast.nFeeTXHash, finalizedBudgetBroadcast.GetHash(), strError, finalizedBudgetBroadcast.nTime)){ + int nConf = 0; + if(!IsBudgetCollateralValid(finalizedBudgetBroadcast.nFeeTXHash, finalizedBudgetBroadcast.GetHash(), strError, finalizedBudgetBroadcast.nTime, nConf)){ LogPrintf("Finalized Budget FeeTX is not valid - %s - %s\n", finalizedBudgetBroadcast.nFeeTXHash.ToString(), strError); + + if(nConf >= 1) vecImmatureFinalizedBudgets.push_back(finalizedBudgetBroadcast); return; } @@ -1133,7 +1192,8 @@ bool CBudgetProposal::IsValid(std::string& strError, bool fCheckCollateral) } if(fCheckCollateral){ - if(!IsBudgetCollateralValid(nFeeTXHash, GetHash(), strError, nTime)){ + int nConf = 0; + if(!IsBudgetCollateralValid(nFeeTXHash, GetHash(), strError, nTime, nConf)){ return false; } } @@ -1339,6 +1399,18 @@ CBudgetProposalBroadcast::CBudgetProposalBroadcast(const CBudgetProposal& other) nTime = other.nTime; } +CBudgetProposalBroadcast::CBudgetProposalBroadcast(const CBudgetProposalBroadcast& other) +{ + strProposalName = other.strProposalName; + strURL = other.strURL; + nBlockStart = other.nBlockStart; + nBlockEnd = other.nBlockEnd; + address = other.address; + nAmount = other.nAmount; + nFeeTXHash = other.nFeeTXHash; + nTime = other.nTime; +} + CBudgetProposalBroadcast::CBudgetProposalBroadcast(std::string strProposalNameIn, std::string strURLIn, int nPaymentCount, CScript addressIn, CAmount nAmountIn, int nBlockStartIn, uint256 nFeeTXHashIn) { strProposalName = strProposalNameIn; @@ -1639,7 +1711,8 @@ bool CFinalizedBudget::IsValid(std::string& strError, bool fCheckCollateral) std::string strError2 = ""; if(fCheckCollateral){ - if(!IsBudgetCollateralValid(nFeeTXHash, GetHash(), strError2, nTime)){ + int nConf = 0; + if(!IsBudgetCollateralValid(nFeeTXHash, GetHash(), strError2, nTime, nConf)){ {strError = "Invalid Collateral : " + strError2; return false;} } } diff --git a/src/masternode-budget.h b/src/masternode-budget.h index afb50cfca..db5411ec9 100644 --- a/src/masternode-budget.h +++ b/src/masternode-budget.h @@ -36,6 +36,9 @@ static const CAmount BUDGET_FEE_TX = (0.5*COIN); static const int64_t BUDGET_FEE_CONFIRMATIONS = 6; static const int64_t BUDGET_VOTE_UPDATE_MIN = 60*60; +extern std::vector vecImmatureBudgetProposals; +extern std::vector vecImmatureFinalizedBudgets; + extern CBudgetManager budget; void DumpBudgets(); @@ -43,7 +46,7 @@ void DumpBudgets(); int GetBudgetPaymentCycleBlocks(); //Check the collateral transaction for the budget proposal/finalized budget -bool IsBudgetCollateralValid(uint256 nTxCollateralHash, uint256 nExpectedHash, std::string& strError, int64_t& nTime); +bool IsBudgetCollateralValid(uint256 nTxCollateralHash, uint256 nExpectedHash, std::string& strError, int64_t& nTime, int& nConf); /** Save Budget Manager (budget.dat) */ @@ -293,6 +296,27 @@ public: CFinalizedBudgetBroadcast(const CFinalizedBudget& other); CFinalizedBudgetBroadcast(std::string strBudgetNameIn, int nBlockStartIn, std::vector vecBudgetPaymentsIn, uint256 nFeeTXHashIn); + void swap(CFinalizedBudgetBroadcast& first, CFinalizedBudgetBroadcast& second) // nothrow + { + // enable ADL (not necessary in our case, but good practice) + using std::swap; + + // by swapping the members of two classes, + // the two classes are effectively swapped + swap(first.strBudgetName, second.strBudgetName); + swap(first.nBlockStart, second.nBlockStart); + first.mapVotes.swap(second.mapVotes); + first.vecBudgetPayments.swap(second.vecBudgetPayments); + swap(first.nFeeTXHash, second.nFeeTXHash); + swap(first.nTime, second.nTime); + } + + CFinalizedBudgetBroadcast& operator=(CFinalizedBudgetBroadcast from) + { + swap(*this, from); + return *this; + } + void Relay(); ADD_SERIALIZE_METHODS; @@ -459,8 +483,33 @@ private: public: CBudgetProposalBroadcast(); CBudgetProposalBroadcast(const CBudgetProposal& other); + CBudgetProposalBroadcast(const CBudgetProposalBroadcast& other); CBudgetProposalBroadcast(std::string strProposalNameIn, std::string strURLIn, int nPaymentCount, CScript addressIn, CAmount nAmountIn, int nBlockStartIn, uint256 nFeeTXHashIn); + void swap(CBudgetProposalBroadcast& first, CBudgetProposalBroadcast& second) // nothrow + { + // enable ADL (not necessary in our case, but good practice) + using std::swap; + + // by swapping the members of two classes, + // the two classes are effectively swapped + swap(first.strProposalName, second.strProposalName); + swap(first.nBlockStart, second.nBlockStart); + swap(first.strURL, second.strURL); + swap(first.nBlockEnd, second.nBlockEnd); + swap(first.nAmount, second.nAmount); + swap(first.address, second.address); + swap(first.nTime, second.nTime); + swap(first.nFeeTXHash, second.nFeeTXHash); + first.mapVotes.swap(second.mapVotes); + } + + CBudgetProposalBroadcast& operator=(CBudgetProposalBroadcast from) + { + swap(*this, from); + return *this; + } + void Relay(); ADD_SERIALIZE_METHODS; diff --git a/src/rpcmasternode-budget.cpp b/src/rpcmasternode-budget.cpp index c0963f648..ccd616d42 100644 --- a/src/rpcmasternode-budget.cpp +++ b/src/rpcmasternode-budget.cpp @@ -174,17 +174,18 @@ Value mnbudget(const Array& params, bool fHelp) CBudgetProposalBroadcast budgetProposalBroadcast(strProposalName, strURL, nPaymentCount, scriptPubKey, nAmount, nBlockStart, hash); std::string strError = ""; - if(!IsBudgetCollateralValid(hash, budgetProposalBroadcast.GetHash(), strError, budgetProposalBroadcast.nTime)){ - return "Proposal FeeTX is not valid - " + hash.ToString() + " - " + strError; + int nConf = 0; + if(!IsBudgetCollateralValid(hash, budgetProposalBroadcast.GetHash(), strError, budgetProposalBroadcast.nTime, nConf)){ + //return "Proposal FeeTX is not valid - " + hash.ToString() + " - " + strError; } if(!masternodeSync.IsSynced()){ return "Must wait for client to sync with masternode network. Try again in a minute or so."; } - if(!budgetProposalBroadcast.IsValid(strError)){ - return "Proposal is not valid - " + budgetProposalBroadcast.GetHash().ToString() + " - " + strError; - } + // if(!budgetProposalBroadcast.IsValid(strError)){ + // return "Proposal is not valid - " + budgetProposalBroadcast.GetHash().ToString() + " - " + strError; + // } budget.mapSeenMasternodeBudgetProposals.insert(make_pair(budgetProposalBroadcast.GetHash(), budgetProposalBroadcast)); budgetProposalBroadcast.Relay();