Merge pull request #710 from UdjinM6/locks

"Fix locks" Pack
This commit is contained in:
evan82 2016-03-04 07:05:04 -07:00
commit 20c10c91f1
23 changed files with 413 additions and 252 deletions

View File

@ -106,6 +106,7 @@ BITCOIN_CORE_H = \
consensus/validation.h \
core_io.h \
darksend.h \
dsnotificationinterface.h \
darksend-relay.h \
core_memusage.h \
hash.h \
@ -249,6 +250,7 @@ libbitcoin_wallet_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
libbitcoin_wallet_a_SOURCES = \
activemasternode.cpp \
darksend.cpp \
dsnotificationinterface.cpp \
darksend-relay.cpp \
instantx.cpp \
masternode.cpp \

View File

@ -450,7 +450,7 @@ std::string CDarksendPool::GetStatus()
showingDarkSendMessage += 10;
std::string suffix = "";
if(chainActive.Tip()->nHeight - cachedLastSuccess < minBlockSpacing || !masternodeSync.IsBlockchainSynced()) {
if((pCurrentBlockIndex && pCurrentBlockIndex->nHeight - cachedLastSuccess < minBlockSpacing) || !masternodeSync.IsBlockchainSynced()) {
return strAutoDenomResult;
}
switch(state) {
@ -570,10 +570,10 @@ void CDarksendPool::CheckFinalTransaction()
CWalletTx txNew = CWalletTx(pwalletMain, finalTransaction);
LOCK2(cs_main, pwalletMain->cs_wallet);
{
LogPrint("darksend", "Transaction 2: %s\n", txNew.ToString());
LogPrint("darksend", "Transaction 2: %s\n", txNew.ToString());
{
LOCK(cs_main);
// See if the transaction is valid
if (!txNew.AcceptToMemoryPool(false, true))
{
@ -585,58 +585,57 @@ void CDarksendPool::CheckFinalTransaction()
RelayCompletedTransaction(sessionID, true, ERR_INVALID_TX);
return;
}
LogPrintf("CDarksendPool::Check() -- IS MASTER -- TRANSMITTING DARKSEND\n");
// sign a message
int64_t sigTime = GetAdjustedTime();
std::string strMessage = txNew.GetHash().ToString() + boost::lexical_cast<std::string>(sigTime);
std::string strError = "";
std::vector<unsigned char> vchSig;
CKey key2;
CPubKey pubkey2;
if(!darkSendSigner.SetKey(strMasterNodePrivKey, strError, key2, pubkey2))
{
LogPrintf("CDarksendPool::Check() - ERROR: Invalid Masternodeprivkey: '%s'\n", strError);
return;
}
if(!darkSendSigner.SignMessage(strMessage, strError, vchSig, key2)) {
LogPrintf("CDarksendPool::Check() - Sign message failed\n");
return;
}
if(!darkSendSigner.VerifyMessage(pubkey2, vchSig, strMessage, strError)) {
LogPrintf("CDarksendPool::Check() - Verify message failed\n");
return;
}
if(!mapDarksendBroadcastTxes.count(txNew.GetHash())){
CDarksendBroadcastTx dstx;
dstx.tx = txNew;
dstx.vin = activeMasternode.vin;
dstx.vchSig = vchSig;
dstx.sigTime = sigTime;
mapDarksendBroadcastTxes.insert(make_pair(txNew.GetHash(), dstx));
}
CInv inv(MSG_DSTX, txNew.GetHash());
RelayInv(inv);
// Tell the clients it was successful
RelayCompletedTransaction(sessionID, false, MSG_SUCCESS);
// Randomly charge clients
ChargeRandomFees();
// Reset
LogPrint("darksend", "CDarksendPool::Check() -- COMPLETED -- RESETTING\n");
SetNull();
RelayStatus(sessionID, GetState(), GetEntriesCount(), MASTERNODE_RESET);
}
LogPrintf("CDarksendPool::Check() -- IS MASTER -- TRANSMITTING DARKSEND\n");
// sign a message
int64_t sigTime = GetAdjustedTime();
std::string strMessage = txNew.GetHash().ToString() + boost::lexical_cast<std::string>(sigTime);
std::string strError = "";
std::vector<unsigned char> vchSig;
CKey key2;
CPubKey pubkey2;
if(!darkSendSigner.SetKey(strMasterNodePrivKey, strError, key2, pubkey2))
{
LogPrintf("CDarksendPool::Check() - ERROR: Invalid Masternodeprivkey: '%s'\n", strError);
return;
}
if(!darkSendSigner.SignMessage(strMessage, strError, vchSig, key2)) {
LogPrintf("CDarksendPool::Check() - Sign message failed\n");
return;
}
if(!darkSendSigner.VerifyMessage(pubkey2, vchSig, strMessage, strError)) {
LogPrintf("CDarksendPool::Check() - Verify message failed\n");
return;
}
if(!mapDarksendBroadcastTxes.count(txNew.GetHash())){
CDarksendBroadcastTx dstx;
dstx.tx = txNew;
dstx.vin = activeMasternode.vin;
dstx.vchSig = vchSig;
dstx.sigTime = sigTime;
mapDarksendBroadcastTxes.insert(make_pair(txNew.GetHash(), dstx));
}
CInv inv(MSG_DSTX, txNew.GetHash());
RelayInv(inv);
// Tell the clients it was successful
RelayCompletedTransaction(sessionID, false, MSG_SUCCESS);
// Randomly charge clients
ChargeRandomFees();
// Reset
LogPrint("darksend", "CDarksendPool::Check() -- COMPLETED -- RESETTING\n");
SetNull();
RelayStatus(sessionID, GetState(), GetEntriesCount(), MASTERNODE_RESET);
}
//
@ -1342,7 +1341,7 @@ void CDarksendPool::CompletedTransaction(bool error, int errorID)
SetNull();
// To avoid race conditions, we'll only let DS run once per block
cachedLastSuccess = chainActive.Tip()->nHeight;
cachedLastSuccess = pCurrentBlockIndex->nHeight;
}
lastMessage = GetMessageByID(errorID);
}
@ -1361,6 +1360,9 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun)
{
if(!fEnableDarksend) return false;
if(fMasterNode) return false;
if(!pCurrentBlockIndex) return false;
if(state == POOL_STATUS_ERROR || state == POOL_STATUS_SUCCESS) return false;
if(GetEntriesCount() > 0) {
strAutoDenomResult = _("Mixing in progress...");
@ -1383,7 +1385,7 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun)
return false;
}
if(!fDarksendMultiSession && chainActive.Tip()->nHeight - cachedLastSuccess < minBlockSpacing) {
if(!fDarksendMultiSession && pCurrentBlockIndex->nHeight - cachedLastSuccess < minBlockSpacing) {
LogPrintf("CDarksendPool::DoAutomaticDenominating - Last successful Darksend action was too recent\n");
strAutoDenomResult = _("Last successful Darksend action was too recent.");
return false;
@ -1704,7 +1706,7 @@ bool CDarksendPool::MakeCollateralAmounts()
return false;
}
cachedLastSuccess = chainActive.Tip()->nHeight;
cachedLastSuccess = pCurrentBlockIndex->nHeight;
return true;
}
@ -1795,7 +1797,7 @@ bool CDarksendPool::CreateDenominated(CAmount nTotalValue)
// use the same cachedLastSuccess as for DS mixinx to prevent race
if(pwalletMain->CommitTransaction(wtx, reservekeyChange))
cachedLastSuccess = chainActive.Tip()->nHeight;
cachedLastSuccess = pCurrentBlockIndex->nHeight;
else
LogPrintf("CreateDenominated: CommitTransaction failed!\n");
@ -2198,6 +2200,15 @@ void CDarksendPool::RelayCompletedTransaction(const int sessionID, const bool er
pnode->PushMessage(NetMsgType::DSSTATUSUPDATE, sessionID, error, errorID);
}
void CDarksendPool::UpdatedBlockTip(const CBlockIndex *pindex)
{
pCurrentBlockIndex = pindex;
LogPrint("darksend", "pCurrentBlockIndex->nHeight: %d\n", pCurrentBlockIndex->nHeight);
if(!fLiteMode && masternodeSync.RequestedMasternodeAssets > MASTERNODE_SYNC_LIST)
NewBlock();
}
//TODO: Rename/move to core
void ThreadCheckDarkSendPool()
{

View File

@ -289,6 +289,9 @@ private:
int64_t lastNewBlock;
// Keep track of current block index
const CBlockIndex *pCurrentBlockIndex;
std::vector<CAmount> darkSendDenominationsSkipped;
//debugging data
@ -535,6 +538,8 @@ public:
void RelayIn(const std::vector<CTxDSIn>& vin, const CAmount& nAmount, const CTransaction& txCollateral, const std::vector<CTxDSOut>& vout);
void RelayStatus(const int sessionID, const int newState, const int newEntriesCount, const int newAccepted, const int errorID=MSG_NOERR);
void RelayCompletedTransaction(const int sessionID, const bool error, const int errorID);
void UpdatedBlockTip(const CBlockIndex *pindex);
};
void ThreadCheckDarkSendPool();

View File

@ -0,0 +1,25 @@
// Copyright (c) 2015 The Dash Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "dsnotificationinterface.h"
#include "darksend.h"
#include "masternode-budget.h"
#include "masternode-payments.h"
#include "masternode-sync.h"
CDSNotificationInterface::CDSNotificationInterface()
{
}
CDSNotificationInterface::~CDSNotificationInterface()
{
}
void CDSNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindex)
{
darkSendPool.UpdatedBlockTip(pindex);
mnpayments.UpdatedBlockTip(pindex);
budget.UpdatedBlockTip(pindex);
masternodeSync.UpdatedBlockTip(pindex);
}

View File

@ -0,0 +1,24 @@
// Copyright (c) 2015 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_DSNOTIFICATIONINTERFACE_H
#define BITCOIN_DSNOTIFICATIONINTERFACE_H
#include "validationinterface.h"
class CDSNotificationInterface : public CValidationInterface
{
public:
// virtual CDSNotificationInterface();
CDSNotificationInterface();
virtual ~CDSNotificationInterface();
protected:
// CValidationInterface
void UpdatedBlockTip(const CBlockIndex *pindex);
private:
};
#endif // BITCOIN_DSNOTIFICATIONINTERFACE_H

View File

@ -70,6 +70,8 @@
#include "zmq/zmqnotificationinterface.h"
#endif
#include "dsnotificationinterface.h"
using namespace std;
#ifdef ENABLE_WALLET
@ -87,6 +89,8 @@ static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false;
static CZMQNotificationInterface* pzmqNotificationInterface = NULL;
#endif
static CDSNotificationInterface* pdsNotificationInterface = NULL;
#ifdef WIN32
// Win32 LevelDB doesn't use filedescriptors, and the ones used for
// accessing block files don't count towards the fd_set size limit
@ -254,6 +258,12 @@ void PrepareShutdown()
}
#endif
if (pdsNotificationInterface) {
UnregisterValidationInterface(pdsNotificationInterface);
delete pdsNotificationInterface;
pdsNotificationInterface = NULL;
}
#ifndef WIN32
try {
boost::filesystem::remove(GetPidFile());
@ -1428,6 +1438,10 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
RegisterValidationInterface(pzmqNotificationInterface);
}
#endif
pdsNotificationInterface = new CDSNotificationInterface();
RegisterValidationInterface(pdsNotificationInterface);
if (mapArgs.count("-maxuploadtarget")) {
CNode::SetMaxOutboundTarget(GetArg("-maxuploadtarget", DEFAULT_MAX_UPLOAD_TARGET)*1024*1024);
}
@ -1938,6 +1952,10 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
darkSendPool.InitDenominations();
darkSendPool.InitCollateralAddress();
// force UpdatedBlockTip to initialize pCurrentBlockIndex for DS, MN payments and budgets
GetMainSignals().UpdatedBlockTip(chainActive.Tip());
// start dash-darksend thread
threadGroup.create_thread(boost::bind(&ThreadCheckDarkSendPool));
// ********************************************************* Step 11: start node

View File

@ -235,7 +235,13 @@ int64_t CreateNewLock(CTransaction tx)
This prevents attackers from using transaction mallibility to predict which masternodes
they'll use.
*/
int nBlockHeight = (chainActive.Tip()->nHeight - nTxAge)+4;
int nBlockHeight = 0;
{
LOCK(cs_main);
CBlockIndex* tip = chainActive.Tip();
if(tip) nBlockHeight = tip->nHeight - nTxAge + 4;
else return 0;
}
if (!mapTxLocks.count(tx.GetHash())){
LogPrintf("CreateNewLock - New Transaction Lock %s !\n", tx.GetHash().ToString().c_str());
@ -434,8 +440,6 @@ int64_t GetAverageVoteTime()
void CleanTransactionLocksList()
{
if(chainActive.Tip() == NULL) return;
std::map<uint256, CTransactionLock>::iterator it = mapTxLocks.begin();
while(it != mapTxLocks.end()) {
@ -460,7 +464,6 @@ void CleanTransactionLocksList()
it++;
}
}
}
uint256 CConsensusVote::GetHash() const

View File

@ -3527,14 +3527,6 @@ bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, c
if (!ActivateBestChain(state, chainparams, pblock))
return error("%s: ActivateBestChain failed", __func__);
if(!fLiteMode){
if (masternodeSync.RequestedMasternodeAssets > MASTERNODE_SYNC_LIST) {
darkSendPool.NewBlock();
mnpayments.ProcessBlock(GetHeight()+10);
budget.NewBlock();
}
}
LogPrintf("%s : ACCEPTED\n", __func__);
return true;
}

View File

@ -57,6 +57,7 @@ bool IsBudgetCollateralValid(uint256 nTxCollateralHash, uint256 nExpectedHash, s
return false;
}
LOCK(cs_main);
int conf = GetIXConfirmations(nTxCollateralHash);
if (nBlockHash != uint256()) {
BlockMap::iterator mi = mapBlockIndex.find(nBlockHash);
@ -109,12 +110,11 @@ void CBudgetManager::CheckOrphanVotes()
void CBudgetManager::SubmitFinalBudget()
{
CBlockIndex* pindexPrev = chainActive.Tip();
if(!pindexPrev) return;
if(!pCurrentBlockIndex) return;
int nBlockStart = pindexPrev->nHeight - pindexPrev->nHeight % Params().GetConsensus().nBudgetPaymentsCycleBlocks + Params().GetConsensus().nBudgetPaymentsCycleBlocks;
int nBlockStart = pCurrentBlockIndex->nHeight - pCurrentBlockIndex->nHeight % Params().GetConsensus().nBudgetPaymentsCycleBlocks + Params().GetConsensus().nBudgetPaymentsCycleBlocks;
if(nSubmittedFinalBudget >= nBlockStart) return;
if(nBlockStart - pindexPrev->nHeight > 576*2) return; //submit final budget 2 days before payment
if(nBlockStart - pCurrentBlockIndex->nHeight > 576*2) return; //submit final budget 2 days before payment
std::vector<CBudgetProposal*> vBudgetProposals = budget.GetBudget();
std::string strBudgetName = "main";
@ -136,7 +136,7 @@ void CBudgetManager::SubmitFinalBudget()
CFinalizedBudgetBroadcast tempBudget(strBudgetName, nBlockStart, vecTxBudgetPayments, uint256());
if(mapSeenFinalizedBudgets.count(tempBudget.GetHash())) {
LogPrintf("CBudgetManager::SubmitFinalBudget - Budget already exists - %s\n", tempBudget.GetHash().ToString());
nSubmittedFinalBudget = pindexPrev->nHeight;
nSubmittedFinalBudget = pCurrentBlockIndex->nHeight;
return; //already exists
}
@ -177,7 +177,7 @@ void CBudgetManager::SubmitFinalBudget()
CFinalizedBudgetBroadcast finalizedBudgetBroadcast(strBudgetName, nBlockStart, vecTxBudgetPayments, tx.GetHash());
std::string strError = "";
if(!finalizedBudgetBroadcast.IsValid(strError)){
if(!finalizedBudgetBroadcast.IsValid(pCurrentBlockIndex, strError)){
LogPrintf("CBudgetManager::SubmitFinalBudget - Invalid finalized budget - %s \n", strError);
return;
}
@ -355,7 +355,7 @@ void DumpBudgets()
bool CBudgetManager::AddFinalizedBudget(CFinalizedBudget& finalizedBudget)
{
std::string strError = "";
if(!finalizedBudget.IsValid(strError)) return false;
if(!finalizedBudget.IsValid(pCurrentBlockIndex, strError)) return false;
if(mapFinalizedBudgets.count(finalizedBudget.GetHash())) {
return false;
@ -369,7 +369,7 @@ bool CBudgetManager::AddProposal(CBudgetProposal& budgetProposal)
{
LOCK(cs);
std::string strError = "";
if(!budgetProposal.IsValid(strError)) {
if(!budgetProposal.IsValid(pCurrentBlockIndex, strError)) {
LogPrintf("CBudgetManager::AddProposal - invalid budget proposal - %s\n", strError);
return false;
}
@ -386,9 +386,7 @@ void CBudgetManager::CheckAndRemove()
{
LogPrintf("CBudgetManager::CheckAndRemove \n");
CBlockIndex* pindexPrev = chainActive.Tip();
if(!pindexPrev) return;
if(!pCurrentBlockIndex) return;
std::string strError = "";
std::map<uint256, CFinalizedBudget>::iterator it = mapFinalizedBudgets.begin();
@ -396,13 +394,13 @@ void CBudgetManager::CheckAndRemove()
{
CFinalizedBudget* pfinalizedBudget = &((*it).second);
pfinalizedBudget->fValid = pfinalizedBudget->IsValid(strError);
pfinalizedBudget->fValid = pfinalizedBudget->IsValid(pCurrentBlockIndex, strError);
if(pfinalizedBudget->fValid) {
pfinalizedBudget->AutoCheck();
++it;
// if it's too old, remove it
} else if(pfinalizedBudget->nBlockStart != 0 && pfinalizedBudget->nBlockStart < pindexPrev->nHeight - Params().GetConsensus().nBudgetPaymentsCycleBlocks) {
} else if(pfinalizedBudget->nBlockStart != 0 && pfinalizedBudget->nBlockStart < pCurrentBlockIndex->nHeight - Params().GetConsensus().nBudgetPaymentsCycleBlocks) {
mapFinalizedBudgets.erase(it++);
LogPrintf("CBudgetManager::CheckAndRemove - removing budget %s\n", pfinalizedBudget->GetHash().ToString());
}
@ -412,7 +410,7 @@ void CBudgetManager::CheckAndRemove()
while(it2 != mapProposals.end())
{
CBudgetProposal* pbudgetProposal = &((*it2).second);
pbudgetProposal->fValid = pbudgetProposal->IsValid(strError);
pbudgetProposal->fValid = pbudgetProposal->IsValid(pCurrentBlockIndex, strError);
++it2;
}
}
@ -421,8 +419,7 @@ void CBudgetManager::FillBlockPayee(CMutableTransaction& txNew, CAmount nFees)
{
LOCK(cs);
CBlockIndex* pindexPrev = chainActive.Tip();
if(!pindexPrev) return;
if(!pCurrentBlockIndex) return;
int nHighestCount = 0;
CScript payee;
@ -435,19 +432,17 @@ void CBudgetManager::FillBlockPayee(CMutableTransaction& txNew, CAmount nFees)
{
CFinalizedBudget* pfinalizedBudget = &((*it).second);
if(pfinalizedBudget->GetVoteCount() > nHighestCount &&
pindexPrev->nHeight + 1 >= pfinalizedBudget->GetBlockStart() &&
pindexPrev->nHeight + 1 <= pfinalizedBudget->GetBlockEnd() &&
pfinalizedBudget->GetPayeeAndAmount(pindexPrev->nHeight + 1, payee, nAmount)){
pCurrentBlockIndex->nHeight + 1 >= pfinalizedBudget->GetBlockStart() &&
pCurrentBlockIndex->nHeight + 1 <= pfinalizedBudget->GetBlockEnd() &&
pfinalizedBudget->GetPayeeAndAmount(pCurrentBlockIndex->nHeight + 1, payee, nAmount)){
nHighestCount = pfinalizedBudget->GetVoteCount();
}
++it;
}
CAmount blockValue = nFees + GetBlockSubsidy(pindexPrev->nBits, pindexPrev->nHeight, Params().GetConsensus());
//miners get the full amount on these blocks
txNew.vout[0].nValue = blockValue;
txNew.vout[0].nValue = nFees + GetBlockSubsidy(pCurrentBlockIndex->nBits, pCurrentBlockIndex->nHeight, Params().GetConsensus());
if(nHighestCount > 0){
txNew.vout.resize(2);
@ -531,13 +526,12 @@ bool CBudgetManager::IsBudgetPaymentBlock(int nBlockHeight)
bool CBudgetManager::HasNextFinalizedBudget()
{
CBlockIndex* pindexPrev = chainActive.Tip();
if(!pindexPrev) return false;
if(!pCurrentBlockIndex) return false;
if(masternodeSync.IsBudgetFinEmpty()) return true;
int nBlockStart = pindexPrev->nHeight - pindexPrev->nHeight % Params().GetConsensus().nBudgetPaymentsCycleBlocks + Params().GetConsensus().nBudgetPaymentsCycleBlocks;
if(nBlockStart - pindexPrev->nHeight > 576*2) return true; //we wouldn't have the budget yet
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(budget.IsBudgetPaymentBlock(nBlockStart)) return true;
@ -649,10 +643,9 @@ std::vector<CBudgetProposal*> CBudgetManager::GetBudget()
std::vector<CBudgetProposal*> vBudgetProposalsRet;
CAmount nBudgetAllocated = 0;
CBlockIndex* pindexPrev = chainActive.Tip();
if(pindexPrev == NULL) return vBudgetProposalsRet;
if(!pCurrentBlockIndex) return vBudgetProposalsRet;
int nBlockStart = pindexPrev->nHeight - pindexPrev->nHeight % Params().GetConsensus().nBudgetPaymentsCycleBlocks + Params().GetConsensus().nBudgetPaymentsCycleBlocks;
int nBlockStart = pCurrentBlockIndex->nHeight - pCurrentBlockIndex->nHeight % Params().GetConsensus().nBudgetPaymentsCycleBlocks + Params().GetConsensus().nBudgetPaymentsCycleBlocks;
int nBlockEnd = nBlockStart + Params().GetConsensus().nBudgetPaymentsWindowBlocks;
CAmount nTotalBudget = GetTotalBudget(nBlockStart);
@ -765,7 +758,7 @@ std::string CBudgetManager::GetRequiredPaymentsString(int nBlockHeight)
CAmount CBudgetManager::GetTotalBudget(int nHeight)
{
if(chainActive.Tip() == NULL) return 0;
if(!pCurrentBlockIndex) return 0;
//get min block value and calculate from that
CAmount nSubsidy = 5 * COIN;
@ -793,6 +786,8 @@ 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
@ -800,12 +795,12 @@ void CBudgetManager::NewBlock()
}
//this function should be called 1/6 blocks, allowing up to 100 votes per day on all proposals
if(chainActive.Height() % 6 != 0) return;
if(pCurrentBlockIndex->nHeight % 6 != 0) return;
// incremental sync with our peers
if(masternodeSync.IsSynced()){
LogPrintf("CBudgetManager::NewBlock - incremental sync started\n");
if(chainActive.Height() % 600 == rand() % 600) {
if(pCurrentBlockIndex->nHeight % 600 == rand() % 600) {
ClearSeen();
ResetSync();
}
@ -814,10 +809,9 @@ void CBudgetManager::NewBlock()
BOOST_FOREACH(CNode* pnode, vNodes)
if(pnode->nVersion >= MIN_BUDGET_PEER_PROTO_VERSION)
Sync(pnode, uint256(), true);
MarkSynced();
}
CheckAndRemove();
@ -854,7 +848,7 @@ void CBudgetManager::NewBlock()
continue;
}
if(!(*it4).IsValid(strError)) {
if(!(*it4).IsValid(pCurrentBlockIndex, strError)) {
LogPrintf("mprop (immature) - invalid budget proposal - %s\n", strError);
it4 = vecImmatureBudgetProposals.erase(it4);
continue;
@ -877,7 +871,7 @@ void CBudgetManager::NewBlock()
continue;
}
if(!(*it5).IsValid(strError)) {
if(!(*it5).IsValid(pCurrentBlockIndex, strError)) {
LogPrintf("fbs (immature) - invalid finalized budget - %s\n", strError);
it5 = vecImmatureFinalizedBudgets.erase(it5);
continue;
@ -939,7 +933,7 @@ void CBudgetManager::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
mapSeenMasternodeBudgetProposals.insert(make_pair(budgetProposalBroadcast.GetHash(), budgetProposalBroadcast));
if(!budgetProposalBroadcast.IsValid(strError)) {
if(!budgetProposalBroadcast.IsValid(pCurrentBlockIndex, strError)) {
LogPrintf("mprop - invalid budget proposal - %s\n", strError);
return;
}
@ -980,7 +974,7 @@ void CBudgetManager::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
mnodeman.AskForMN(pfrom, vote.vin);
return;
}
std::string strError = "";
if(UpdateProposal(vote, pfrom, strError)) {
vote.Relay();
@ -1010,7 +1004,7 @@ void CBudgetManager::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
mapSeenFinalizedBudgets.insert(make_pair(finalizedBudgetBroadcast.GetHash(), finalizedBudgetBroadcast));
if(!finalizedBudgetBroadcast.IsValid(strError)) {
if(!finalizedBudgetBroadcast.IsValid(pCurrentBlockIndex, strError)) {
LogPrintf("fbs - invalid finalized budget - %s\n", strError);
return;
}
@ -1320,7 +1314,7 @@ CBudgetProposal::CBudgetProposal(std::string strProposalNameIn, std::string strU
nFeeTXHash = nFeeTXHashIn;
}
bool CBudgetProposal::IsValid(std::string& strError, bool fCheckCollateral)
bool CBudgetProposal::IsValid(const CBlockIndex* pindex, std::string& strError, bool fCheckCollateral)
{
if(GetNoCount() - GetYesCount() > mnodeman.CountEnabled(MIN_BUDGET_PEER_PROTO_VERSION)/10){
strError = "Active removal";
@ -1332,11 +1326,13 @@ bool CBudgetProposal::IsValid(std::string& strError, bool fCheckCollateral)
return false;
}
CBlockIndex* pindexPrev = chainActive.Tip();
if(pindexPrev == NULL) {strError = "Tip is NULL"; return true;}
if(!pindex) {
strError = "Tip is NULL";
return true;
}
if(nBlockStart % Params().GetConsensus().nBudgetPaymentsCycleBlocks != 0){
int nNext = pindexPrev->nHeight - pindexPrev->nHeight % Params().GetConsensus().nBudgetPaymentsCycleBlocks + Params().GetConsensus().nBudgetPaymentsCycleBlocks;
int nNext = pindex->nHeight - pindex->nHeight % Params().GetConsensus().nBudgetPaymentsCycleBlocks + Params().GetConsensus().nBudgetPaymentsCycleBlocks;
strError = strprintf("Invalid block start - must be a budget cycle block. Next valid block: %d", nNext);
return false;
}
@ -1408,7 +1404,7 @@ bool CBudgetProposal::IsValid(std::string& strError, bool fCheckCollateral)
return false;
}
if(GetBlockEnd() + Params().GetConsensus().nBudgetPaymentsWindowBlocks < pindexPrev->nHeight) return false;
if(GetBlockEnd() + Params().GetConsensus().nBudgetPaymentsWindowBlocks < pindex->nHeight) return false;
return true;
@ -1528,14 +1524,13 @@ int CBudgetProposal::GetBlockStartCycle()
return nBlockStart - nBlockStart % Params().GetConsensus().nBudgetPaymentsCycleBlocks;
}
int CBudgetProposal::GetBlockCurrentCycle()
int CBudgetProposal::GetBlockCurrentCycle(const CBlockIndex* pindex)
{
CBlockIndex* pindexPrev = chainActive.Tip();
if(pindexPrev == NULL) return -1;
if(!pindex) return -1;
if(pindexPrev->nHeight >= GetBlockEndCycle()) return -1;
if(pindex->nHeight >= GetBlockEndCycle()) return -1;
return pindexPrev->nHeight - pindexPrev->nHeight % Params().GetConsensus().nBudgetPaymentsCycleBlocks;
return pindex->nHeight - pindex->nHeight % Params().GetConsensus().nBudgetPaymentsCycleBlocks;
}
int CBudgetProposal::GetBlockEndCycle()
@ -1850,7 +1845,7 @@ std::string CFinalizedBudget::GetStatus()
return retBadHashes + retBadPayeeOrAmount;
}
bool CFinalizedBudget::IsValid(std::string& strError, bool fCheckCollateral)
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;}
@ -1867,16 +1862,19 @@ bool CFinalizedBudget::IsValid(std::string& strError, bool fCheckCollateral)
if(fCheckCollateral){
int nConf = 0;
if(!IsBudgetCollateralValid(nFeeTXHash, GetHash(), strError2, nTime, nConf)){
{strError = "Invalid Collateral : " + strError2; return false;}
strError = "Invalid Collateral : " + strError2;
return false;
}
}
//TODO: if N cycles old, invalid, invalid
CBlockIndex* pindexPrev = chainActive.Tip();
if(pindexPrev == NULL) return true;
if(!pindex) return true;
if(nBlockStart < pindexPrev->nHeight - Params().GetConsensus().nBudgetPaymentsWindowBlocks) {strError = "Older than current blockHeight"; return false;}
if(nBlockStart < pindex->nHeight - Params().GetConsensus().nBudgetPaymentsWindowBlocks) {
strError = "Older than current blockHeight";
return false;
}
return true;
}
@ -2059,4 +2057,11 @@ std::string CBudgetManager::ToString() const
return info.str();
}
void CBudgetManager::UpdatedBlockTip(const CBlockIndex *pindex)
{
pCurrentBlockIndex = pindex;
LogPrint("mnbudget", "pCurrentBlockIndex->nHeight: %d\n", pCurrentBlockIndex->nHeight);
if(!fLiteMode && masternodeSync.RequestedMasternodeAssets > MASTERNODE_SYNC_LIST)
NewBlock();
}

View File

@ -78,6 +78,8 @@ private:
//hold txes until they mature enough to use
map<uint256, CTransaction> mapCollateral;
// Keep track of current block index
const CBlockIndex *pCurrentBlockIndex;
public:
// critical section to protect the inner data structures
@ -179,6 +181,8 @@ public:
READWRITE(mapProposals);
READWRITE(mapFinalizedBudgets);
}
void UpdatedBlockTip(const CBlockIndex *pindex);
};
@ -235,7 +239,7 @@ public:
double GetScore();
bool HasMinimumRequiredSupport();
bool IsValid(std::string& strError, bool fCheckCollateral=true);
bool IsValid(const CBlockIndex* pindex, std::string& strError, bool fCheckCollateral=true);
std::string GetName() {return strBudgetName; }
std::string GetProposals();
@ -427,7 +431,7 @@ public:
bool HasMinimumRequiredSupport();
std::pair<std::string, std::string> GetVotes();
bool IsValid(std::string& strError, bool fCheckCollateral=true);
bool IsValid(const CBlockIndex* pindex, std::string& strError, bool fCheckCollateral=true);
bool IsEstablished();
std::string GetName() {return strProposalName; }
@ -438,7 +442,7 @@ public:
int GetTotalPaymentCount();
int GetRemainingPaymentCount();
int GetBlockStartCycle();
int GetBlockCurrentCycle();
int GetBlockCurrentCycle(const CBlockIndex* pindex);
int GetBlockEndCycle();
double GetRatio();
int GetAbsoluteYesCount();

View File

@ -183,19 +183,21 @@ void DumpMasternodePayments()
}
bool IsBlockValueValid(const CBlock& block, CAmount nExpectedValue){
CBlockIndex* pindexPrev = chainActive.Tip();
if(pindexPrev == NULL) return true;
int nHeight = 0;
if(pindexPrev->GetBlockHash() == block.hashPrevBlock)
{
nHeight = pindexPrev->nHeight+1;
} else { //out of order
BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock);
if (mi != mapBlockIndex.end() && (*mi).second)
nHeight = (*mi).second->nHeight+1;
}
{
LOCK(cs_main);
if(!chainActive.Tip()) return true;
if(chainActive.Tip()->GetBlockHash() == block.hashPrevBlock)
{
nHeight = chainActive.Tip()->nHeight+1;
} else { //out of order
BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock);
if (mi != mapBlockIndex.end() && (*mi).second)
nHeight = (*mi).second->nHeight+1;
}
}
if(nHeight == 0){
LogPrintf("IsBlockValueValid() : WARNING: Couldn't find previous block");
}
@ -269,10 +271,9 @@ bool IsBlockPayeeValid(const CTransaction& txNew, int nBlockHeight)
void FillBlockPayee(CMutableTransaction& txNew, CAmount nFees)
{
CBlockIndex* pindexPrev = chainActive.Tip();
if(!pindexPrev) return;
if(!chainActive.Tip()) return;
if(IsSporkActive(SPORK_13_ENABLE_SUPERBLOCKS) && budget.IsBudgetPaymentBlock(pindexPrev->nHeight+1)){
if(IsSporkActive(SPORK_13_ENABLE_SUPERBLOCKS) && budget.IsBudgetPaymentBlock(chainActive.Tip()->nHeight+1)){
budget.FillBlockPayee(txNew, nFees);
} else {
mnpayments.FillBlockPayee(txNew, nFees);
@ -290,14 +291,13 @@ std::string GetRequiredPaymentsString(int nBlockHeight)
void CMasternodePayments::FillBlockPayee(CMutableTransaction& txNew, CAmount nFees)
{
CBlockIndex* pindexPrev = chainActive.Tip();
if(!pindexPrev) return;
if(!pCurrentBlockIndex) return;
bool hasPayment = true;
CScript payee;
//spork
if(!mnpayments.GetBlockPayee(pindexPrev->nHeight+1, payee)){
if(!mnpayments.GetBlockPayee(pCurrentBlockIndex->nHeight+1, payee)){
//no masternode detected
CMasternode* winningNode = mnodeman.GetCurrentMasterNode();
if(winningNode){
@ -308,8 +308,8 @@ void CMasternodePayments::FillBlockPayee(CMutableTransaction& txNew, CAmount nFe
}
}
CAmount blockValue = nFees + GetBlockSubsidy(pindexPrev->nBits, pindexPrev->nHeight, Params().GetConsensus());
CAmount masternodePayment = GetMasternodePayment(pindexPrev->nHeight+1, blockValue);
CAmount blockValue = nFees + GetBlockSubsidy(pCurrentBlockIndex->nBits, pCurrentBlockIndex->nHeight, Params().GetConsensus());
CAmount masternodePayment = GetMasternodePayment(pCurrentBlockIndex->nHeight+1, blockValue);
txNew.vout[0].nValue = blockValue;
@ -367,17 +367,17 @@ void CMasternodePayments::ProcessMessageMasternodePayments(CNode* pfrom, std::st
if(pfrom->nVersion < MIN_MNW_PEER_PROTO_VERSION) return;
if(chainActive.Tip() == NULL) return;
if(!pCurrentBlockIndex) return;
if(mnpayments.mapMasternodePayeeVotes.count(winner.GetHash())){
LogPrint("mnpayments", "mnw - Already seen - %s bestHeight %d\n", winner.GetHash().ToString().c_str(), chainActive.Tip()->nHeight);
LogPrint("mnpayments", "mnw - Already seen - %s bestHeight %d\n", winner.GetHash().ToString().c_str(), pCurrentBlockIndex->nHeight);
masternodeSync.AddedMasternodeWinner(winner.GetHash());
return;
}
int nFirstBlock = chainActive.Tip()->nHeight - (mnodeman.CountEnabled()*1.25);
if(winner.nBlockHeight < nFirstBlock || winner.nBlockHeight > chainActive.Tip()->nHeight+20){
LogPrint("mnpayments", "mnw - winner out of range - FirstBlock %d Height %d bestHeight %d\n", nFirstBlock, winner.nBlockHeight, chainActive.Tip()->nHeight);
int nFirstBlock = pCurrentBlockIndex->nHeight - (mnodeman.CountEnabled()*1.25);
if(winner.nBlockHeight < nFirstBlock || winner.nBlockHeight > pCurrentBlockIndex->nHeight+20){
LogPrint("mnpayments", "mnw - winner out of range - FirstBlock %d Height %d bestHeight %d\n", nFirstBlock, winner.nBlockHeight, pCurrentBlockIndex->nHeight);
return;
}
@ -404,7 +404,7 @@ void CMasternodePayments::ProcessMessageMasternodePayments(CNode* pfrom, std::st
ExtractDestination(winner.payee, address1);
CBitcoinAddress address2(address1);
LogPrint("mnpayments", "mnw - winning vote - Addr %s Height %d bestHeight %d - %s\n", address2.ToString().c_str(), winner.nBlockHeight, chainActive.Tip()->nHeight, winner.vinMasternode.prevout.ToStringShort());
LogPrint("mnpayments", "mnw - winning vote - Addr %s Height %d bestHeight %d - %s\n", address2.ToString().c_str(), winner.nBlockHeight, pCurrentBlockIndex->nHeight, winner.vinMasternode.prevout.ToStringShort());
if(mnpayments.AddWinningMasternode(winner)){
winner.Relay();
@ -450,14 +450,13 @@ bool CMasternodePayments::IsScheduled(CMasternode& mn, int nNotBlockHeight)
{
LOCK(cs_mapMasternodeBlocks);
CBlockIndex* pindexPrev = chainActive.Tip();
if(pindexPrev == NULL) return false;
if(!pCurrentBlockIndex) return false;
CScript mnpayee;
mnpayee = GetScriptForDestination(mn.pubkey.GetID());
CScript payee;
for(int64_t h = pindexPrev->nHeight; h <= pindexPrev->nHeight+8; h++){
for(int64_t h = pCurrentBlockIndex->nHeight; h <= pCurrentBlockIndex->nHeight + 8; h++){
if(h == nNotBlockHeight) continue;
if(mapMasternodeBlocks.count(h)){
if(mapMasternodeBlocks[h].GetPayee(payee)){
@ -593,18 +592,18 @@ bool CMasternodePayments::IsTransactionValid(const CTransaction& txNew, int nBlo
void CMasternodePayments::CleanPaymentList()
{
if(!pCurrentBlockIndex) return;
LOCK2(cs_mapMasternodePayeeVotes, cs_mapMasternodeBlocks);
if(chainActive.Tip() == NULL) return;
//keep up to five cycles for historical sake
int nLimit = std::max(int(mnodeman.size()*1.25), 1000);
// keep a bit more for historical sake but at least 4000
int nLimit = std::max(int(mnodeman.size()*1.25), 4000);
std::map<uint256, CMasternodePaymentWinner>::iterator it = mapMasternodePayeeVotes.begin();
while(it != mapMasternodePayeeVotes.end()) {
CMasternodePaymentWinner winner = (*it).second;
if(chainActive.Tip()->nHeight - winner.nBlockHeight > nLimit){
if(pCurrentBlockIndex->nHeight - winner.nBlockHeight > nLimit){
LogPrint("mnpayments", "CMasternodePayments::CleanPaymentList - Removing old Masternode payment - block %d\n", winner.nBlockHeight);
masternodeSync.mapSeenSyncMNW.erase((*it).first);
mapMasternodePayeeVotes.erase(it++);
@ -777,7 +776,7 @@ void CMasternodePayments::Sync(CNode* node, int nCountNeeded)
{
LOCK(cs_mapMasternodePayeeVotes);
if(chainActive.Tip() == NULL) return;
if(!pCurrentBlockIndex) return;
int nCount = (mnodeman.CountEnabled()*1.25);
if(nCountNeeded > nCount) nCountNeeded = nCount;
@ -786,7 +785,7 @@ void CMasternodePayments::Sync(CNode* node, int nCountNeeded)
std::map<uint256, CMasternodePaymentWinner>::iterator it = mapMasternodePayeeVotes.begin();
while(it != mapMasternodePayeeVotes.end()) {
CMasternodePaymentWinner winner = (*it).second;
if(winner.nBlockHeight >= chainActive.Tip()->nHeight-nCountNeeded && winner.nBlockHeight <= chainActive.Tip()->nHeight + 20) {
if(winner.nBlockHeight >= pCurrentBlockIndex->nHeight - nCountNeeded && winner.nBlockHeight <= pCurrentBlockIndex->nHeight + 20) {
node->PushInventory(CInv(MSG_MASTERNODE_WINNER, winner.GetHash()));
nInvCount++;
}
@ -842,3 +841,12 @@ int CMasternodePayments::GetNewestBlock()
return nNewestBlock;
}
void CMasternodePayments::UpdatedBlockTip(const CBlockIndex *pindex)
{
pCurrentBlockIndex = pindex;
LogPrint("mnpayments", "pCurrentBlockIndex->nHeight: %d\n", pCurrentBlockIndex->nHeight);
if(!fLiteMode && masternodeSync.RequestedMasternodeAssets > MASTERNODE_SYNC_LIST)
ProcessBlock(pindex->nHeight+10);
}

View File

@ -226,6 +226,8 @@ class CMasternodePayments
private:
int nSyncedFromPeer;
int nLastBlockHeight;
// Keep track of current block index
const CBlockIndex *pCurrentBlockIndex;
public:
std::map<uint256, CMasternodePaymentWinner> mapMasternodePayeeVotes;
@ -293,6 +295,8 @@ public:
READWRITE(mapMasternodePayeeVotes);
READWRITE(mapMasternodeBlocks);
}
void UpdatedBlockTip(const CBlockIndex *pindex);
};

View File

@ -42,15 +42,8 @@ bool CMasternodeSync::IsBlockchainSynced()
if (fImporting || fReindex) return false;
TRY_LOCK(cs_main, lockMain);
if(!lockMain) return false;
CBlockIndex* pindex = chainActive.Tip();
if(pindex == NULL) return false;
if(pindex->nTime + 60*60 < GetTime())
return false;
if(!pCurrentBlockIndex) return false;
if(pCurrentBlockIndex->nTime + 60*60 < GetTime()) return false;
fBlockchainSynced = true;
@ -227,8 +220,10 @@ void CMasternodeSync::Process()
static int tick = 0;
if(tick++ % 6 != 0) return;
if(!pCurrentBlockIndex) return;
//the actual count of masternodes we have currently
int nMnCount = mnodeman.CountEnabled();
int nMnCount = mnodeman.CountEnabled();
// RESET SYNCING INCASE OF FAILURE
{
@ -319,8 +314,8 @@ void CMasternodeSync::Process()
// shall we move onto the next asset?
//printf("Masternode count %d est %d\n", nMnCount, mnodeman.GetEstimatedMasternodes(chainActive.Height())) ;
if(nMnCount > mnodeman.GetEstimatedMasternodes(chainActive.Height())*0.9)
//printf("Masternode count %d est %d\n", nMnCount, mnodeman.GetEstimatedMasternodes(pCurrentBlockIndex->nHeight));
if(nMnCount > mnodeman.GetEstimatedMasternodes(pCurrentBlockIndex->nHeight)*0.9)
{
GetNextAsset();
//printf("synced masternode list successfully\n");
@ -378,9 +373,6 @@ void CMasternodeSync::Process()
if(pnode->HasFulfilledRequest("mnwsync")) continue;
pnode->FulfilledRequest("mnwsync");
CBlockIndex* pindexPrev = chainActive.Tip();
if(pindexPrev == NULL) return;
int nMnCount = mnodeman.CountEnabled();
pnode->PushMessage(NetMsgType::MNWINNERSSYNC, nMnCount); //sync payees
RequestedMasternodeAttempt++;
@ -435,3 +427,8 @@ void CMasternodeSync::Process()
}
}
}
void CMasternodeSync::UpdatedBlockTip(const CBlockIndex *pindex)
{
pCurrentBlockIndex = pindex;
}

View File

@ -55,6 +55,9 @@ public:
// Time when current masternode asset sync started
int64_t nAssetSyncStarted;
// Keep track of current block index
const CBlockIndex *pCurrentBlockIndex;
CMasternodeSync();
void AddedMasternodeList(uint256 hash);
@ -71,6 +74,8 @@ public:
bool IsSynced();
bool IsBlockchainSynced();
void ClearFulfilledRequest();
void UpdatedBlockTip(const CBlockIndex *pindex);
};
#endif

View File

@ -21,6 +21,7 @@ std::map<int64_t, uint256> mapCacheBlockHashes;
//Get the last hash that matches the modulus given. Processed in reverse order
bool GetBlockHash(uint256& hash, int nBlockHeight)
{
LOCK(cs_main);
if (chainActive.Tip() == NULL) return false;
if(nBlockHeight == 0)
@ -151,7 +152,10 @@ bool CMasternode::UpdateFromNewBroadcast(CMasternodeBroadcast& mnb)
//
uint256 CMasternode::CalculateScore(int mod, int64_t nBlockHeight)
{
if(chainActive.Tip() == NULL) return uint256();
{
LOCK(cs_main);
if(chainActive.Tip() == NULL) return uint256();
}
uint256 hash = uint256();
uint256 aux = ArithToUint256(UintToArith256(vin.prevout.hash) + vin.prevout.n);
@ -241,8 +245,13 @@ int64_t CMasternode::SecondsSincePayment() {
}
int64_t CMasternode::GetLastPaid() {
CBlockIndex* pindexPrev = chainActive.Tip();
if(pindexPrev == NULL) return false;
CBlockIndex *pindexPrev = NULL;
{
LOCK(cs_main);
pindexPrev = chainActive.Tip();
if(!pindexPrev) return 0;
}
CScript mnpayee;
mnpayee = GetScriptForDestination(pubkey.GetID());
@ -255,9 +264,7 @@ int64_t CMasternode::GetLastPaid() {
// use a deterministic offset to break a tie -- 2.5 minutes
int64_t nOffset = UintToArith256(hash).GetCompact(false) % 150;
if (chainActive.Tip() == NULL) return false;
const CBlockIndex *BlockReading = chainActive.Tip();
const CBlockIndex *BlockReading = pindexPrev;
int nMnCount = mnodeman.CountEnabled()*1.25;
int n = 0;
@ -473,19 +480,21 @@ bool CMasternodeBroadcast::CheckInputsAndAdd(int& nDoS)
uint256 hashBlock = uint256();
CTransaction tx2;
GetTransaction(vin.prevout.hash, tx2, Params().GetConsensus(), hashBlock, true);
BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
if (mi != mapBlockIndex.end() && (*mi).second)
{
CBlockIndex* pMNIndex = (*mi).second; // block for 1000 DASH tx -> 1 confirmation
CBlockIndex* pConfIndex = chainActive[pMNIndex->nHeight + MASTERNODE_MIN_CONFIRMATIONS - 1]; // block where tx got MASTERNODE_MIN_CONFIRMATIONS
if(pConfIndex->GetBlockTime() > sigTime)
LOCK(cs_main);
BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
if (mi != mapBlockIndex.end() && (*mi).second)
{
LogPrintf("mnb - Bad sigTime %d for Masternode %20s %105s (%i conf block is at %d)\n",
sigTime, addr.ToString(), vin.ToString(), MASTERNODE_MIN_CONFIRMATIONS, pConfIndex->GetBlockTime());
return false;
CBlockIndex* pMNIndex = (*mi).second; // block for 1000 DASH tx -> 1 confirmation
CBlockIndex* pConfIndex = chainActive[pMNIndex->nHeight + MASTERNODE_MIN_CONFIRMATIONS - 1]; // block where tx got MASTERNODE_MIN_CONFIRMATIONS
if(pConfIndex->GetBlockTime() > sigTime)
{
LogPrintf("mnb - Bad sigTime %d for Masternode %20s %105s (%i conf block is at %d)\n",
sigTime, addr.ToString(), vin.ToString(), MASTERNODE_MIN_CONFIRMATIONS, pConfIndex->GetBlockTime());
return false;
}
}
}
LogPrintf("mnb - Got NEW Masternode entry - %s - %s - %s - %lli \n", GetHash().ToString(), addr.ToString(), vin.ToString(), sigTime);
CMasternode mn(*this);
mnodeman.Add(mn);
@ -543,8 +552,17 @@ CMasternodePing::CMasternodePing()
CMasternodePing::CMasternodePing(CTxIn& newVin)
{
int nHeight;
{
LOCK(cs_main);
CBlockIndex* pindexPrev = chainActive.Tip();
if(!pindexPrev) return;
nHeight = pindexPrev->nHeight;
}
vin = newVin;
blockHash = chainActive[chainActive.Height() - 12]->GetBlockHash();
blockHash = chainActive[nHeight - 12]->GetBlockHash();
sigTime = GetAdjustedTime();
vchSig = std::vector<unsigned char>();
}
@ -608,25 +626,27 @@ bool CMasternodePing::CheckAndUpdate(int& nDos, bool fRequireEnabled)
return false;
}
BlockMap::iterator mi = mapBlockIndex.find(blockHash);
if (mi != mapBlockIndex.end() && (*mi).second)
{
if((*mi).second->nHeight < chainActive.Height() - 24)
LOCK(cs_main);
BlockMap::iterator mi = mapBlockIndex.find(blockHash);
if (mi != mapBlockIndex.end() && (*mi).second)
{
LogPrintf("CMasternodePing::CheckAndUpdate - Masternode %s block hash %s is too old\n", vin.ToString(), blockHash.ToString());
// Do nothing here (no Masternode update, no mnping relay)
// Let this node to be visible but fail to accept mnping
if((*mi).second->nHeight < chainActive.Height() - 24)
{
LogPrintf("CMasternodePing::CheckAndUpdate - Masternode %s block hash %s is too old\n", vin.ToString(), blockHash.ToString());
// Do nothing here (no Masternode update, no mnping relay)
// Let this node to be visible but fail to accept mnping
return false;
}
} else {
if (fDebug) LogPrintf("CMasternodePing::CheckAndUpdate - Masternode %s block hash %s is unknown\n", vin.ToString(), blockHash.ToString());
// maybe we stuck so we shouldn't ban this node, just fail to accept it
// TODO: or should we also request this block?
return false;
}
} else {
if (fDebug) LogPrintf("CMasternodePing::CheckAndUpdate - Masternode %s block hash %s is unknown\n", vin.ToString(), blockHash.ToString());
// maybe we stuck so we shouldn't ban this node, just fail to accept it
// TODO: or should we also request this block?
return false;
}
pmn->lastPing = *this;
//mnodeman.mapSeenMasternodeBroadcast.lastPing is probably outdated, so we'll update it

View File

@ -251,6 +251,7 @@ public:
int GetMasternodeInputAge()
{
LOCK(cs_main);
if(chainActive.Tip() == NULL) return 0;
if(cacheInputAge == 0){
@ -258,7 +259,7 @@ public:
cacheInputAgeBlock = chainActive.Tip()->nHeight;
}
return cacheInputAge+(chainActive.Tip()->nHeight-cacheInputAgeBlock);
return cacheInputAge + (chainActive.Tip()->nHeight - cacheInputAgeBlock);
}
std::string Status() {

View File

@ -351,9 +351,6 @@ void OverviewPage::updateDarksendProgress()
double nAverageAnonymizedRounds;
{
TRY_LOCK(cs_main, lockMain);
if(!lockMain) return;
nDenominatedConfirmedBalance = pwalletMain->GetDenominatedBalance();
nDenominatedUnconfirmedBalance = pwalletMain->GetDenominatedBalance(true);
nAnonymizableBalance = pwalletMain->GetAnonymizableBalance();
@ -434,12 +431,10 @@ void OverviewPage::updateDarksendProgress()
void OverviewPage::darkSendStatus()
{
if (!chainActive.Tip()) return;
if(!masternodeSync.IsBlockchainSynced() || ShutdownRequested()) return;
static int64_t nLastDSProgressBlockTime = 0;
int nBestHeight = chainActive.Tip()->nHeight;
int nBestHeight = clientModel->getNumBlocks();
// we we're processing more then 1 block per second, we'll just leave
if(((nBestHeight - darkSendPool.cachedNumBlocks) / (GetTimeMillis() - nLastDSProgressBlockTime + 1) > 1)) return;

View File

@ -583,9 +583,6 @@ void SendCoinsDialog::setBalance(const CAmount& balance, const CAmount& unconfir
void SendCoinsDialog::updateDisplayUnit()
{
TRY_LOCK(cs_main, lockMain);
if(!lockMain) return;
setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance(), model->getAnonymizedBalance(),
model->getWatchBalance(), model->getWatchUnconfirmedBalance(), model->getWatchImmatureBalance());
CoinControlDialog::coinControl->useDarkSend = ui->checkUseDarksend->isChecked();

View File

@ -146,9 +146,6 @@ void WalletModel::pollBalanceChanged()
void WalletModel::checkBalanceChanged()
{
TRY_LOCK(cs_main, lockMain);
if(!lockMain) return;
CAmount newBalance = getBalance();
CAmount newUnconfirmedBalance = getUnconfirmedBalance();
CAmount newImmatureBalance = getImmatureBalance();

View File

@ -53,19 +53,21 @@ UniValue mnbudget(const UniValue& params, bool fHelp)
if(strCommand == "nextblock")
{
CBlockIndex* pindexPrev = chainActive.Tip();
if(!pindexPrev) return "unknown";
LOCK(cs_main);
CBlockIndex* pindex = chainActive.Tip();
if(!pindex) return "unknown";
int nNext = pindexPrev->nHeight - pindexPrev->nHeight % Params().GetConsensus().nBudgetPaymentsCycleBlocks + Params().GetConsensus().nBudgetPaymentsCycleBlocks;
int nNext = pindex->nHeight - pindex->nHeight % Params().GetConsensus().nBudgetPaymentsCycleBlocks + Params().GetConsensus().nBudgetPaymentsCycleBlocks;
return nNext;
}
if(strCommand == "nextsuperblocksize")
{
CBlockIndex* pindexPrev = chainActive.Tip();
if(!pindexPrev) return "unknown";
LOCK(cs_main);
CBlockIndex* pindex = chainActive.Tip();
if(!pindex) return "unknown";
int nHeight = pindexPrev->nHeight - pindexPrev->nHeight % Params().GetConsensus().nBudgetPaymentsCycleBlocks + Params().GetConsensus().nBudgetPaymentsCycleBlocks;
int nHeight = pindex->nHeight - pindex->nHeight % Params().GetConsensus().nBudgetPaymentsCycleBlocks + Params().GetConsensus().nBudgetPaymentsCycleBlocks;
CAmount nTotal = budget.GetTotalBudget(nHeight);
return nTotal;
@ -77,7 +79,8 @@ UniValue mnbudget(const UniValue& params, bool fHelp)
throw runtime_error("Correct usage is 'mnbudget prepare <proposal-name> <url> <payment-count> <block-start> <dash-address> <monthly-payment-dash>'");
int nBlockMin = 0;
CBlockIndex* pindexPrev = chainActive.Tip();
LOCK(cs_main);
CBlockIndex* pindex = chainActive.Tip();
std::vector<CMasternodeConfig::CMasternodeEntry> mnEntries;
mnEntries = masternodeConfig.getEntries();
@ -88,7 +91,7 @@ UniValue mnbudget(const UniValue& params, bool fHelp)
int nBlockStart = params[4].get_int();
//set block min
if(pindexPrev != NULL) nBlockMin = pindexPrev->nHeight;
if(pindex != NULL) nBlockMin = pindex->nHeight;
if(nBlockStart < nBlockMin)
return "Invalid block start, must be more than current height.";
@ -107,7 +110,7 @@ UniValue mnbudget(const UniValue& params, bool fHelp)
CBudgetProposalBroadcast budgetProposalBroadcast(strProposalName, strURL, nPaymentCount, scriptPubKey, nAmount, nBlockStart, uint256());
std::string strError = "";
if(!budgetProposalBroadcast.IsValid(strError, false))
if(!budgetProposalBroadcast.IsValid(pindex, strError, false))
return "Proposal is not valid - " + budgetProposalBroadcast.GetHash().ToString() + " - " + strError;
bool useIX = false; //true;
@ -140,7 +143,8 @@ UniValue mnbudget(const UniValue& params, bool fHelp)
}
int nBlockMin = 0;
CBlockIndex* pindexPrev = chainActive.Tip();
LOCK(cs_main);
CBlockIndex* pindex = chainActive.Tip();
std::vector<CMasternodeConfig::CMasternodeEntry> mnEntries;
mnEntries = masternodeConfig.getEntries();
@ -151,7 +155,7 @@ UniValue mnbudget(const UniValue& params, bool fHelp)
int nBlockStart = params[4].get_int();
//set block min
if(pindexPrev != NULL) nBlockMin = pindexPrev->nHeight;
if(pindex != NULL) nBlockMin = pindex->nHeight;
if(nBlockStart < nBlockMin)
return "Invalid payment count, must be more than current height.";
@ -170,7 +174,7 @@ UniValue mnbudget(const UniValue& params, bool fHelp)
std::string strError = "";
if(!budgetProposalBroadcast.IsValid(strError)){
if(!budgetProposalBroadcast.IsValid(pindex, strError)){
return "Proposal is not valid - " + budgetProposalBroadcast.GetHash().ToString() + " - " + strError;
}
@ -404,6 +408,12 @@ UniValue mnbudget(const UniValue& params, bool fHelp)
if(strCommand == "projection")
{
CBlockIndex* pindex;
{
LOCK(cs_main);
pindex = chainActive.Tip();
}
UniValue resultObj(UniValue::VOBJ);
CAmount nTotalAllotted = 0;
@ -434,7 +444,7 @@ UniValue mnbudget(const UniValue& params, bool fHelp)
bObj.push_back(Pair("Alloted", ValueFromAmount(pbudgetProposal->GetAllotted())));
std::string strError = "";
bObj.push_back(Pair("IsValid", pbudgetProposal->IsValid(strError)));
bObj.push_back(Pair("IsValid", pbudgetProposal->IsValid(pindex, strError)));
bObj.push_back(Pair("IsValidReason", strError.c_str()));
bObj.push_back(Pair("fValid", pbudgetProposal->fValid));
@ -453,6 +463,12 @@ UniValue mnbudget(const UniValue& params, bool fHelp)
std::string strShow = "valid";
if (params.size() == 2) strShow = params[1].get_str();
CBlockIndex* pindex;
{
LOCK(cs_main);
pindex = chainActive.Tip();
}
UniValue resultObj(UniValue::VOBJ);
int64_t nTotalAllotted = 0;
@ -488,7 +504,7 @@ UniValue mnbudget(const UniValue& params, bool fHelp)
bObj.push_back(Pair("IsEstablished", pbudgetProposal->IsEstablished()));
std::string strError = "";
bObj.push_back(Pair("IsValid", pbudgetProposal->IsValid(strError)));
bObj.push_back(Pair("IsValid", pbudgetProposal->IsValid(pindex, strError)));
bObj.push_back(Pair("IsValidReason", strError.c_str()));
bObj.push_back(Pair("fValid", pbudgetProposal->fValid));
@ -544,6 +560,7 @@ UniValue mnbudget(const UniValue& params, bool fHelp)
ExtractDestination(pbudgetProposal->GetPayee(), address1);
CBitcoinAddress address2(address1);
LOCK(cs_main);
UniValue obj(UniValue::VOBJ);
obj.push_back(Pair("Name", pbudgetProposal->GetName()));
obj.push_back(Pair("Hash", pbudgetProposal->GetHash().ToString()));
@ -565,7 +582,7 @@ UniValue mnbudget(const UniValue& params, bool fHelp)
obj.push_back(Pair("IsEstablished", pbudgetProposal->IsEstablished()));
std::string strError = "";
obj.push_back(Pair("IsValid", pbudgetProposal->IsValid(strError)));
obj.push_back(Pair("IsValid", pbudgetProposal->IsValid(chainActive.Tip(), strError)));
obj.push_back(Pair("fValid", pbudgetProposal->fValid));
return obj;
@ -803,6 +820,7 @@ UniValue mnfinalbudget(const UniValue& params, bool fHelp)
UniValue resultObj(UniValue::VOBJ);
std::vector<CFinalizedBudget*> winningFbs = budget.GetFinalizedBudgets();
LOCK(cs_main);
BOOST_FOREACH(CFinalizedBudget* finalizedBudget, winningFbs)
{
UniValue bObj(UniValue::VOBJ);
@ -815,7 +833,7 @@ UniValue mnfinalbudget(const UniValue& params, bool fHelp)
bObj.push_back(Pair("Status", finalizedBudget->GetStatus()));
std::string strError = "";
bObj.push_back(Pair("IsValid", finalizedBudget->IsValid(strError)));
bObj.push_back(Pair("IsValid", finalizedBudget->IsValid(chainActive.Tip(), strError)));
bObj.push_back(Pair("IsValidReason", strError.c_str()));
resultObj.push_back(Pair(finalizedBudget->GetName(), bObj));
@ -887,11 +905,11 @@ UniValue mnfinalbudget(const UniValue& params, bool fHelp)
return "Invalid finalized proposal";
}
LOCK(cs_main);
CBlockIndex* pindex = chainActive.Tip();
if(!pindex) return "invalid chaintip";
CBlockIndex* pindexPrev = chainActive.Tip();
if(!pindexPrev) return "invalid chaintip";
int nBlockStart = pindexPrev->nHeight - pindexPrev->nHeight % Params().GetConsensus().nBudgetPaymentsCycleBlocks + Params().GetConsensus().nBudgetPaymentsCycleBlocks;
int nBlockStart = pindex->nHeight - pindex->nHeight % Params().GetConsensus().nBudgetPaymentsCycleBlocks + Params().GetConsensus().nBudgetPaymentsCycleBlocks;
CFinalizedBudgetBroadcast tempBudget("main", nBlockStart, vecTxBudgetPayments, uint256());
// if(mapSeenFinalizedBudgets.count(tempBudget.GetHash())) {
@ -945,10 +963,11 @@ UniValue mnfinalbudget(const UniValue& params, bool fHelp)
return "Invalid finalized proposal";
}
CBlockIndex* pindexPrev = chainActive.Tip();
if(!pindexPrev) return "invalid chaintip";
LOCK(cs_main);
CBlockIndex* pindex = chainActive.Tip();
if(!pindex) return "invalid chaintip";
int nBlockStart = pindexPrev->nHeight - pindexPrev->nHeight % Params().GetConsensus().nBudgetPaymentsCycleBlocks + Params().GetConsensus().nBudgetPaymentsCycleBlocks;
int nBlockStart = pindex->nHeight - pindex->nHeight % Params().GetConsensus().nBudgetPaymentsCycleBlocks + Params().GetConsensus().nBudgetPaymentsCycleBlocks;
// CTxIn in(COutPoint(nColHash, 0));
// int conf = GetInputAgeIX(nColHash, in);
@ -965,7 +984,7 @@ UniValue mnfinalbudget(const UniValue& params, bool fHelp)
CFinalizedBudgetBroadcast finalizedBudgetBroadcast("main", nBlockStart, vecTxBudgetPayments, nColHash);
std::string strError = "";
if(!finalizedBudgetBroadcast.IsValid(strError)){
if(!finalizedBudgetBroadcast.IsValid(pindex, strError)){
printf("CBudgetManager::SubmitFinalBudget - Invalid finalized budget - %s \n", strError.c_str());
return "invalid finalized budget";
}

View File

@ -155,8 +155,11 @@ UniValue masternode(const UniValue& params, bool fHelp)
{
int nCount = 0;
if(chainActive.Tip())
mnodeman.GetNextMasternodeInQueueForPayment(chainActive.Tip()->nHeight, true, nCount);
{
LOCK(cs_main);
if(chainActive.Tip())
mnodeman.GetNextMasternodeInQueueForPayment(chainActive.Tip()->nHeight, true, nCount);
}
if(params[1].get_str() == "ds") return mnodeman.CountEnabled(MIN_POOL_PEER_PROTO_VERSION);
if(params[1].get_str() == "enabled") return mnodeman.CountEnabled();
@ -172,7 +175,10 @@ UniValue masternode(const UniValue& params, bool fHelp)
if (strCommand == "current")
{
CMasternode* winner = mnodeman.GetCurrentMasterNode(1);
LOCK(cs_main);
CMasternode* winner = NULL;
if(chainActive.Tip())
winner = mnodeman.GetCurrentMasterNode(1);
if(winner) {
UniValue obj(UniValue::VOBJ);
@ -425,6 +431,15 @@ UniValue masternode(const UniValue& params, bool fHelp)
if (strCommand == "winners")
{
int nHeight;
{
LOCK(cs_main);
CBlockIndex* pindex = chainActive.Tip();
if(!pindex) return NullUniValue;
nHeight = pindex->nHeight;
}
int nLast = 10;
if (params.size() >= 2){
@ -433,9 +448,9 @@ UniValue masternode(const UniValue& params, bool fHelp)
UniValue obj(UniValue::VOBJ);
for(int nHeight = chainActive.Tip()->nHeight-nLast; nHeight < chainActive.Tip()->nHeight+20; nHeight++)
for(int i = nHeight - nLast; i < nHeight + 20; i++)
{
obj.push_back(Pair(strprintf("%d", nHeight), GetRequiredPaymentsString(nHeight)));
obj.push_back(Pair(strprintf("%d", i), GetRequiredPaymentsString(i)));
}
return obj;
@ -447,6 +462,15 @@ UniValue masternode(const UniValue& params, bool fHelp)
if (strCommand == "calcscore")
{
int nHeight;
{
LOCK(cs_main);
CBlockIndex* pindex = chainActive.Tip();
if(!pindex) return NullUniValue;
nHeight = pindex->nHeight;
}
int nLast = 10;
if (params.size() >= 2){
@ -455,18 +479,18 @@ UniValue masternode(const UniValue& params, bool fHelp)
UniValue obj(UniValue::VOBJ);
std::vector<CMasternode> vMasternodes = mnodeman.GetFullMasternodeVector();
for(int nHeight = chainActive.Tip()->nHeight-nLast; nHeight < chainActive.Tip()->nHeight+20; nHeight++){
for(int i = nHeight - nLast; i < nHeight + 20; i++){
arith_uint256 nHigh = 0;
CMasternode *pBestMasternode = NULL;
BOOST_FOREACH(CMasternode& mn, vMasternodes) {
arith_uint256 n = UintToArith256(mn.CalculateScore(1, nHeight-100));
arith_uint256 n = UintToArith256(mn.CalculateScore(1, i - 100));
if(n > nHigh){
nHigh = n;
pBestMasternode = &mn;
}
}
if(pBestMasternode)
obj.push_back(Pair(strprintf("%d", nHeight), pBestMasternode->vin.prevout.ToStringShort().c_str()));
obj.push_back(Pair(strprintf("%d", i), pBestMasternode->vin.prevout.ToStringShort().c_str()));
}
return obj;

View File

@ -39,6 +39,7 @@ void ProcessSpork(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
CSporkMessage spork;
vRecv >> spork;
LOCK(cs_main);
if(chainActive.Tip() == NULL) return;
uint256 hash = spork.GetHash();

View File

@ -8,6 +8,7 @@
#include "consensus/merkle.h"
#include "consensus/validation.h"
#include "main.h"
#include "masternode-payments.h"
#include "miner.h"
#include "pubkey.h"
#include "script/standard.h"
@ -74,6 +75,9 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
LOCK(cs_main);
fCheckpointsEnabled = false;
// force UpdatedBlockTip to initialize pCurrentBlockIndex
mnpayments.UpdatedBlockTip(chainActive.Tip());
// Simple block creation, nothing special yet:
BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey));