mirror of
https://github.com/dashpay/dash.git
synced 2024-12-28 05:23:01 +01:00
Merge pull request #1009 from UdjinM6/lastPaid
Improve mn winners detection
This commit is contained in:
commit
6f84dc15c0
@ -302,7 +302,7 @@ void CMasternodePayments::ProcessMessage(CNode* pfrom, std::string& strCommand,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nFirstBlock = pCurrentBlockIndex->nHeight - mnodeman.CountEnabled()*1.25;
|
int nFirstBlock = pCurrentBlockIndex->nHeight - GetStorageLimit();
|
||||||
if(winner.nBlockHeight < nFirstBlock || winner.nBlockHeight > pCurrentBlockIndex->nHeight+20) {
|
if(winner.nBlockHeight < nFirstBlock || winner.nBlockHeight > pCurrentBlockIndex->nHeight+20) {
|
||||||
LogPrint("mnpayments", "MNWINNER -- winner out of range: nFirstBlock=%d, nBlockHeight=%d, nHeight=%d\n", nFirstBlock, winner.nBlockHeight, pCurrentBlockIndex->nHeight);
|
LogPrint("mnpayments", "MNWINNER -- winner out of range: nFirstBlock=%d, nBlockHeight=%d, nHeight=%d\n", nFirstBlock, winner.nBlockHeight, pCurrentBlockIndex->nHeight);
|
||||||
return;
|
return;
|
||||||
@ -692,8 +692,8 @@ void CMasternodePayments::Sync(CNode* node, int nCountNeeded)
|
|||||||
|
|
||||||
if(!pCurrentBlockIndex) return;
|
if(!pCurrentBlockIndex) return;
|
||||||
|
|
||||||
int nCount = (mnodeman.CountEnabled()*1.25);
|
int nLimit = GetStorageLimit();
|
||||||
if(nCountNeeded > nCount) nCountNeeded = nCount;
|
if(nCountNeeded > nLimit) nCountNeeded = nLimit;
|
||||||
|
|
||||||
int nInvCount = 0;
|
int nInvCount = 0;
|
||||||
std::map<uint256, CMasternodePaymentWinner>::iterator it = mapMasternodePayeeVotes.begin();
|
std::map<uint256, CMasternodePaymentWinner>::iterator it = mapMasternodePayeeVotes.begin();
|
||||||
@ -768,6 +768,11 @@ bool CMasternodePayments::IsEnoughData(int nMnCount) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CMasternodePayments::GetStorageLimit()
|
||||||
|
{
|
||||||
|
return std::max(int(mnodeman.size() * nStorageCoeff), nMinBlocksToStore);
|
||||||
|
}
|
||||||
|
|
||||||
void CMasternodePayments::UpdatedBlockTip(const CBlockIndex *pindex)
|
void CMasternodePayments::UpdatedBlockTip(const CBlockIndex *pindex)
|
||||||
{
|
{
|
||||||
pCurrentBlockIndex = pindex;
|
pCurrentBlockIndex = pindex;
|
||||||
@ -776,4 +781,6 @@ void CMasternodePayments::UpdatedBlockTip(const CBlockIndex *pindex)
|
|||||||
if (!fLiteMode && masternodeSync.IsMasternodeListSynced()) {
|
if (!fLiteMode && masternodeSync.IsMasternodeListSynced()) {
|
||||||
ProcessBlock(pindex->nHeight + 10);
|
ProcessBlock(pindex->nHeight + 10);
|
||||||
}
|
}
|
||||||
|
// normal wallet does not need to update this every block, doing update on rpc call should be enough
|
||||||
|
if(fMasterNode) mnodeman.UpdateLastPaid(pindex);
|
||||||
}
|
}
|
||||||
|
@ -272,6 +272,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool IsEnoughData(int nMnCount);
|
bool IsEnoughData(int nMnCount);
|
||||||
|
int GetStorageLimit();
|
||||||
|
|
||||||
ADD_SERIALIZE_METHODS;
|
ADD_SERIALIZE_METHODS;
|
||||||
|
|
||||||
|
@ -296,7 +296,7 @@ void CMasternodeSync::ProcessTick()
|
|||||||
// check for data
|
// check for data
|
||||||
// if mnpayments already has enough blocks and votes, switch to the next asset
|
// if mnpayments already has enough blocks and votes, switch to the next asset
|
||||||
// try to fetch data from at least two peers though
|
// try to fetch data from at least two peers though
|
||||||
if(nRequestedMasternodeAttempt > 1 && mnpayments.IsEnoughData(nMnCount)) {
|
if(nRequestedMasternodeAttempt > 1 && mnpayments.IsEnoughData(mnpayments.GetStorageLimit())) {
|
||||||
LogPrintf("CMasternodeSync::Process -- nTick %d nRequestedMasternodeAssets %d -- found enough data\n", nTick, nRequestedMasternodeAssets);
|
LogPrintf("CMasternodeSync::Process -- nTick %d nRequestedMasternodeAssets %d -- found enough data\n", nTick, nRequestedMasternodeAssets);
|
||||||
SwitchToNextAsset();
|
SwitchToNextAsset();
|
||||||
return;
|
return;
|
||||||
@ -309,7 +309,7 @@ void CMasternodeSync::ProcessTick()
|
|||||||
if(pnode->nVersion < mnpayments.GetMinMasternodePaymentsProto()) continue;
|
if(pnode->nVersion < mnpayments.GetMinMasternodePaymentsProto()) continue;
|
||||||
nRequestedMasternodeAttempt++;
|
nRequestedMasternodeAttempt++;
|
||||||
|
|
||||||
pnode->PushMessage(NetMsgType::MNWINNERSSYNC, nMnCount); //sync payees
|
pnode->PushMessage(NetMsgType::MNWINNERSSYNC, mnpayments.GetStorageLimit()); //sync payees
|
||||||
|
|
||||||
|
|
||||||
return; //this will cause each peer to get one request each six seconds for the various assets we need
|
return; //this will cause each peer to get one request each six seconds for the various assets we need
|
||||||
|
@ -30,8 +30,9 @@ CMasternode::CMasternode()
|
|||||||
activeState = MASTERNODE_ENABLED;
|
activeState = MASTERNODE_ENABLED;
|
||||||
sigTime = GetAdjustedTime();
|
sigTime = GetAdjustedTime();
|
||||||
lastPing = CMasternodePing();
|
lastPing = CMasternodePing();
|
||||||
cacheInputAge = 0;
|
nTimeLastPaid = 0;
|
||||||
cacheInputAgeBlock = 0;
|
nBlockLastPaid = 0;
|
||||||
|
nCacheCollateralBlock = 0;
|
||||||
unitTest = false;
|
unitTest = false;
|
||||||
allowFreeTx = true;
|
allowFreeTx = true;
|
||||||
protocolVersion = PROTOCOL_VERSION;
|
protocolVersion = PROTOCOL_VERSION;
|
||||||
@ -52,8 +53,9 @@ CMasternode::CMasternode(const CMasternode& other)
|
|||||||
activeState = other.activeState;
|
activeState = other.activeState;
|
||||||
sigTime = other.sigTime;
|
sigTime = other.sigTime;
|
||||||
lastPing = other.lastPing;
|
lastPing = other.lastPing;
|
||||||
cacheInputAge = other.cacheInputAge;
|
nTimeLastPaid = other.nTimeLastPaid;
|
||||||
cacheInputAgeBlock = other.cacheInputAgeBlock;
|
nBlockLastPaid = other.nBlockLastPaid;
|
||||||
|
nCacheCollateralBlock = other.nCacheCollateralBlock;
|
||||||
unitTest = other.unitTest;
|
unitTest = other.unitTest;
|
||||||
allowFreeTx = other.allowFreeTx;
|
allowFreeTx = other.allowFreeTx;
|
||||||
protocolVersion = other.protocolVersion;
|
protocolVersion = other.protocolVersion;
|
||||||
@ -74,8 +76,9 @@ CMasternode::CMasternode(const CMasternodeBroadcast& mnb)
|
|||||||
activeState = MASTERNODE_ENABLED;
|
activeState = MASTERNODE_ENABLED;
|
||||||
sigTime = mnb.sigTime;
|
sigTime = mnb.sigTime;
|
||||||
lastPing = mnb.lastPing;
|
lastPing = mnb.lastPing;
|
||||||
cacheInputAge = 0;
|
nTimeLastPaid = 0;
|
||||||
cacheInputAgeBlock = 0;
|
nBlockLastPaid = 0;
|
||||||
|
nCacheCollateralBlock = 0;
|
||||||
unitTest = false;
|
unitTest = false;
|
||||||
allowFreeTx = true;
|
allowFreeTx = true;
|
||||||
protocolVersion = mnb.protocolVersion;
|
protocolVersion = mnb.protocolVersion;
|
||||||
@ -200,57 +203,54 @@ void CMasternode::Check(bool forceCheck)
|
|||||||
activeState = MASTERNODE_ENABLED; // OK
|
activeState = MASTERNODE_ENABLED; // OK
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t CMasternode::SecondsSincePayment() {
|
int CMasternode::GetCollateralAge()
|
||||||
int64_t sec = (GetAdjustedTime() - GetLastPaid());
|
|
||||||
int64_t month = 60*60*24*30;
|
|
||||||
if(sec < month) return sec; //if it's less than 30 days, give seconds
|
|
||||||
|
|
||||||
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
|
|
||||||
ss << vin;
|
|
||||||
ss << sigTime;
|
|
||||||
uint256 hash = ss.GetHash();
|
|
||||||
|
|
||||||
// return some deterministic value for unknown/unpaid but force it to be more than 30 days old
|
|
||||||
return month + UintToArith256(hash).GetCompact(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t CMasternode::GetLastPaid() {
|
|
||||||
CBlockIndex *pindexPrev = NULL;
|
|
||||||
{
|
{
|
||||||
LOCK(cs_main);
|
int nHeight;
|
||||||
pindexPrev = chainActive.Tip();
|
{
|
||||||
if(!pindexPrev) return 0;
|
TRY_LOCK(cs_main, lockMain);
|
||||||
|
if(!lockMain || !chainActive.Tip()) return -1;
|
||||||
|
nHeight = chainActive.Height();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nCacheCollateralBlock == 0) {
|
||||||
CScript mnpayee;
|
int nInputAge = GetInputAge(vin);
|
||||||
mnpayee = GetScriptForDestination(pubkey.GetID());
|
if(nInputAge > 0) {
|
||||||
|
nCacheCollateralBlock = nHeight - nInputAge;
|
||||||
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
|
} else {
|
||||||
ss << vin;
|
return nInputAge;
|
||||||
ss << sigTime;
|
}
|
||||||
uint256 hash = ss.GetHash();
|
|
||||||
|
|
||||||
// use a deterministic offset to break a tie -- 2.5 minutes
|
|
||||||
int64_t nOffset = UintToArith256(hash).GetCompact(false) % 150;
|
|
||||||
|
|
||||||
const CBlockIndex *BlockReading = pindexPrev;
|
|
||||||
|
|
||||||
int nMnCount = mnodeman.CountEnabled()*1.25;
|
|
||||||
int n = 0;
|
|
||||||
for (unsigned int i = 1; BlockReading && BlockReading->nHeight > 0; i++) {
|
|
||||||
if(n >= nMnCount){
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
n++;
|
|
||||||
|
|
||||||
if(mnpayments.mapMasternodeBlocks.count(BlockReading->nHeight)){
|
return nHeight - nCacheCollateralBlock;
|
||||||
/*
|
}
|
||||||
Search for this payee, with at least 2 votes. This will aid in consensus allowing the network
|
|
||||||
to converge on the same payees quickly, then keep the same schedule.
|
void CMasternode::UpdateLastPaid(const CBlockIndex *pindex, int nMaxBlocksToScanBack)
|
||||||
*/
|
{
|
||||||
if(mnpayments.mapMasternodeBlocks[BlockReading->nHeight].HasPayeeWithVotes(mnpayee, 2)){
|
if(!pindex) return;
|
||||||
return BlockReading->nTime + nOffset;
|
|
||||||
|
const CBlockIndex *BlockReading = pindex;
|
||||||
|
|
||||||
|
CScript mnpayee = GetScriptForDestination(pubkey.GetID());
|
||||||
|
// LogPrint("masternode", "CMasternode::UpdateLastPaidBlock -- searching for block with payment to %s\n", vin.prevout.ToStringShort());
|
||||||
|
|
||||||
|
LOCK(cs_mapMasternodeBlocks);
|
||||||
|
|
||||||
|
for (int i = 0; BlockReading && BlockReading->nHeight > nBlockLastPaid && i < nMaxBlocksToScanBack; i++) {
|
||||||
|
if(mnpayments.mapMasternodeBlocks.count(BlockReading->nHeight) &&
|
||||||
|
mnpayments.mapMasternodeBlocks[BlockReading->nHeight].HasPayeeWithVotes(mnpayee, 2))
|
||||||
|
{
|
||||||
|
CBlock block;
|
||||||
|
if(!ReadBlockFromDisk(block, BlockReading, Params().GetConsensus())) // shouldn't really happen
|
||||||
|
continue;
|
||||||
|
|
||||||
|
CAmount nMasternodePayment = GetMasternodePayment(BlockReading->nHeight, block.vtx[0].GetValueOut());
|
||||||
|
|
||||||
|
BOOST_FOREACH(CTxOut txout, block.vtx[0].vout)
|
||||||
|
if(mnpayee == txout.scriptPubKey && nMasternodePayment == txout.nValue) {
|
||||||
|
nBlockLastPaid = BlockReading->nHeight;
|
||||||
|
nTimeLastPaid = BlockReading->nTime;
|
||||||
|
LogPrint("masternode", "CMasternode::UpdateLastPaidBlock -- searching for block with payment to %s -- found new %d\n", vin.prevout.ToStringShort(), nBlockLastPaid);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,7 +258,9 @@ int64_t CMasternode::GetLastPaid() {
|
|||||||
BlockReading = BlockReading->pprev;
|
BlockReading = BlockReading->pprev;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
// Last payment for this masternode wasn't found in latest mnpayments blocks
|
||||||
|
// or it was found in mnpayments blocks but wasn't found in the blockchain.
|
||||||
|
// LogPrint("masternode", "CMasternode::UpdateLastPaidBlock -- searching for block with payment to %s -- keeping old %d\n", vin.prevout.ToStringShort(), nBlockLastPaid);
|
||||||
}
|
}
|
||||||
|
|
||||||
CMasternodeBroadcast::CMasternodeBroadcast()
|
CMasternodeBroadcast::CMasternodeBroadcast()
|
||||||
@ -271,8 +273,9 @@ CMasternodeBroadcast::CMasternodeBroadcast()
|
|||||||
activeState = MASTERNODE_ENABLED;
|
activeState = MASTERNODE_ENABLED;
|
||||||
sigTime = GetAdjustedTime();
|
sigTime = GetAdjustedTime();
|
||||||
lastPing = CMasternodePing();
|
lastPing = CMasternodePing();
|
||||||
cacheInputAge = 0;
|
nTimeLastPaid = 0;
|
||||||
cacheInputAgeBlock = 0;
|
nBlockLastPaid = 0;
|
||||||
|
nCacheCollateralBlock = 0;
|
||||||
unitTest = false;
|
unitTest = false;
|
||||||
allowFreeTx = true;
|
allowFreeTx = true;
|
||||||
protocolVersion = PROTOCOL_VERSION;
|
protocolVersion = PROTOCOL_VERSION;
|
||||||
@ -291,8 +294,9 @@ CMasternodeBroadcast::CMasternodeBroadcast(CService newAddr, CTxIn newVin, CPubK
|
|||||||
activeState = MASTERNODE_ENABLED;
|
activeState = MASTERNODE_ENABLED;
|
||||||
sigTime = GetAdjustedTime();
|
sigTime = GetAdjustedTime();
|
||||||
lastPing = CMasternodePing();
|
lastPing = CMasternodePing();
|
||||||
cacheInputAge = 0;
|
nTimeLastPaid = 0;
|
||||||
cacheInputAgeBlock = 0;
|
nBlockLastPaid = 0;
|
||||||
|
nCacheCollateralBlock = 0;
|
||||||
unitTest = false;
|
unitTest = false;
|
||||||
allowFreeTx = true;
|
allowFreeTx = true;
|
||||||
protocolVersion = protocolVersionIn;
|
protocolVersion = protocolVersionIn;
|
||||||
@ -311,8 +315,9 @@ CMasternodeBroadcast::CMasternodeBroadcast(const CMasternode& mn)
|
|||||||
activeState = mn.activeState;
|
activeState = mn.activeState;
|
||||||
sigTime = mn.sigTime;
|
sigTime = mn.sigTime;
|
||||||
lastPing = mn.lastPing;
|
lastPing = mn.lastPing;
|
||||||
cacheInputAge = mn.cacheInputAge;
|
nTimeLastPaid = mn.nTimeLastPaid;
|
||||||
cacheInputAgeBlock = mn.cacheInputAgeBlock;
|
nBlockLastPaid = mn.nBlockLastPaid;
|
||||||
|
nCacheCollateralBlock = mn.nCacheCollateralBlock;
|
||||||
unitTest = mn.unitTest;
|
unitTest = mn.unitTest;
|
||||||
allowFreeTx = mn.allowFreeTx;
|
allowFreeTx = mn.allowFreeTx;
|
||||||
protocolVersion = mn.protocolVersion;
|
protocolVersion = mn.protocolVersion;
|
||||||
|
@ -122,8 +122,9 @@ public:
|
|||||||
std::vector<unsigned char> vchSig;
|
std::vector<unsigned char> vchSig;
|
||||||
int activeState;
|
int activeState;
|
||||||
int64_t sigTime; //mnb message time
|
int64_t sigTime; //mnb message time
|
||||||
int cacheInputAge;
|
int64_t nTimeLastPaid;
|
||||||
int cacheInputAgeBlock;
|
int nBlockLastPaid;
|
||||||
|
int nCacheCollateralBlock;
|
||||||
bool unitTest;
|
bool unitTest;
|
||||||
bool allowFreeTx;
|
bool allowFreeTx;
|
||||||
int protocolVersion;
|
int protocolVersion;
|
||||||
@ -155,8 +156,9 @@ public:
|
|||||||
swap(first.activeState, second.activeState);
|
swap(first.activeState, second.activeState);
|
||||||
swap(first.sigTime, second.sigTime);
|
swap(first.sigTime, second.sigTime);
|
||||||
swap(first.lastPing, second.lastPing);
|
swap(first.lastPing, second.lastPing);
|
||||||
swap(first.cacheInputAge, second.cacheInputAge);
|
swap(first.nTimeLastPaid, second.nTimeLastPaid);
|
||||||
swap(first.cacheInputAgeBlock, second.cacheInputAgeBlock);
|
swap(first.nBlockLastPaid, second.nBlockLastPaid);
|
||||||
|
swap(first.nCacheCollateralBlock, second.nCacheCollateralBlock);
|
||||||
swap(first.unitTest, second.unitTest);
|
swap(first.unitTest, second.unitTest);
|
||||||
swap(first.allowFreeTx, second.allowFreeTx);
|
swap(first.allowFreeTx, second.allowFreeTx);
|
||||||
swap(first.protocolVersion, second.protocolVersion);
|
swap(first.protocolVersion, second.protocolVersion);
|
||||||
@ -204,8 +206,9 @@ public:
|
|||||||
READWRITE(protocolVersion);
|
READWRITE(protocolVersion);
|
||||||
READWRITE(activeState);
|
READWRITE(activeState);
|
||||||
READWRITE(lastPing);
|
READWRITE(lastPing);
|
||||||
READWRITE(cacheInputAge);
|
READWRITE(nTimeLastPaid);
|
||||||
READWRITE(cacheInputAgeBlock);
|
READWRITE(nBlockLastPaid);
|
||||||
|
READWRITE(nCacheCollateralBlock);
|
||||||
READWRITE(unitTest);
|
READWRITE(unitTest);
|
||||||
READWRITE(allowFreeTx);
|
READWRITE(allowFreeTx);
|
||||||
READWRITE(nLastDsq);
|
READWRITE(nLastDsq);
|
||||||
@ -257,19 +260,6 @@ public:
|
|||||||
return activeState == MASTERNODE_PRE_ENABLED;
|
return activeState == MASTERNODE_PRE_ENABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetMasternodeInputAge()
|
|
||||||
{
|
|
||||||
LOCK(cs_main);
|
|
||||||
if(chainActive.Tip() == NULL) return 0;
|
|
||||||
|
|
||||||
if(cacheInputAge == 0){
|
|
||||||
cacheInputAge = GetInputAge(vin);
|
|
||||||
cacheInputAgeBlock = chainActive.Tip()->nHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cacheInputAge + (chainActive.Tip()->nHeight - cacheInputAgeBlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Status() {
|
std::string Status() {
|
||||||
std::string strStatus = "unknown";
|
std::string strStatus = "unknown";
|
||||||
|
|
||||||
@ -283,7 +273,11 @@ public:
|
|||||||
return strStatus;
|
return strStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t GetLastPaid();
|
int GetCollateralAge();
|
||||||
|
|
||||||
|
int GetLastPaidTime() { return nTimeLastPaid; }
|
||||||
|
int GetLastPaidBlock() { return nBlockLastPaid; }
|
||||||
|
void UpdateLastPaid(const CBlockIndex *pindex, int nMaxBlocksToScanBack);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17,12 +17,12 @@
|
|||||||
/** Masternode manager */
|
/** Masternode manager */
|
||||||
CMasternodeMan mnodeman;
|
CMasternodeMan mnodeman;
|
||||||
|
|
||||||
struct CompareLastPaid
|
struct CompareLastPaidBlock
|
||||||
{
|
{
|
||||||
bool operator()(const pair<int64_t, CTxIn>& t1,
|
bool operator()(const std::pair<int, CTxIn>& t1,
|
||||||
const pair<int64_t, CTxIn>& t2) const
|
const std::pair<int, CTxIn>& t2) const
|
||||||
{
|
{
|
||||||
return t1.first < t2.first;
|
return (t1.first != t2.first) ? (t1.first < t2.first) : (t1.second < t2.second);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -311,7 +311,7 @@ CMasternode* CMasternodeMan::GetNextMasternodeInQueueForPayment(int nBlockHeight
|
|||||||
LOCK(cs);
|
LOCK(cs);
|
||||||
|
|
||||||
CMasternode *pBestMasternode = NULL;
|
CMasternode *pBestMasternode = NULL;
|
||||||
std::vector<pair<int64_t, CTxIn> > vecMasternodeLastPaid;
|
std::vector<std::pair<int, CTxIn> > vecMasternodeLastPaid;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Make a vector with all of the last paid times
|
Make a vector with all of the last paid times
|
||||||
@ -333,9 +333,9 @@ CMasternode* CMasternodeMan::GetNextMasternodeInQueueForPayment(int nBlockHeight
|
|||||||
if(fFilterSigTime && mn.sigTime + (nMnCount*2.6*60) > GetAdjustedTime()) continue;
|
if(fFilterSigTime && mn.sigTime + (nMnCount*2.6*60) > GetAdjustedTime()) continue;
|
||||||
|
|
||||||
//make sure it has as many confirmations as there are masternodes
|
//make sure it has as many confirmations as there are masternodes
|
||||||
if(mn.GetMasternodeInputAge() < nMnCount) continue;
|
if(mn.GetCollateralAge() < nMnCount) continue;
|
||||||
|
|
||||||
vecMasternodeLastPaid.push_back(make_pair(mn.SecondsSincePayment(), mn.vin));
|
vecMasternodeLastPaid.push_back(std::make_pair(mn.GetLastPaidBlock(), mn.vin));
|
||||||
}
|
}
|
||||||
|
|
||||||
nCount = (int)vecMasternodeLastPaid.size();
|
nCount = (int)vecMasternodeLastPaid.size();
|
||||||
@ -343,8 +343,8 @@ CMasternode* CMasternodeMan::GetNextMasternodeInQueueForPayment(int nBlockHeight
|
|||||||
//when the network is in the process of upgrading, don't penalize nodes that recently restarted
|
//when the network is in the process of upgrading, don't penalize nodes that recently restarted
|
||||||
if(fFilterSigTime && nCount < nMnCount/3) return GetNextMasternodeInQueueForPayment(nBlockHeight, false, nCount);
|
if(fFilterSigTime && nCount < nMnCount/3) return GetNextMasternodeInQueueForPayment(nBlockHeight, false, nCount);
|
||||||
|
|
||||||
// Sort them high to low
|
// Sort them low to high
|
||||||
sort(vecMasternodeLastPaid.rbegin(), vecMasternodeLastPaid.rend(), CompareLastPaid());
|
sort(vecMasternodeLastPaid.begin(), vecMasternodeLastPaid.end(), CompareLastPaidBlock());
|
||||||
|
|
||||||
// Look at 1/10 of the oldest nodes (by last payment), calculate their scores and pay the best one
|
// Look at 1/10 of the oldest nodes (by last payment), calculate their scores and pay the best one
|
||||||
// -- This doesn't look at who is being paid in the +8-10 blocks, allowing for double payments very rarely
|
// -- This doesn't look at who is being paid in the +8-10 blocks, allowing for double payments very rarely
|
||||||
@ -353,7 +353,7 @@ CMasternode* CMasternodeMan::GetNextMasternodeInQueueForPayment(int nBlockHeight
|
|||||||
int nTenthNetwork = CountEnabled()/10;
|
int nTenthNetwork = CountEnabled()/10;
|
||||||
int nCountTenth = 0;
|
int nCountTenth = 0;
|
||||||
arith_uint256 nHigh = 0;
|
arith_uint256 nHigh = 0;
|
||||||
BOOST_FOREACH (PAIRTYPE(int64_t, CTxIn)& s, vecMasternodeLastPaid){
|
BOOST_FOREACH (PAIRTYPE(int, CTxIn)& s, vecMasternodeLastPaid){
|
||||||
CMasternode* pmn = Find(s.second);
|
CMasternode* pmn = Find(s.second);
|
||||||
if(!pmn) break;
|
if(!pmn) break;
|
||||||
|
|
||||||
@ -769,3 +769,22 @@ bool CMasternodeMan::CheckMnbAndUpdateMasternodeList(CMasternodeBroadcast mnb, i
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CMasternodeMan::UpdateLastPaid(const CBlockIndex *pindex) {
|
||||||
|
if(fLiteMode) return;
|
||||||
|
|
||||||
|
static bool IsFirstRun = true;
|
||||||
|
// Do full scan on first run or if we are not a masternode
|
||||||
|
// (MNs should update this info on every block, so limited scan should be enough for them)
|
||||||
|
int nMaxBlocksToScanBack = (IsFirstRun || !fMasterNode) ? mnpayments.GetStorageLimit() : MASTERNODES_LAST_PAID_SCAN_BLOCKS;
|
||||||
|
|
||||||
|
// LogPrint("mnpayments", "CMasternodeMan::UpdateLastPaid -- nHeight=%d, nMaxBlocksToScanBack=%d, IsFirstRun=%s\n",
|
||||||
|
// pindex->nHeight, nMaxBlocksToScanBack, IsFirstRun ? "true" : "false");
|
||||||
|
|
||||||
|
BOOST_FOREACH(CMasternode& mn, vMasternodes) {
|
||||||
|
mn.UpdateLastPaid(pindex, nMaxBlocksToScanBack);
|
||||||
|
}
|
||||||
|
|
||||||
|
// every time is like the first time if winners list is not synced
|
||||||
|
IsFirstRun = !masternodeSync.IsWinnersListSynced();
|
||||||
|
}
|
||||||
|
@ -24,6 +24,8 @@ extern CMasternodeMan mnodeman;
|
|||||||
class CMasternodeMan
|
class CMasternodeMan
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
static const int MASTERNODES_LAST_PAID_SCAN_BLOCKS = 100;
|
||||||
|
|
||||||
// critical section to protect the inner data structures
|
// critical section to protect the inner data structures
|
||||||
mutable CCriticalSection cs;
|
mutable CCriticalSection cs;
|
||||||
|
|
||||||
@ -134,6 +136,7 @@ public:
|
|||||||
/// Perform complete check and only then update list and maps
|
/// Perform complete check and only then update list and maps
|
||||||
bool CheckMnbAndUpdateMasternodeList(CMasternodeBroadcast mnb, int& nDos);
|
bool CheckMnbAndUpdateMasternodeList(CMasternodeBroadcast mnb, int& nDos);
|
||||||
|
|
||||||
|
void UpdateLastPaid(const CBlockIndex *pindex);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -477,9 +477,10 @@ UniValue masternodelist(const UniValue& params, bool fHelp)
|
|||||||
if (params.size() >= 1) strMode = params[0].get_str();
|
if (params.size() >= 1) strMode = params[0].get_str();
|
||||||
if (params.size() == 2) strFilter = params[1].get_str();
|
if (params.size() == 2) strFilter = params[1].get_str();
|
||||||
|
|
||||||
if (fHelp ||
|
if (fHelp || (
|
||||||
(strMode != "status" && strMode != "vin" && strMode != "pubkey" && strMode != "lastseen" && strMode != "activeseconds" && strMode != "rank" && strMode != "addr"
|
strMode != "activeseconds" && strMode != "addr" && strMode != "full" &&
|
||||||
&& strMode != "protocol" && strMode != "full" && strMode != "lastpaid"))
|
strMode != "lastseen" && strMode != "lastpaidtime" && strMode != "lastpaidblock" &&
|
||||||
|
strMode != "protocol" && strMode != "pubkey" && strMode != "rank" && strMode != "status"))
|
||||||
{
|
{
|
||||||
throw runtime_error(
|
throw runtime_error(
|
||||||
"masternodelist ( \"mode\" \"filter\" )\n"
|
"masternodelist ( \"mode\" \"filter\" )\n"
|
||||||
@ -492,10 +493,11 @@ UniValue masternodelist(const UniValue& params, bool fHelp)
|
|||||||
" activeseconds - Print number of seconds masternode recognized by the network as enabled\n"
|
" activeseconds - Print number of seconds masternode recognized by the network as enabled\n"
|
||||||
" (since latest issued \"masternode start/start-many/start-alias\")\n"
|
" (since latest issued \"masternode start/start-many/start-alias\")\n"
|
||||||
" addr - Print ip address associated with a masternode (can be additionally filtered, partial match)\n"
|
" addr - Print ip address associated with a masternode (can be additionally filtered, partial match)\n"
|
||||||
" full - Print info in format 'status protocol pubkey IP lastseen activeseconds lastpaid'\n"
|
" full - Print info in format 'status protocol pubkey IP lastseen activeseconds lastpaidtime'\n"
|
||||||
" (can be additionally filtered, partial match)\n"
|
" (can be additionally filtered, partial match)\n"
|
||||||
" lastseen - Print timestamp of when a masternode was last seen on the network\n"
|
" lastseen - Print timestamp of when a masternode was last seen on the network\n"
|
||||||
" lastpaid - The last time a node was paid on the network\n"
|
" lastpaidblock - Print the last block height a node was paid on the network\n"
|
||||||
|
" lastpaidtime - Print the last time a node was paid on the network\n"
|
||||||
" protocol - Print protocol of a masternode (can be additionally filtered, exact match))\n"
|
" protocol - Print protocol of a masternode (can be additionally filtered, exact match))\n"
|
||||||
" pubkey - Print public key associated with a masternode (can be additionally filtered,\n"
|
" pubkey - Print public key associated with a masternode (can be additionally filtered,\n"
|
||||||
" partial match)\n"
|
" partial match)\n"
|
||||||
@ -505,6 +507,15 @@ UniValue masternodelist(const UniValue& params, bool fHelp)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strMode == "full" || strMode == "lastpaidtime" || strMode == "lastpaidblock") {
|
||||||
|
CBlockIndex* pindex;
|
||||||
|
{
|
||||||
|
LOCK(cs_main);
|
||||||
|
pindex = chainActive.Tip();
|
||||||
|
}
|
||||||
|
mnodeman.UpdateLastPaid(pindex);
|
||||||
|
}
|
||||||
|
|
||||||
UniValue obj(UniValue::VOBJ);
|
UniValue obj(UniValue::VOBJ);
|
||||||
if (strMode == "rank") {
|
if (strMode == "rank") {
|
||||||
std::vector<pair<int, CMasternode> > vMasternodeRanks = mnodeman.GetMasternodeRanks(chainActive.Tip()->nHeight);
|
std::vector<pair<int, CMasternode> > vMasternodeRanks = mnodeman.GetMasternodeRanks(chainActive.Tip()->nHeight);
|
||||||
@ -536,7 +547,7 @@ UniValue masternodelist(const UniValue& params, bool fHelp)
|
|||||||
mn.addr.ToString() << " " <<
|
mn.addr.ToString() << " " <<
|
||||||
(int64_t)mn.lastPing.sigTime << " " << setw(8) <<
|
(int64_t)mn.lastPing.sigTime << " " << setw(8) <<
|
||||||
(int64_t)(mn.lastPing.sigTime - mn.sigTime) << " " <<
|
(int64_t)(mn.lastPing.sigTime - mn.sigTime) << " " <<
|
||||||
(int64_t)mn.GetLastPaid();
|
(int64_t)mn.GetLastPaidTime();
|
||||||
std::string output = stringStream.str();
|
std::string output = stringStream.str();
|
||||||
stringStream << " " << strVin;
|
stringStream << " " << strVin;
|
||||||
if(strFilter !="" && stringStream.str().find(strFilter) == string::npos &&
|
if(strFilter !="" && stringStream.str().find(strFilter) == string::npos &&
|
||||||
@ -545,10 +556,12 @@ UniValue masternodelist(const UniValue& params, bool fHelp)
|
|||||||
} else if (strMode == "lastseen") {
|
} else if (strMode == "lastseen") {
|
||||||
if(strFilter !="" && strVin.find(strFilter) == string::npos) continue;
|
if(strFilter !="" && strVin.find(strFilter) == string::npos) continue;
|
||||||
obj.push_back(Pair(strVin, (int64_t)mn.lastPing.sigTime));
|
obj.push_back(Pair(strVin, (int64_t)mn.lastPing.sigTime));
|
||||||
} else if (strMode == "lastpaid"){
|
} else if (strMode == "lastpaidblock") {
|
||||||
if(strFilter !="" && mn.vin.prevout.hash.ToString().find(strFilter) == string::npos &&
|
if (strFilter !="" && strVin.find(strFilter) == std::string::npos) continue;
|
||||||
strVin.find(strFilter) == string::npos) continue;
|
obj.push_back(Pair(strVin, mn.GetLastPaidBlock()));
|
||||||
obj.push_back(Pair(strVin, (int64_t)mn.GetLastPaid()));
|
} else if (strMode == "lastpaidtime") {
|
||||||
|
if (strFilter !="" && strVin.find(strFilter) == std::string::npos) continue;
|
||||||
|
obj.push_back(Pair(strVin, mn.GetLastPaidTime()));
|
||||||
} else if (strMode == "protocol") {
|
} else if (strMode == "protocol") {
|
||||||
if(strFilter !="" && strFilter != strprintf("%d", mn.protocolVersion) &&
|
if(strFilter !="" && strFilter != strprintf("%d", mn.protocolVersion) &&
|
||||||
strVin.find(strFilter) == string::npos) continue;
|
strVin.find(strFilter) == string::npos) continue;
|
||||||
|
Loading…
Reference in New Issue
Block a user