diff --git a/README.md b/README.md index 3e1db28a0..6c4d662b1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ -Dash Core staging tree 0.12 +Dash Core staging tree 0.12.1 =============================== +`master:` [![Build Status](https://travis-ci.org/dashpay/dash.svg?branch=master)](https://travis-ci.org/dashpay/dash) `v0.12.0.x:` [![Build Status](https://travis-ci.org/dashpay/dash.svg?branch=v0.12.0.x)](https://travis-ci.org/dashpay/dash/branches) `v0.12.1.x:` [![Build Status](https://travis-ci.org/dashpay/dash.svg?branch=v0.12.1.x)](https://travis-ci.org/dashpay/dash/branches) + https://www.dash.org @@ -72,4 +74,4 @@ Translations are periodically pulled from Transifex and merged into the git repo **Important**: We do not accept translation changes as GitHub pull requests because the next pull from Transifex would automatically overwrite them again. -Translators should also follow the [forum](https://dashtalk.org/forums/dash-worldwide-collaboration.88/). +Translators should also follow the [forum](https://www.dash.org/forum/topic/dash-worldwide-collaboration.88/). diff --git a/src/darksend.cpp b/src/darksend.cpp index 7f3b346cc..ecfafc8fa 100644 --- a/src/darksend.cpp +++ b/src/darksend.cpp @@ -385,7 +385,7 @@ void CDarksendPool::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataS return; } - darkSendPool.CompletedTransaction(error, errorID); + CompletedTransaction(error, errorID); } } @@ -1445,6 +1445,14 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun) if(nBalanceNeedsDenominated > nValueIn) nBalanceNeedsDenominated = nValueIn; + LogPrint("privatesend", "%s -- SelectCoinsDark -- (%f - (%f + %f - %f = %f) ) = %f\n", __func__, + (float)nBalanceNeedsAnonymized/COIN, + (float)pwalletMain->GetDenominatedBalance(true)/COIN, + (float)pwalletMain->GetDenominatedBalance()/COIN, + (float)pwalletMain->GetAnonymizedBalance()/COIN, + (float)nOnlyDenominatedBalance/COIN, + (float)nBalanceNeedsDenominated/COIN); + if(nBalanceNeedsDenominated < nLowestDenom) return false; // most likely we just waiting for denoms to confirm if(!fDryRun) return CreateDenominated(nBalanceNeedsDenominated); @@ -1461,6 +1469,13 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun) nOnlyDenominatedBalance = pwalletMain->GetDenominatedBalance(true) + pwalletMain->GetDenominatedBalance() - pwalletMain->GetAnonymizedBalance(); nBalanceNeedsDenominated = nBalanceNeedsAnonymized - nOnlyDenominatedBalance; + LogPrint("privatesend", "%s -- 'nBalanceNeedsDenominated > nOnlyDenominatedBalance' (%f - (%f + %f - %f = %f) ) = %f\n", __func__, + (float)nBalanceNeedsAnonymized/COIN, + (float)pwalletMain->GetDenominatedBalance(true)/COIN, + (float)pwalletMain->GetDenominatedBalance()/COIN, + (float)pwalletMain->GetAnonymizedBalance()/COIN, + (float)nOnlyDenominatedBalance/COIN, + (float)nBalanceNeedsDenominated/COIN); //check if we have should create more denominated inputs if(nBalanceNeedsDenominated > nOnlyDenominatedBalance) return CreateDenominated(nBalanceNeedsDenominated); diff --git a/src/init.cpp b/src/init.cpp index 864be7733..062a8e2bb 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -191,8 +191,6 @@ void Interrupt(boost::thread_group& threadGroup) /** Preparing steps before shutting down or restarting the wallet */ void PrepareShutdown() { - LogPrintf("1 %s\n", governance.ToString()); - fRequestShutdown = true; // Needed when we shutdown the wallet fRestartRequested = true; // Needed when we restart the wallet LogPrintf("%s: In progress...\n", __func__); @@ -201,8 +199,6 @@ void PrepareShutdown() if (!lockShutdown) return; - LogPrintf("2 %s\n", governance.ToString()); - /// Note: Shutdown() must be able to handle cases in which AppInit2() failed part of the way, /// for example if the data directory was found to be locked. /// Be sure that anything that writes files or flushes caches only does this if the respective diff --git a/src/main.cpp b/src/main.cpp index 88dd94c20..e7d3a1c08 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1450,17 +1450,17 @@ int64_t GetTotalCoinEstimate(int nHeight) /* these values are taken from the block explorer */ if(nHeight > 5076) nTotalCoins += 2021642; if(nHeight > 17000) nTotalCoins += 3267692-2021642; - if(nHeight > 34000) nTotalCoins += 3688775-3267692; - if(nHeight > 68000) nTotalCoins += 4277615-3688775; + if(nHeight > 34000) nTotalCoins += 3688775-3267692; + if(nHeight > 68000) nTotalCoins += 4277615-3688775; if(nHeight > 68000*2) { - nTotalCoins += 4649913.99999995-4277615; + nTotalCoins += 4649913.99999995-4277615; } else { return nTotalCoins; } //5.383754730451325 per block average after this - nTotalCoins += ((nHeight-68000*2)*((5382104.64334133-4649913.99999995)/(68000*2))); + nTotalCoins += ((nHeight-68000*2)*((5382104.64334133-4649913.99999995)/(68000*2))); // TODO: this should include the 7.1% decline too return nTotalCoins; @@ -4565,7 +4565,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam } } - if (!pushed && inv.type == MSG_DSTX) { + if (!pushed && inv.type == MSG_DSTX) { if(mapDarksendBroadcastTxes.count(inv.hash)){ CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss.reserve(1000); diff --git a/src/masternode-budget.cpp b/src/masternode-budget.cpp deleted file mode 100644 index de4ca0816..000000000 --- a/src/masternode-budget.cpp +++ /dev/null @@ -1,1023 +0,0 @@ -// Copyright (c) 2014-2016 The Dash developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "core_io.h" -#include "main.h" -#include "init.h" - -CBudgetManager budget; -CCriticalSection cs_budget; - -std::vector vecImmatureFinalizedBudgets; - -int nSubmittedFinalBudget; - -struct sortFinalizedBudgetsByVotes { - bool operator()(const std::pair &left, const std::pair &right) { - return left.second > right.second; - } -}; - -// -// Sort by votes, if there's a tie sort by their feeHash TX -// -struct sortProposalsByVotes { - bool operator()(const std::pair &left, const std::pair &right) { - if( left.second != right.second) - return (left.second > right.second); - return (UintToArith256(left.first->nFeeTXHash) > UintToArith256(right.first->nFeeTXHash)); - } -}; - - -// void CBudgetManager::MarkSynced() -// { -// LOCK(cs); - -// /* -// Mark that we've sent all valid items -// */ - -// std::map::iterator it3 = mapSeenFinalizedBudgets.begin(); -// while(it3 != mapSeenFinalizedBudgets.end()){ -// CFinalizedBudget* pfinalizedBudget = FindFinalizedBudget((*it3).first); -// if(pfinalizedBudget && pfinalizedBudget->fValid){ - -// //mark votes -// std::map::iterator it4 = pfinalizedBudget->mapVotes.begin(); -// while(it4 != pfinalizedBudget->mapVotes.end()){ -// if((*it4).second.fValid) -// (*it4).second.fSynced = true; -// ++it4; -// } -// } -// ++it3; -// } - -// } - -// //mark that a full sync is needed -// void CBudgetManager::ResetSync() -// { -// LOCK(cs); - -// std::map::iterator it3 = mapSeenFinalizedBudgets.begin(); -// while(it3 != mapSeenFinalizedBudgets.end()){ -// CFinalizedBudget* pfinalizedBudget = FindFinalizedBudget((*it3).first); -// if(pfinalizedBudget && pfinalizedBudget->fValid){ - -// //send votes -// std::map::iterator it4 = pfinalizedBudget->mapVotes.begin(); -// while(it4 != pfinalizedBudget->mapVotes.end()){ -// (*it4).second.fSynced = false; -// ++it4; -// } -// } -// ++it3; -// } -// } - -void CBudgetManager::Sync(CNode* pfrom, uint256 nProp, bool fPartial) -{ - LOCK(cs); - - /* - Sync with a client on the network - - -- - - This code checks each of the hash maps for all known budget proposals and finalized budget proposals, then checks them against the - budget object to see if they're OK. If all checks pass, we'll send it to the peer. - - */ - - int nInvCount = 0; - - LogPrintf("CBudgetManager::Sync - sent %d items\n", nInvCount); - - // finalized budget -- this code has no issues as far as we can tell - std::map::iterator it3 = mapSeenFinalizedBudgets.begin(); - while(it3 != mapSeenFinalizedBudgets.end()){ - CFinalizedBudget* pfinalizedBudget = FindFinalizedBudget((*it3).first); - if(pfinalizedBudget && pfinalizedBudget->fValid && (nProp == uint256() || (*it3).first == nProp)){ - pfrom->PushInventory(CInv(MSG_BUDGET_FINALIZED, (*it3).second.GetHash())); - nInvCount++; - - //send votes - std::map::iterator it4 = pfinalizedBudget->mapVotes.begin(); - while(it4 != pfinalizedBudget->mapVotes.end()){ - if((*it4).second.fValid) { - if((fPartial && !(*it4).second.fSynced) || !fPartial) { - pfrom->PushInventory(CInv(MSG_BUDGET_FINALIZED_VOTE, (*it4).second.GetHash())); - nInvCount++; - } - } - ++it4; - } - } - ++it3; - } - - pfrom->PushMessage(NetMsgType::SYNCSTATUSCOUNT, MASTERNODE_SYNC_BUDGET_FIN, nInvCount); - LogPrintf("CBudgetManager::Sync - sent %d items\n", nInvCount); - -} - -void CBudgetManager::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv) -{ - // lite mode is not supported - if(fLiteMode) return; - if(!masternodeSync.IsBlockchainSynced()) return; - - LOCK(cs_budget); - - // todo : 12.1 - split out into two messages - // --- one for finalized budgets and one for gov objs - if (strCommand == NetMsgType::MNGOVERNANCEVOTESYNC) { //Masternode vote sync - uint256 nProp; - vRecv >> nProp; - - if(Params().NetworkIDString() == CBaseChainParams::MAIN){ - if(nProp == uint256()) { - if(pfrom->HasFulfilledRequest(NetMsgType::MNGOVERNANCEVOTESYNC)) { - LogPrintf("mnvs - peer already asked me for the list\n"); - Misbehaving(pfrom->GetId(), 20); - return; - } - pfrom->FulfilledRequest(NetMsgType::MNGOVERNANCEVOTESYNC); - } - } - - Sync(pfrom, nProp); - LogPrintf("mnvs - Sent Masternode votes to %s\n", pfrom->addr.ToString()); - } - - if (strCommand == NetMsgType::MNGOVERNANCEFINAL) { //Finalized Budget Suggestion - CFinalizedBudget finalizedBudgetBroadcast; - vRecv >> finalizedBudgetBroadcast; - - if(mapSeenFinalizedBudgets.count(finalizedBudgetBroadcast.GetHash())){ - masternodeSync.AddedBudgetItem(finalizedBudgetBroadcast.GetHash()); - return; - } - - std::string strError = ""; - int nConf = 0; - if(!IsCollateralValid(finalizedBudgetBroadcast.nFeeTXHash, finalizedBudgetBroadcast.GetHash(), strError, finalizedBudgetBroadcast.nTime, nConf, GOVERNANCE_FEE_TX)){ - LogPrintf("Finalized Budget FeeTX is not valid - %s - %s\n", finalizedBudgetBroadcast.nFeeTXHash.ToString(), strError); - - if(nConf >= 1) vecImmatureFinalizedBudgets.push_back(finalizedBudgetBroadcast); - return; - } - - mapSeenFinalizedBudgets.insert(make_pair(finalizedBudgetBroadcast.GetHash(), finalizedBudgetBroadcast)); - - if(!finalizedBudgetBroadcast.IsValid(pCurrentBlockIndex, strError)) { - LogPrintf("fbs - invalid finalized budget - %s\n", strError); - return; - } - - LogPrintf("fbs - new finalized budget - %s\n", finalizedBudgetBroadcast.GetHash().ToString()); - - CFinalizedBudget finalizedBudget(finalizedBudgetBroadcast); - if(AddFinalizedBudget(finalizedBudget)) {finalizedBudgetBroadcast.Relay();} - masternodeSync.AddedBudgetItem(finalizedBudgetBroadcast.GetHash()); - - //we might have active votes for this budget that are now valid - CheckOrphanVotes(); - } - - if (strCommand == NetMsgType::MNGOVERNANCEFINALVOTE) { //Finalized Budget Vote - CGovernanceVote vote; - vRecv >> vote; - vote.fValid = true; - - if(mapSeenFinalizedBudgetVotes.count(vote.GetHash())){ - masternodeSync.AddedBudgetItem(vote.GetHash()); - return; - } - - CMasternode* pmn = mnodeman.Find(vote.vin); - if(pmn == NULL) { - LogPrint("mngovernance", "fbvote - unknown masternode - vin: %s\n", vote.vin.ToString()); - mnodeman.AskForMN(pfrom, vote.vin); - return; - } - - mapSeenFinalizedBudgetVotes.insert(make_pair(vote.GetHash(), vote)); - - if(!vote.IsValid(true)){ - if(masternodeSync.IsSynced()) Misbehaving(pfrom->GetId(), 20); - // it could just be a non-synced masternode - mnodeman.AskForMN(pfrom, vote.vin); - return; - } - - std::string strError = ""; - if(UpdateFinalizedBudget(vote, pfrom, strError)) { - vote.Relay(); - masternodeSync.AddedBudgetItem(vote.GetHash()); - - LogPrintf("fbvote - new finalized budget vote - %s\n", vote.GetHash().ToString()); - } else { - LogPrintf("fbvote - rejected finalized budget vote - %s - %s\n", vote.GetHash().ToString(), strError); - } - } -} - -void CBudgetManager::NewBlock() -{ - TRY_LOCK(cs, fBudgetNewBlock); - if(!fBudgetNewBlock) return; - - if(!pCurrentBlockIndex) return; - - if (masternodeSync.RequestedMasternodeAssets <= MASTERNODE_SYNC_BUDGET) return; - - if (strBudgetMode == "suggest") { //suggest the budget we see - SubmitFinalBudget(); - } - - //this function should be called 1/6 blocks, allowing up to 100 votes per day on all proposals - if(pCurrentBlockIndex->nHeight % 6 != 0) return; - - // incremental sync with our peers - std::map::iterator it3 = mapFinalizedBudgets.begin(); - while(it3 != mapFinalizedBudgets.end()){ - (*it3).second.CleanAndRemove(false); - ++it3; - } - - std::vector::iterator it5 = vecImmatureFinalizedBudgets.begin(); - while(it5 != vecImmatureFinalizedBudgets.end()) - { - std::string strError = ""; - int nConf = 0; - if(!IsCollateralValid((*it5).nFeeTXHash, (*it5).GetHash(), strError, (*it5).nTime, nConf, GOVERNANCE_FEE_TX)){ - ++it5; - continue; - } - - if(!(*it5).IsValid(pCurrentBlockIndex, 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); - } -} - -CFinalizedBudget *CBudgetManager::FindFinalizedBudget(uint256 nHash) -{ - if(mapFinalizedBudgets.count(nHash)) - return &mapFinalizedBudgets[nHash]; - - return NULL; -} - -CAmount CBudgetManager::GetTotalBudget(int nHeight) -{ - if(!pCurrentBlockIndex) return 0; - - //get min block value and calculate from that - CAmount nSubsidy = 5 * COIN; - - const Consensus::Params consensusParams = Params().GetConsensus(); - - // TODO: Remove this to further unify logic among mainnet/testnet/whatevernet, - // use single formula instead (the one that is for current mainnet). - // Probably a good idea to use a significally lower consensusParams.nSubsidyHalvingInterval - // for testnet (like 10 times for example) to see the effect of halving there faster. - // Will require testnet restart. - if(Params().NetworkIDString() == CBaseChainParams::TESTNET){ - for(int i = 46200; i <= nHeight; i += consensusParams.nSubsidyHalvingInterval) nSubsidy -= nSubsidy/14; - } else { - // yearly decline of production by 7.1% per year, projected 21.3M coins max by year 2050. - for(int i = consensusParams.nSubsidyHalvingInterval; i <= nHeight; i += consensusParams.nSubsidyHalvingInterval) nSubsidy -= nSubsidy/14; - } - - // 10% - return ((nSubsidy/100)*10)*consensusParams.nBudgetPaymentsCycleBlocks; -} - -std::vector CBudgetManager::GetFinalizedBudgets() -{ - LOCK(cs); - - std::vector vFinalizedBudgetsRet; - std::vector > vFinalizedBudgetsSort; - - // ------- Grab The Budgets In Order - - std::map::iterator it = mapFinalizedBudgets.begin(); - while(it != mapFinalizedBudgets.end()) - { - CFinalizedBudget* pfinalizedBudget = &((*it).second); - - vFinalizedBudgetsSort.push_back(make_pair(pfinalizedBudget, pfinalizedBudget->GetVoteCount())); - ++it; - } - std::sort(vFinalizedBudgetsSort.begin(), vFinalizedBudgetsSort.end(), sortFinalizedBudgetsByVotes()); - - std::vector >::iterator it2 = vFinalizedBudgetsSort.begin(); - while(it2 != vFinalizedBudgetsSort.end()) - { - vFinalizedBudgetsRet.push_back((*it2).first); - ++it2; - } - - return vFinalizedBudgetsRet; -} - -bool CBudgetManager::IsBudgetPaymentBlock(int nBlockHeight) -{ - int nHighestCount = -1; - - std::map::iterator it = mapFinalizedBudgets.begin(); - while(it != mapFinalizedBudgets.end()) - { - CFinalizedBudget* pfinalizedBudget = &((*it).second); - if(pfinalizedBudget->GetVoteCount() > nHighestCount && - nBlockHeight >= pfinalizedBudget->GetBlockStart() && - nBlockHeight <= pfinalizedBudget->GetBlockEnd()){ - nHighestCount = pfinalizedBudget->GetVoteCount(); - } - - ++it; - } - - /* - If budget doesn't have 5% of the network votes, then we should pay a masternode instead - */ - if(nHighestCount > mnodeman.CountEnabled(MIN_BUDGET_PEER_PROTO_VERSION)/20) return true; - - return false; -} - -bool CBudgetManager::AddFinalizedBudget(CFinalizedBudget& finalizedBudget) -{ - std::string strError = ""; - if(!finalizedBudget.IsValid(pCurrentBlockIndex, strError)) return false; - - if(mapFinalizedBudgets.count(finalizedBudget.GetHash())) { - return false; - } - - mapFinalizedBudgets.insert(make_pair(finalizedBudget.GetHash(), finalizedBudget)); - return true; -} - -bool CBudgetManager::HasNextFinalizedBudget() -{ - if(!pCurrentBlockIndex) return false; - - if(masternodeSync.IsBudgetFinEmpty()) return true; - - int nBlockStart = pCurrentBlockIndex->nHeight - pCurrentBlockIndex->nHeight % Params().GetConsensus().nBudgetPaymentsCycleBlocks + Params().GetConsensus().nBudgetPaymentsCycleBlocks; - if(nBlockStart - pCurrentBlockIndex->nHeight > 576*2) return true; //we wouldn't have the budget yet - - if(IsBudgetPaymentBlock(nBlockStart)) return true; - - LogPrintf("CBudgetManager::HasNextFinalizedBudget() - Client is missing budget - %lli\n", nBlockStart); - - return false; -} - -bool CBudgetManager::UpdateFinalizedBudget(CGovernanceVote& vote, CNode* pfrom, std::string& strError) -{ - LOCK(cs); - - if(!mapFinalizedBudgets.count(vote.nBudgetHash)){ - if(pfrom){ - // only ask for missing items after our syncing process is complete -- - // otherwise we'll think a full sync succeeded when they return a result - if(!masternodeSync.IsSynced()) return false; - - LogPrintf("CBudgetManager::UpdateFinalizedBudget - Unknown Finalized Proposal %s, asking for source budget\n", vote.nBudgetHash.ToString()); - mapOrphanFinalizedBudgetVotes[vote.nBudgetHash] = vote; - - if(!mapAskedForGovernanceObject.count(vote.nBudgetHash)){ - pfrom->PushMessage(NetMsgType::MNGOVERNANCEVOTESYNC, vote.nBudgetHash); - mapAskedForGovernanceObject[vote.nBudgetHash] = GetTime(); - } - - } - - strError = "Finalized Budget not found!"; - return false; - } - - return mapFinalizedBudgets[vote.nBudgetHash].AddOrUpdateVote(vote, strError); -} - -// todo - 12.1 - terrible name - how about IsBlockTransactionValid -bool CBudgetManager::IsTransactionValid(const CTransaction& txNew, int nBlockHeight) -{ - LOCK(cs); - - int nHighestCount = 0; - std::vector ret; - - // ------- Grab The Highest Count - - std::map::iterator it = mapFinalizedBudgets.begin(); - while(it != mapFinalizedBudgets.end()) - { - CFinalizedBudget* pfinalizedBudget = &((*it).second); - if(pfinalizedBudget->GetVoteCount() > nHighestCount && - nBlockHeight >= pfinalizedBudget->GetBlockStart() && - nBlockHeight <= pfinalizedBudget->GetBlockEnd()){ - nHighestCount = pfinalizedBudget->GetVoteCount(); - } - - ++it; - } - - /* - If budget doesn't have 5% of the network votes, then we should pay a masternode instead - */ - if(nHighestCount < mnodeman.CountEnabled(MIN_BUDGET_PEER_PROTO_VERSION)/20) return false; - - // check the highest finalized budgets (+/- 10% to assist in consensus) - - it = mapFinalizedBudgets.begin(); - while(it != mapFinalizedBudgets.end()) - { - CFinalizedBudget* pfinalizedBudget = &((*it).second); - - if(pfinalizedBudget->GetVoteCount() > nHighestCount - mnodeman.CountEnabled(MIN_BUDGET_PEER_PROTO_VERSION)/10){ - if(nBlockHeight >= pfinalizedBudget->GetBlockStart() && nBlockHeight <= pfinalizedBudget->GetBlockEnd()){ - if(pfinalizedBudget->IsTransactionValid(txNew, nBlockHeight)){ - return true; - } - } - } - - ++it; - } - - //we looked through all of the known budgets - return false; -} - -std::string CBudgetManager::GetRequiredPaymentsString(int nBlockHeight) -{ - LOCK(cs); - - std::string ret = "unknown-budget"; - - std::map::iterator it = mapFinalizedBudgets.begin(); - while(it != mapFinalizedBudgets.end()) - { - CFinalizedBudget* pfinalizedBudget = &((*it).second); - if(nBlockHeight >= pfinalizedBudget->GetBlockStart() && nBlockHeight <= pfinalizedBudget->GetBlockEnd()){ - CTxBudgetPayment payment; - if(pfinalizedBudget->GetBudgetPaymentByBlock(nBlockHeight, payment)){ - if(ret == "unknown-budget"){ - ret = payment.nProposalHash.ToString(); - } else { - ret += ","; - ret += payment.nProposalHash.ToString(); - } - } else { - LogPrintf("CBudgetManager::GetRequiredPaymentsString - Couldn't find budget payment for block %d\n", nBlockHeight); - } - } - - ++it; - } - - return ret; -} - -void CBudgetManager::FillBlockPayee(CMutableTransaction& txNew, CAmount nFees) -{ - LOCK(cs); - - AssertLockHeld(cs_main); - if(!chainActive.Tip()) return; - - int nHighestCount = 0; - CScript payee; - CAmount nAmount = 0; - - // ------- Grab The Highest Count - - std::map::iterator it = mapFinalizedBudgets.begin(); - while(it != mapFinalizedBudgets.end()) - { - CFinalizedBudget* pfinalizedBudget = &((*it).second); - if(pfinalizedBudget->GetVoteCount() > nHighestCount && - chainActive.Tip()->nHeight + 1 >= pfinalizedBudget->GetBlockStart() && - chainActive.Tip()->nHeight + 1 <= pfinalizedBudget->GetBlockEnd() && - pfinalizedBudget->GetPayeeAndAmount(chainActive.Tip()->nHeight + 1, payee, nAmount)){ - nHighestCount = pfinalizedBudget->GetVoteCount(); - } - - ++it; - } - - //miners get the full amount on these blocks - txNew.vout[0].nValue = nFees + GetBlockSubsidy(chainActive.Tip()->nBits, chainActive.Tip()->nHeight, Params().GetConsensus()); - - if(nHighestCount > 0){ - txNew.vout.resize(2); - - //these are super blocks, so their value can be much larger than normal - txNew.vout[1].scriptPubKey = payee; - txNew.vout[1].nValue = nAmount; - - CTxDestination address1; - ExtractDestination(payee, address1); - CBitcoinAddress address2(address1); - - LogPrintf("CBudgetManager::FillBlockPayee - Budget payment to %s for %lld\n", address2.ToString(), nAmount); - } - -} - - -void CBudgetManager::CheckOrphanVotes() -{ - LOCK(cs); - - std::string strError = ""; - - std::map::iterator it2 = mapOrphanFinalizedBudgetVotes.begin(); - while(it2 != mapOrphanFinalizedBudgetVotes.end()){ - if(UpdateFinalizedBudget(((*it2).second),NULL, strError)){ - LogPrintf("CBudgetManager::CheckOrphanVotes - Proposal/Budget is known, activating and removing orphan vote\n"); - mapOrphanFinalizedBudgetVotes.erase(it2++); - } else { - ++it2; - } - } -} - -void CBudgetManager::CheckAndRemove() -{ - LogPrintf("CBudgetManager::CheckAndRemove \n"); - - if(!pCurrentBlockIndex) return; - - std::string strError = ""; - std::map::iterator it = mapFinalizedBudgets.begin(); - while(it != mapFinalizedBudgets.end()) - { - CFinalizedBudget* pfinalizedBudget = &((*it).second); - - pfinalizedBudget->fValid = pfinalizedBudget->IsValid(pCurrentBlockIndex, strError); - if(pfinalizedBudget->fValid) { - pfinalizedBudget->AutoCheck(); - ++it; - continue; - } else if(pfinalizedBudget->nBlockStart != 0 && pfinalizedBudget->nBlockStart < pCurrentBlockIndex->nHeight - Params().GetConsensus().nBudgetPaymentsCycleBlocks) { - // it's too old, remove it - mapFinalizedBudgets.erase(it++); - LogPrintf("CBudgetManager::CheckAndRemove - removing budget %s\n", pfinalizedBudget->GetHash().ToString()); - continue; - } - // it's not valid already but it's not too old yet, keep it and move to the next one - ++it; - } -} - -std::string CBudgetManager::ToString() const -{ - std::ostringstream info; - - info << "Budgets: " << (int)mapFinalizedBudgets.size() << - ", Seen Final Budgets: " << (int)mapSeenFinalizedBudgets.size() << - ", Seen Final Budget Votes: " << (int)mapSeenFinalizedBudgetVotes.size(); - - return info.str(); -} - -// todo - 12.1 - rename : UpdateBlockTip -void CBudgetManager::UpdatedBlockTip(const CBlockIndex *pindex) -{ - pCurrentBlockIndex = pindex; - LogPrint("mngovernance", "pCurrentBlockIndex->nHeight: %d\n", pCurrentBlockIndex->nHeight); - - if(!fLiteMode && masternodeSync.RequestedMasternodeAssets > MASTERNODE_SYNC_LIST) - NewBlock(); -} - -/* - * Class : CFinalizedBudget - * -------------------- - * Holds a proposed finalized budget - * -*/ - - -CFinalizedBudget::CFinalizedBudget() -{ - strBudgetName = ""; - nBlockStart = 0; - vecBudgetPayments.clear(); - mapVotes.clear(); - nFeeTXHash = uint256(); - nTime = 0; - fValid = true; - fAutoChecked = false; -} - -CFinalizedBudget::CFinalizedBudget(const CFinalizedBudget& other) -{ - strBudgetName = other.strBudgetName; - nBlockStart = other.nBlockStart; - vecBudgetPayments = other.vecBudgetPayments; - mapVotes = other.mapVotes; - nFeeTXHash = other.nFeeTXHash; - nTime = other.nTime; - fValid = true; - fAutoChecked = false; -} - -bool CFinalizedBudget::AddOrUpdateVote(CGovernanceVote& vote, std::string& strError) -{ - LOCK(cs); - - uint256 hash = vote.vin.prevout.GetHash(); - if(mapVotes.count(hash)){ - if(mapVotes[hash].nTime > vote.nTime){ - strError = strprintf("new vote older than existing vote - %s", vote.GetHash().ToString()); - LogPrint("mngovernance", "CFinalizedBudget::AddOrUpdateVote - %s\n", strError); - return false; - } - if(vote.nTime - mapVotes[hash].nTime < GOVERNANCE_VOTE_UPDATE_MIN){ - strError = strprintf("time between votes is too soon - %s - %lli", vote.GetHash().ToString(), vote.nTime - mapVotes[hash].nTime); - LogPrint("mngovernance", "CFinalizedBudget::AddOrUpdateVote - %s\n", strError); - return false; - } - } - - mapVotes[hash] = vote; - return true; -} - -//evaluate if we should vote for this. Masternode only -void CFinalizedBudget::AutoCheck() -{ - LOCK(cs); - - CBlockIndex* pindexPrev = chainActive.Tip(); - if(!pindexPrev) return; - - LogPrintf("CFinalizedBudget::AutoCheck - %lli - %d\n", pindexPrev->nHeight, fAutoChecked); - - if(!fMasterNode || fAutoChecked) return; - - //do this 1 in 4 blocks -- spread out the voting activity on mainnet - // -- this function is only called every sixth block, so this is really 1 in 24 blocks - if(Params().NetworkIDString() == CBaseChainParams::MAIN && rand() % 4 != 0) { - LogPrintf("CFinalizedBudget::AutoCheck - waiting\n"); - return; - } - - fAutoChecked = true; //we only need to check this once - - - if(strBudgetMode == "auto") //only vote for exact matches - { - std::vector vBudgetProposals = budget.GetBudget(); - - - for(unsigned int i = 0; i < vecBudgetPayments.size(); i++){ - LogPrintf("CFinalizedBudget::AutoCheck - nProp %d %s\n", i, vecBudgetPayments[i].nProposalHash.ToString()); - LogPrintf("CFinalizedBudget::AutoCheck - Payee %d %s\n", i, ScriptToAsmStr(vecBudgetPayments[i].payee)); - LogPrintf("CFinalizedBudget::AutoCheck - nAmount %d %lli\n", i, vecBudgetPayments[i].nAmount); - } - - for(unsigned int i = 0; i < vBudgetProposals.size(); i++){ - LogPrintf("CFinalizedBudget::AutoCheck - nProp %d %s\n", i, vBudgetProposals[i]->GetHash().ToString()); - LogPrintf("CFinalizedBudget::AutoCheck - Payee %d %s\n", i, ScriptToAsmStr(vBudgetProposals[i]->GetPayee())); - LogPrintf("CFinalizedBudget::AutoCheck - nAmount %d %lli\n", i, vBudgetProposals[i]->GetAmount()); - } - - if(vBudgetProposals.size() == 0) { - LogPrintf("CFinalizedBudget::AutoCheck - Can't get Budget, aborting\n"); - return; - } - - if(vBudgetProposals.size() != vecBudgetPayments.size()) { - LogPrintf("CFinalizedBudget::AutoCheck - Budget length doesn't match\n"); - return; - } - - - for(unsigned int i = 0; i < vecBudgetPayments.size(); i++){ - if(i > vBudgetProposals.size() - 1) { - LogPrintf("CFinalizedBudget::AutoCheck - Vector size mismatch, aborting\n"); - return; - } - - if(vecBudgetPayments[i].nProposalHash != vBudgetProposals[i]->GetHash()){ - LogPrintf("CFinalizedBudget::AutoCheck - item #%d doesn't match %s %s\n", i, vecBudgetPayments[i].nProposalHash.ToString(), vBudgetProposals[i]->GetHash().ToString()); - return; - } - - // if(vecBudgetPayments[i].payee != vBudgetProposals[i]->GetPayee()){ -- triggered with false positive - if(vecBudgetPayments[i].payee != vBudgetProposals[i]->GetPayee()){ - LogPrintf("CFinalizedBudget::AutoCheck - item #%d payee doesn't match %s %s\n", i, ScriptToAsmStr(vecBudgetPayments[i].payee), ScriptToAsmStr(vBudgetProposals[i]->GetPayee())); - return; - } - - if(vecBudgetPayments[i].nAmount != vBudgetProposals[i]->GetAmount()){ - LogPrintf("CFinalizedBudget::AutoCheck - item #%d payee doesn't match %lli %lli\n", i, vecBudgetPayments[i].nAmount, vBudgetProposals[i]->GetAmount()); - return; - } - } - - LogPrintf("CFinalizedBudget::AutoCheck - Finalized Budget Matches! Submitting Vote.\n"); - SubmitVote(); - - } -} -// If masternode voted for a proposal, but is now invalid -- remove the vote -void CFinalizedBudget::CleanAndRemove(bool fSignatureCheck) -{ - std::map::iterator it = mapVotes.begin(); - - while(it != mapVotes.end()) { - (*it).second.fValid = (*it).second.IsValid(fSignatureCheck); - ++it; - } -} - - -CAmount CFinalizedBudget::GetTotalPayout() -{ - CAmount ret = 0; - - for(unsigned int i = 0; i < vecBudgetPayments.size(); i++){ - ret += vecBudgetPayments[i].nAmount; - } - - return ret; -} - -std::string CFinalizedBudget::GetProposals() -{ - LOCK(cs); - std::string ret = ""; - - BOOST_FOREACH(CTxBudgetPayment& budgetPayment, vecBudgetPayments){ - CGovernanceObject* pbudgetProposal = governance.FindGovernanceObject(budgetPayment.nProposalHash); - - std::string token = budgetPayment.nProposalHash.ToString(); - - if(pbudgetProposal) token = pbudgetProposal->GetName(); - if(ret == "") {ret = token;} - else {ret += "," + token;} - } - return ret; -} - -std::string CFinalizedBudget::GetStatus() -{ - std::string retBadHashes = ""; - std::string retBadPayeeOrAmount = ""; - - for(int nBlockHeight = GetBlockStart(); nBlockHeight <= GetBlockEnd(); nBlockHeight++) - { - CTxBudgetPayment budgetPayment; - if(!GetBudgetPaymentByBlock(nBlockHeight, budgetPayment)){ - LogPrintf("CFinalizedBudget::GetStatus - Couldn't find budget payment for block %lld\n", nBlockHeight); - continue; - } - - CGovernanceObject* pbudgetProposal = governance.FindGovernanceObject(budgetPayment.nProposalHash); - if(!pbudgetProposal){ - if(retBadHashes == ""){ - retBadHashes = "Unknown proposal hash! Check this proposal before voting" + budgetPayment.nProposalHash.ToString(); - } else { - retBadHashes += "," + budgetPayment.nProposalHash.ToString(); - } - } else { - if(pbudgetProposal->GetPayee() != budgetPayment.payee || pbudgetProposal->GetAmount() != budgetPayment.nAmount) - { - if(retBadPayeeOrAmount == ""){ - retBadPayeeOrAmount = "Budget payee/nAmount doesn't match our proposal! " + budgetPayment.nProposalHash.ToString(); - } else { - retBadPayeeOrAmount += "," + budgetPayment.nProposalHash.ToString(); - } - } - } - } - - if(retBadHashes == "" && retBadPayeeOrAmount == "") return "OK"; - - return retBadHashes + retBadPayeeOrAmount; -} - -bool CFinalizedBudget::IsValid(const CBlockIndex* pindex, std::string& strError, bool fCheckCollateral) -{ - //must be the correct block for payment to happen (once a month) - if(nBlockStart % Params().GetConsensus().nBudgetPaymentsCycleBlocks != 0) {strError = "Invalid BlockStart"; return false;} - if(GetBlockEnd() - nBlockStart > Params().GetConsensus().nBudgetPaymentsWindowBlocks) {strError = "Invalid BlockEnd"; return false;} - if((int)vecBudgetPayments.size() > Params().GetConsensus().nBudgetPaymentsWindowBlocks) {strError = "Invalid budget payments count (too many)"; return false;} - if(strBudgetName == "") {strError = "Invalid Budget Name"; return false;} - if(nBlockStart == 0) {strError = "Invalid BlockStart == 0"; return false;} - if(nFeeTXHash == uint256()) {strError = "Invalid FeeTx == 0"; return false;} - - //can only pay out 10% of the possible coins (min value of coins) - if(GetTotalPayout() > budget.GetTotalBudget(nBlockStart)) {strError = "Invalid Payout (more than max)"; return false;} - - std::string strError2 = ""; - if(fCheckCollateral){ - int nConf = 0; - if(!IsCollateralValid(nFeeTXHash, GetHash(), strError2, nTime, nConf, GOVERNANCE_FEE_TX)){ - strError = "Invalid Collateral : " + strError2; - return false; - } - } - - //TODO: if N cycles old, invalid, invalid - - if(!pindex) return true; - - if(nBlockStart < pindex->nHeight - Params().GetConsensus().nBudgetPaymentsWindowBlocks) { - strError = "Older than current blockHeight"; - return false; - } - - return true; -} - -bool CFinalizedBudget::IsTransactionValid(const CTransaction& txNew, int nBlockHeight) -{ - int nCurrentBudgetPayment = nBlockHeight - GetBlockStart(); - if(nCurrentBudgetPayment < 0) { - LogPrintf("CFinalizedBudget::IsTransactionValid - Invalid block - height: %d start: %d\n", nBlockHeight, GetBlockStart()); - return false; - } - - if(nCurrentBudgetPayment > (int)vecBudgetPayments.size() - 1) { - LogPrintf("CFinalizedBudget::IsTransactionValid - Invalid block - current budget payment: %d of %d\n", nCurrentBudgetPayment + 1, (int)vecBudgetPayments.size()); - return false; - } - - bool found = false; - BOOST_FOREACH(CTxOut out, txNew.vout) - { - if(vecBudgetPayments[nCurrentBudgetPayment].payee == out.scriptPubKey && vecBudgetPayments[nCurrentBudgetPayment].nAmount == out.nValue) - found = true; - } - if(!found) { - CTxDestination address1; - ExtractDestination(vecBudgetPayments[nCurrentBudgetPayment].payee, address1); - CBitcoinAddress address2(address1); - - LogPrintf("CFinalizedBudget::IsTransactionValid - Missing required payment - %s: %d\n", address2.ToString(), vecBudgetPayments[nCurrentBudgetPayment].nAmount); - } - - return found; -} - -void CFinalizedBudget::SubmitVote() -{ - CPubKey pubKeyMasternode; - CKey keyMasternode; - std::string errorMessage; - - if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, keyMasternode, pubKeyMasternode)){ - LogPrintf("CFinalizedBudget::SubmitVote - Error upon calling SetKey\n"); - return; - } - - CGovernanceVote vote(activeMasternode.vin, GetHash()); - if(!vote.Sign(keyMasternode, pubKeyMasternode)){ - LogPrintf("CFinalizedBudget::SubmitVote - Failure to sign."); - return; - } - - std::string strError = ""; - if(budget.UpdateFinalizedBudget(vote, NULL, strError)){ - LogPrintf("CFinalizedBudget::SubmitVote - new finalized budget vote - %s\n", vote.GetHash().ToString()); - - budget.mapSeenFinalizedBudgetVotes.insert(make_pair(vote.GetHash(), vote)); - vote.Relay(); - } else { - LogPrintf("CFinalizedBudget::SubmitVote : Error submitting vote - %s\n", strError); - } -} - -CFinalizedBudget::CFinalizedBudget() -{ - strBudgetName = ""; - nBlockStart = 0; - vecBudgetPayments.clear(); - mapVotes.clear(); - vchSig.clear(); - nFeeTXHash = uint256(); -} - -CFinalizedBudget::CFinalizedBudget(const CFinalizedBudget& other) -{ - strBudgetName = other.strBudgetName; - nBlockStart = other.nBlockStart; - BOOST_FOREACH(CTxBudgetPayment out, other.vecBudgetPayments) vecBudgetPayments.push_back(out); - mapVotes = other.mapVotes; - nFeeTXHash = other.nFeeTXHash; -} - -CFinalizedBudget::CFinalizedBudget(std::string strBudgetNameIn, int nBlockStartIn, std::vector vecBudgetPaymentsIn, uint256 nFeeTXHashIn) -{ - strBudgetName = strBudgetNameIn; - nBlockStart = nBlockStartIn; - BOOST_FOREACH(CTxBudgetPayment out, vecBudgetPaymentsIn) vecBudgetPayments.push_back(out); - mapVotes.clear(); - nFeeTXHash = nFeeTXHashIn; -} - -void CFinalizedBudget::Relay() -{ - CInv inv(MSG_BUDGET_FINALIZED, GetHash()); - RelayInv(inv, MIN_BUDGET_PEER_PROTO_VERSION); -} - -CGovernanceVote::CGovernanceVote() -{ - vin = CTxIn(); - nBudgetHash = uint256(); - nTime = 0; - vchSig.clear(); - fValid = true; - fSynced = false; -} - -CGovernanceVote::CGovernanceVote(CTxIn vinIn, uint256 nBudgetHashIn) -{ - vin = vinIn; - nBudgetHash = nBudgetHashIn; - nTime = GetAdjustedTime(); - vchSig.clear(); - fValid = true; - fSynced = false; -} - -void CGovernanceVote::Relay() -{ - CInv inv(MSG_BUDGET_FINALIZED_VOTE, GetHash()); - RelayInv(inv, MIN_BUDGET_PEER_PROTO_VERSION); -} - -bool CGovernanceVote::Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode) -{ - // Choose coins to use - CPubKey pubKeyCollateralAddress; - CKey keyCollateralAddress; - - std::string errorMessage; - std::string strMessage = vin.prevout.ToStringShort() + nBudgetHash.ToString() + boost::lexical_cast(nTime); - - if(!darkSendSigner.SignMessage(strMessage, errorMessage, vchSig, keyMasternode)) { - LogPrintf("CGovernanceVote::Sign - Error upon calling SignMessage"); - return false; - } - - if(!darkSendSigner.VerifyMessage(pubKeyMasternode, vchSig, strMessage, errorMessage)) { - LogPrintf("CGovernanceVote::Sign - Error upon calling VerifyMessage"); - return false; - } - - return true; -} - -bool CGovernanceVote::IsValid(bool fSignatureCheck) -{ - if(nTime > GetTime() + (60*60)){ - LogPrint("mngovernance", "CGovernanceVote::IsValid() - vote is too far ahead of current time - %s - nTime %lli - Max Time %lli\n", GetHash().ToString(), nTime, GetTime() + (60*60)); - return false; - } - - CMasternode* pmn = mnodeman.Find(vin); - - if(pmn == NULL) - { - LogPrint("mngovernance", "CGovernanceVote::IsValid() - Unknown Masternode\n"); - return false; - } - - if(!fSignatureCheck) return true; - - std::string errorMessage; - std::string strMessage = vin.prevout.ToStringShort() + nBudgetHash.ToString() + boost::lexical_cast(nTime); - - if(!darkSendSigner.VerifyMessage(pmn->pubkey2, vchSig, strMessage, errorMessage)) { - LogPrintf("CGovernanceVote::IsValid() - Verify message failed\n"); - return false; - } - - return true; -} - diff --git a/src/masternode-payments.cpp b/src/masternode-payments.cpp index 1d842b2da..c7d51e63a 100644 --- a/src/masternode-payments.cpp +++ b/src/masternode-payments.cpp @@ -21,167 +21,6 @@ CCriticalSection cs_vecPayments; CCriticalSection cs_mapMasternodeBlocks; CCriticalSection cs_mapMasternodePayeeVotes; -// -// CMasternodePaymentDB -// - -CMasternodePaymentDB::CMasternodePaymentDB() -{ - pathDB = GetDataDir() / "mnpayments.dat"; - strMagicMessage = "MasternodePayments"; -} - -bool CMasternodePaymentDB::Write(const CMasternodePayments& objToSave) -{ - int64_t nStart = GetTimeMillis(); - - // serialize, checksum data up to that point, then append checksum - CDataStream ssObj(SER_DISK, CLIENT_VERSION); - ssObj << strMagicMessage; // masternode cache file specific magic message - ssObj << FLATDATA(Params().MessageStart()); // network specific magic number - ssObj << objToSave; - uint256 hash = Hash(ssObj.begin(), ssObj.end()); - ssObj << hash; - - // open output file, and associate with CAutoFile - FILE *file = fopen(pathDB.string().c_str(), "wb"); - CAutoFile fileout(file, SER_DISK, CLIENT_VERSION); - if (fileout.IsNull()) - return error("%s : Failed to open file %s", __func__, pathDB.string()); - - // Write and commit header, data - try { - fileout << ssObj; - } - catch (std::exception &e) { - return error("%s : Serialize or I/O error - %s", __func__, e.what()); - } - fileout.fclose(); - - LogPrintf("Written info to mnpayments.dat %dms\n", GetTimeMillis() - nStart); - - return true; -} - -CMasternodePaymentDB::ReadResult CMasternodePaymentDB::Read(CMasternodePayments& objToLoad, bool fDryRun) -{ - - int64_t nStart = GetTimeMillis(); - // open input file, and associate with CAutoFile - FILE *file = fopen(pathDB.string().c_str(), "rb"); - CAutoFile filein(file, SER_DISK, CLIENT_VERSION); - if (filein.IsNull()) - { - error("%s : Failed to open file %s", __func__, pathDB.string()); - return FileError; - } - - // use file size to size memory buffer - int fileSize = boost::filesystem::file_size(pathDB); - int dataSize = fileSize - sizeof(uint256); - // Don't try to resize to a negative number if file is small - if (dataSize < 0) - dataSize = 0; - vector vchData; - vchData.resize(dataSize); - uint256 hashIn; - - // read data and checksum from file - try { - filein.read((char *)&vchData[0], dataSize); - filein >> hashIn; - } - catch (std::exception &e) { - error("%s : Deserialize or I/O error - %s", __func__, e.what()); - return HashReadError; - } - filein.fclose(); - - CDataStream ssObj(vchData, SER_DISK, CLIENT_VERSION); - - // verify stored checksum matches input data - uint256 hashTmp = Hash(ssObj.begin(), ssObj.end()); - if (hashIn != hashTmp) - { - error("%s : Checksum mismatch, data corrupted", __func__); - return IncorrectHash; - } - - - unsigned char pchMsgTmp[4]; - std::string strMagicMessageTmp; - try { - // de-serialize file header (masternode cache file specific magic message) and .. - ssObj >> strMagicMessageTmp; - - // ... verify the message matches predefined one - if (strMagicMessage != strMagicMessageTmp) - { - error("%s : Invalid masternode payement cache magic message", __func__); - return IncorrectMagicMessage; - } - - - // de-serialize file header (network specific magic number) and .. - ssObj >> FLATDATA(pchMsgTmp); - - // ... verify the network matches ours - if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp))) - { - error("%s : Invalid network magic number", __func__); - return IncorrectMagicNumber; - } - - // de-serialize data into CMasternodePayments object - ssObj >> objToLoad; - } - catch (std::exception &e) { - objToLoad.Clear(); - error("%s : Deserialize or I/O error - %s", __func__, e.what()); - return IncorrectFormat; - } - - LogPrintf("Loaded info from mnpayments.dat %dms\n", GetTimeMillis() - nStart); - LogPrintf(" %s\n", objToLoad.ToString()); - if(!fDryRun) { - LogPrintf("Masternode payments manager - cleaning....\n"); - objToLoad.CheckAndRemove(); - LogPrintf("Masternode payments manager - result:\n"); - LogPrintf(" %s\n", objToLoad.ToString()); - } - - return Ok; -} - -void DumpMasternodePayments() -{ - int64_t nStart = GetTimeMillis(); - - CMasternodePaymentDB paymentdb; - CMasternodePayments tempPayments; - - LogPrintf("Verifying mnpayments.dat format...\n"); - CMasternodePaymentDB::ReadResult readResult = paymentdb.Read(tempPayments, true); - // there was an error and it was not an error on file opening => do not proceed - if (readResult == CMasternodePaymentDB::FileError) - LogPrintf("Missing budgets file - mnpayments.dat, will try to recreate\n"); - else if (readResult != CMasternodePaymentDB::Ok) - { - LogPrintf("Error reading mnpayments.dat: "); - if(readResult == CMasternodePaymentDB::IncorrectFormat) - LogPrintf("magic is ok but data has invalid format, will try to recreate\n"); - else - { - LogPrintf("file format is unknown or invalid, please fix it manually\n"); - return; - } - } - LogPrintf("Writting info to mnpayments.dat...\n"); - paymentdb.Write(mnpayments); - - LogPrintf("Budget dump finished %dms\n", GetTimeMillis() - nStart); -} - bool IsBlockValueValid(const CBlock& block, CAmount nExpectedValue){ int nHeight = 0; @@ -369,7 +208,7 @@ void CMasternodePayments::ProcessMessage(CNode* pfrom, std::string& strCommand, } pfrom->FulfilledRequest(NetMsgType::MNWINNERSSYNC); - mnpayments.Sync(pfrom, nCountNeeded); + Sync(pfrom, nCountNeeded); LogPrintf("mnget - Sent Masternode winners to %s\n", pfrom->addr.ToString()); } else if (strCommand == NetMsgType::MNWINNER) { //Masternode Payments Declare Winner @@ -381,7 +220,7 @@ void CMasternodePayments::ProcessMessage(CNode* pfrom, std::string& strCommand, if(!pCurrentBlockIndex) return; - if(mnpayments.mapMasternodePayeeVotes.count(winner.GetHash())){ + if(mapMasternodePayeeVotes.count(winner.GetHash())){ LogPrint("mnpayments", "mnw - Already seen - %s bestHeight %d\n", winner.GetHash().ToString(), pCurrentBlockIndex->nHeight); masternodeSync.AddedMasternodeWinner(winner.GetHash()); return; @@ -399,7 +238,7 @@ void CMasternodePayments::ProcessMessage(CNode* pfrom, std::string& strCommand, return; } - if(!mnpayments.CanVote(winner.vinMasternode.prevout, winner.nBlockHeight)){ + if(!CanVote(winner.vinMasternode.prevout, winner.nBlockHeight)){ LogPrintf("mnw - masternode already voted - %s\n", winner.vinMasternode.prevout.ToStringShort()); return; } @@ -418,7 +257,7 @@ void CMasternodePayments::ProcessMessage(CNode* pfrom, std::string& strCommand, LogPrint("mnpayments", "mnw - winning vote - Addr %s Height %d bestHeight %d - %s\n", address2.ToString(), winner.nBlockHeight, pCurrentBlockIndex->nHeight, winner.vinMasternode.prevout.ToStringShort()); - if(mnpayments.AddWinningMasternode(winner)){ + if(AddWinningMasternode(winner)){ winner.Relay(); masternodeSync.AddedMasternodeWinner(winner.GetHash()); } @@ -622,6 +461,7 @@ void CMasternodePayments::CheckAndRemove() ++it; } } + LogPrintf("CMasternodePayments::CleanPaymentList() - %s mapSeenSyncMNW %lld\n", ToString(), masternodeSync.mapSeenSyncMNW.size()); } bool CMasternodePaymentWinner::IsValid(CNode* pnode, std::string& strError) diff --git a/src/masternode-payments.h b/src/masternode-payments.h index 79063ae65..400f14e2f 100644 --- a/src/masternode-payments.h +++ b/src/masternode-payments.h @@ -36,31 +36,6 @@ std::string GetRequiredPaymentsString(int nBlockHeight); bool IsBlockValueValid(const CBlock& block, CAmount nExpectedValue); void FillBlockPayee(CMutableTransaction& txNew, CAmount nFees); -void DumpMasternodePayments(); - -/** Save Masternode Payment Data (mnpayments.dat) - */ -class CMasternodePaymentDB -{ -private: - boost::filesystem::path pathDB; - std::string strMagicMessage; -public: - enum ReadResult { - Ok, - FileError, - HashReadError, - IncorrectHash, - IncorrectMagicMessage, - IncorrectMagicNumber, - IncorrectFormat - }; - - CMasternodePaymentDB(); - bool Write(const CMasternodePayments &objToSave); - ReadResult Read(CMasternodePayments& objToLoad, bool fDryRun = false); -}; - class CMasternodePayee { public: diff --git a/src/masternode.cpp b/src/masternode.cpp index 160c13029..d281593e7 100644 --- a/src/masternode.cpp +++ b/src/masternode.cpp @@ -128,7 +128,7 @@ CMasternode::CMasternode(const CMasternodeBroadcast& mnb) // bool CMasternode::UpdateFromNewBroadcast(CMasternodeBroadcast& mnb) { - if(mnb.sigTime > sigTime) { + if(mnb.sigTime > sigTime) { pubkey2 = mnb.pubkey2; sigTime = mnb.sigTime; vchSig = mnb.vchSig; @@ -679,7 +679,7 @@ bool CMasternodePing::CheckAndUpdate(int& nDos, bool fRequireEnabled, bool fChec return true; } - LogPrint("masternode", "CMasternodePing::CheckAndUpdate - New Ping - %s - %s - %lli\n", GetHash().ToString(), blockHash.ToString(), sigTime); + LogPrint("masternode", "CMasternodePing::CheckAndUpdate - New Ping %s - %s %s %d\n", vin.ToString(), GetHash().ToString(), blockHash.ToString(), sigTime); // see if we have this Masternode CMasternode* pmn = mnodeman.Find(vin); diff --git a/src/masternodeman.cpp b/src/masternodeman.cpp index cb4be5dd7..ddcb6cfb0 100644 --- a/src/masternodeman.cpp +++ b/src/masternodeman.cpp @@ -44,137 +44,6 @@ struct CompareScoreMN } }; -// -// CMasternodeDB -// - -CMasternodeDB::CMasternodeDB() -{ - pathMN = GetDataDir() / "mncache.dat"; - strMagicMessage = "MasternodeCache"; -} - -bool CMasternodeDB::Write(const CMasternodeMan& mnodemanToSave) -{ - int64_t nStart = GetTimeMillis(); - - // serialize, checksum data up to that point, then append checksum - CDataStream ssMasternodes(SER_DISK, CLIENT_VERSION); - ssMasternodes << strMagicMessage; // masternode cache file specific magic message - ssMasternodes << FLATDATA(Params().MessageStart()); // network specific magic number - ssMasternodes << mnodemanToSave; - uint256 hash = Hash(ssMasternodes.begin(), ssMasternodes.end()); - ssMasternodes << hash; - - // open output file, and associate with CAutoFile - FILE *file = fopen(pathMN.string().c_str(), "wb"); - CAutoFile fileout(file, SER_DISK, CLIENT_VERSION); - if (fileout.IsNull()) - return error("%s : Failed to open file %s", __func__, pathMN.string()); - - // Write and commit header, data - try { - fileout << ssMasternodes; - } - catch (std::exception &e) { - return error("%s : Serialize or I/O error - %s", __func__, e.what()); - } -// FileCommit(fileout); - fileout.fclose(); - - LogPrintf("Written info to mncache.dat %dms\n", GetTimeMillis() - nStart); - LogPrintf(" %s\n", mnodemanToSave.ToString()); - - return true; -} - -CMasternodeDB::ReadResult CMasternodeDB::Read(CMasternodeMan& mnodemanToLoad, bool fDryRun) -{ - int64_t nStart = GetTimeMillis(); - // open input file, and associate with CAutoFile - FILE *file = fopen(pathMN.string().c_str(), "rb"); - CAutoFile filein(file, SER_DISK, CLIENT_VERSION); - if (filein.IsNull()) - { - error("%s : Failed to open file %s", __func__, pathMN.string()); - return FileError; - } - - // use file size to size memory buffer - int fileSize = boost::filesystem::file_size(pathMN); - int dataSize = fileSize - sizeof(uint256); - // Don't try to resize to a negative number if file is small - if (dataSize < 0) - dataSize = 0; - vector vchData; - vchData.resize(dataSize); - uint256 hashIn; - - // read data and checksum from file - try { - filein.read((char *)&vchData[0], dataSize); - filein >> hashIn; - } - catch (std::exception &e) { - error("%s : Deserialize or I/O error - %s", __func__, e.what()); - return HashReadError; - } - filein.fclose(); - - CDataStream ssMasternodes(vchData, SER_DISK, CLIENT_VERSION); - - // verify stored checksum matches input data - uint256 hashTmp = Hash(ssMasternodes.begin(), ssMasternodes.end()); - if (hashIn != hashTmp) - { - error("%s : Checksum mismatch, data corrupted", __func__); - return IncorrectHash; - } - - unsigned char pchMsgTmp[4]; - std::string strMagicMessageTmp; - try { - // de-serialize file header (masternode cache file specific magic message) and .. - - ssMasternodes >> strMagicMessageTmp; - - // ... verify the message matches predefined one - if (strMagicMessage != strMagicMessageTmp) - { - error("%s : Invalid masternode cache magic message", __func__); - return IncorrectMagicMessage; - } - - // de-serialize file header (network specific magic number) and .. - ssMasternodes >> FLATDATA(pchMsgTmp); - - // ... verify the network matches ours - if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp))) - { - error("%s : Invalid network magic number", __func__); - return IncorrectMagicNumber; - } - // de-serialize data into CMasternodeMan object - ssMasternodes >> mnodemanToLoad; - } - catch (std::exception &e) { - mnodemanToLoad.Clear(); - error("%s : Deserialize or I/O error - %s", __func__, e.what()); - return IncorrectFormat; - } - - LogPrintf("Loaded info from mncache.dat %dms\n", GetTimeMillis() - nStart); - LogPrintf(" %s\n", mnodemanToLoad.ToString()); - if(!fDryRun) { - LogPrintf("Masternode manager - cleaning....\n"); - mnodemanToLoad.CheckAndRemove(true); - LogPrintf("Masternode manager - result:\n"); - LogPrintf(" %s\n", mnodemanToLoad.ToString()); - } - - return Ok; -} - CMasternodeMan::CMasternodeMan() { nDsqCount = 0; } @@ -225,6 +94,8 @@ void CMasternodeMan::Check() void CMasternodeMan::CheckAndRemove(bool forceExpiredRemoval) { + LogPrintf("CMasternodeMan::CheckAndRemove\n"); + Check(); LOCK(cs); @@ -235,7 +106,7 @@ void CMasternodeMan::CheckAndRemove(bool forceExpiredRemoval) if((*it).activeState == CMasternode::MASTERNODE_REMOVE || (*it).activeState == CMasternode::MASTERNODE_VIN_SPENT || (forceExpiredRemoval && (*it).activeState == CMasternode::MASTERNODE_EXPIRED)) { - LogPrint("masternode", "CMasternodeMan::CheckAndRemove - Removing inactive Masternode %s - %i now\n", (*it).addr.ToString(), size() - 1); + LogPrint("masternode", "CMasternodeMan::CheckAndRemove - Removing %s Masternode %s - %i now\n", (*it).Status(), (*it).addr.ToString(), size() - 1); //erase all of the broadcasts we've seen from this vin // -- if we missed a few pings and the node was removed, this will allow is to get it back without them @@ -746,8 +617,8 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData if(mn.addr.IsRFC1918() || mn.addr.IsLocal()) continue; //local network if(mn.IsEnabled()) { - LogPrint("masternode", "dseg - Sending Masternode entry - %s \n", mn.addr.ToString()); if(vin == CTxIn() || vin == mn.vin){ + LogPrint("masternode", "dseg - Sending Masternode entry - %s \n", mn.addr.ToString()); CMasternodeBroadcast mnb = CMasternodeBroadcast(mn); uint256 hash = mnb.GetHash(); pfrom->PushInventory(CInv(MSG_MASTERNODE_ANNOUNCE, hash)); diff --git a/src/masternodeman.h b/src/masternodeman.h index 53384c6f3..ee13535b9 100644 --- a/src/masternodeman.h +++ b/src/masternodeman.h @@ -21,29 +21,6 @@ using namespace std; class CMasternodeMan; extern CMasternodeMan mnodeman; -/** Access to the MN database (mncache.dat) - */ -class CMasternodeDB -{ -private: - boost::filesystem::path pathMN; - std::string strMagicMessage; -public: - enum ReadResult { - Ok, - FileError, - HashReadError, - IncorrectHash, - IncorrectMagicMessage, - IncorrectMagicNumber, - IncorrectFormat - }; - - CMasternodeDB(); - bool Write(const CMasternodeMan &mnodemanToSave); - ReadResult Read(CMasternodeMan& mnodemanToLoad, bool fDryRun = false); -}; - class CMasternodeMan { private: diff --git a/src/protocol.cpp b/src/protocol.cpp index 5b105dbbe..1b7f6dc5e 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -233,7 +233,7 @@ CInv::CInv(const std::string& strType, const uint256& hashIn) } } if (i == ARRAYLEN(ppszTypeName)) - LogPrint("net", "CInv::CInv(string, uint256) : unknown type '%s'", strType); + LogPrint("net", "CInv::CInv(string, uint256) : unknown type '%s'\n", strType); hash = hashIn; } @@ -250,7 +250,7 @@ bool CInv::IsKnownType() const const char* CInv::GetCommand() const { if (!IsKnownType()) - LogPrint("net", "CInv::GetCommand() : type=%d unknown type", type); + LogPrint("net", "CInv::GetCommand() : type=%d unknown type\n", type); return ppszTypeName[type]; } diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index e699a5d67..ed6cfcaa1 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -474,8 +474,8 @@ void RPCConsole::setClientModel(ClientModel *model) autoCompleter = new QCompleter(wordList, this); ui->lineEdit->setCompleter(autoCompleter); - // clear the lineEdit after activating from QCompleter - connect(autoCompleter, SIGNAL(activated(const QString&)), ui->lineEdit, SLOT(clear()), Qt::QueuedConnection); + // clear the lineEdit after activating from QCompleter + connect(autoCompleter, SIGNAL(activated(const QString&)), ui->lineEdit, SLOT(clear()), Qt::QueuedConnection); } } diff --git a/src/rpcmasternode.cpp b/src/rpcmasternode.cpp index bede685d3..647e47c85 100644 --- a/src/rpcmasternode.cpp +++ b/src/rpcmasternode.cpp @@ -324,9 +324,6 @@ UniValue masternode(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "You can't use this command until masternode list is synced"); } - std::vector mnEntries; - mnEntries = masternodeConfig.getEntries(); - int successful = 0; int failed = 0; @@ -378,9 +375,6 @@ UniValue masternode(const UniValue& params, bool fHelp) if(strCommand == "list-conf") { - std::vector mnEntries; - mnEntries = masternodeConfig.getEntries(); - UniValue resultObj(UniValue::VOBJ); BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) { diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index daa8c22c7..d9a6d18ae 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2531,7 +2531,7 @@ UniValue listunspent(const UniValue& params, bool fHelp) const UniValue& input = inputs[idx]; CBitcoinAddress address(input.get_str()); if (!address.IsValid()) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+input.get_str()); + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Dash address: ")+input.get_str()); if (setAddress.count(address)) throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+input.get_str()); setAddress.insert(address);