mirror of
https://github.com/dashpay/dash.git
synced 2024-12-27 13:03:17 +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;
|
||||
}
|
||||
|
||||
int nFirstBlock = pCurrentBlockIndex->nHeight - mnodeman.CountEnabled()*1.25;
|
||||
int nFirstBlock = pCurrentBlockIndex->nHeight - GetStorageLimit();
|
||||
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);
|
||||
return;
|
||||
@ -692,8 +692,8 @@ void CMasternodePayments::Sync(CNode* node, int nCountNeeded)
|
||||
|
||||
if(!pCurrentBlockIndex) return;
|
||||
|
||||
int nCount = (mnodeman.CountEnabled()*1.25);
|
||||
if(nCountNeeded > nCount) nCountNeeded = nCount;
|
||||
int nLimit = GetStorageLimit();
|
||||
if(nCountNeeded > nLimit) nCountNeeded = nLimit;
|
||||
|
||||
int nInvCount = 0;
|
||||
std::map<uint256, CMasternodePaymentWinner>::iterator it = mapMasternodePayeeVotes.begin();
|
||||
@ -768,6 +768,11 @@ bool CMasternodePayments::IsEnoughData(int nMnCount) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int CMasternodePayments::GetStorageLimit()
|
||||
{
|
||||
return std::max(int(mnodeman.size() * nStorageCoeff), nMinBlocksToStore);
|
||||
}
|
||||
|
||||
void CMasternodePayments::UpdatedBlockTip(const CBlockIndex *pindex)
|
||||
{
|
||||
pCurrentBlockIndex = pindex;
|
||||
@ -776,4 +781,6 @@ void CMasternodePayments::UpdatedBlockTip(const CBlockIndex *pindex)
|
||||
if (!fLiteMode && masternodeSync.IsMasternodeListSynced()) {
|
||||
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);
|
||||
int GetStorageLimit();
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
|
@ -296,7 +296,7 @@ void CMasternodeSync::ProcessTick()
|
||||
// check for data
|
||||
// if mnpayments already has enough blocks and votes, switch to the next asset
|
||||
// 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);
|
||||
SwitchToNextAsset();
|
||||
return;
|
||||
@ -309,7 +309,7 @@ void CMasternodeSync::ProcessTick()
|
||||
if(pnode->nVersion < mnpayments.GetMinMasternodePaymentsProto()) continue;
|
||||
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
|
||||
|
@ -30,8 +30,9 @@ CMasternode::CMasternode()
|
||||
activeState = MASTERNODE_ENABLED;
|
||||
sigTime = GetAdjustedTime();
|
||||
lastPing = CMasternodePing();
|
||||
cacheInputAge = 0;
|
||||
cacheInputAgeBlock = 0;
|
||||
nTimeLastPaid = 0;
|
||||
nBlockLastPaid = 0;
|
||||
nCacheCollateralBlock = 0;
|
||||
unitTest = false;
|
||||
allowFreeTx = true;
|
||||
protocolVersion = PROTOCOL_VERSION;
|
||||
@ -52,8 +53,9 @@ CMasternode::CMasternode(const CMasternode& other)
|
||||
activeState = other.activeState;
|
||||
sigTime = other.sigTime;
|
||||
lastPing = other.lastPing;
|
||||
cacheInputAge = other.cacheInputAge;
|
||||
cacheInputAgeBlock = other.cacheInputAgeBlock;
|
||||
nTimeLastPaid = other.nTimeLastPaid;
|
||||
nBlockLastPaid = other.nBlockLastPaid;
|
||||
nCacheCollateralBlock = other.nCacheCollateralBlock;
|
||||
unitTest = other.unitTest;
|
||||
allowFreeTx = other.allowFreeTx;
|
||||
protocolVersion = other.protocolVersion;
|
||||
@ -74,8 +76,9 @@ CMasternode::CMasternode(const CMasternodeBroadcast& mnb)
|
||||
activeState = MASTERNODE_ENABLED;
|
||||
sigTime = mnb.sigTime;
|
||||
lastPing = mnb.lastPing;
|
||||
cacheInputAge = 0;
|
||||
cacheInputAgeBlock = 0;
|
||||
nTimeLastPaid = 0;
|
||||
nBlockLastPaid = 0;
|
||||
nCacheCollateralBlock = 0;
|
||||
unitTest = false;
|
||||
allowFreeTx = true;
|
||||
protocolVersion = mnb.protocolVersion;
|
||||
@ -200,57 +203,54 @@ void CMasternode::Check(bool forceCheck)
|
||||
activeState = MASTERNODE_ENABLED; // OK
|
||||
}
|
||||
|
||||
int64_t CMasternode::SecondsSincePayment() {
|
||||
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;
|
||||
int CMasternode::GetCollateralAge()
|
||||
{
|
||||
LOCK(cs_main);
|
||||
pindexPrev = chainActive.Tip();
|
||||
if(!pindexPrev) return 0;
|
||||
int nHeight;
|
||||
{
|
||||
TRY_LOCK(cs_main, lockMain);
|
||||
if(!lockMain || !chainActive.Tip()) return -1;
|
||||
nHeight = chainActive.Height();
|
||||
}
|
||||
|
||||
|
||||
CScript mnpayee;
|
||||
mnpayee = GetScriptForDestination(pubkey.GetID());
|
||||
|
||||
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
|
||||
ss << vin;
|
||||
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;
|
||||
if (nCacheCollateralBlock == 0) {
|
||||
int nInputAge = GetInputAge(vin);
|
||||
if(nInputAge > 0) {
|
||||
nCacheCollateralBlock = nHeight - nInputAge;
|
||||
} else {
|
||||
return nInputAge;
|
||||
}
|
||||
}
|
||||
n++;
|
||||
|
||||
if(mnpayments.mapMasternodeBlocks.count(BlockReading->nHeight)){
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
if(mnpayments.mapMasternodeBlocks[BlockReading->nHeight].HasPayeeWithVotes(mnpayee, 2)){
|
||||
return BlockReading->nTime + nOffset;
|
||||
return nHeight - nCacheCollateralBlock;
|
||||
}
|
||||
|
||||
void CMasternode::UpdateLastPaid(const CBlockIndex *pindex, int nMaxBlocksToScanBack)
|
||||
{
|
||||
if(!pindex) return;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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()
|
||||
@ -271,8 +273,9 @@ CMasternodeBroadcast::CMasternodeBroadcast()
|
||||
activeState = MASTERNODE_ENABLED;
|
||||
sigTime = GetAdjustedTime();
|
||||
lastPing = CMasternodePing();
|
||||
cacheInputAge = 0;
|
||||
cacheInputAgeBlock = 0;
|
||||
nTimeLastPaid = 0;
|
||||
nBlockLastPaid = 0;
|
||||
nCacheCollateralBlock = 0;
|
||||
unitTest = false;
|
||||
allowFreeTx = true;
|
||||
protocolVersion = PROTOCOL_VERSION;
|
||||
@ -291,8 +294,9 @@ CMasternodeBroadcast::CMasternodeBroadcast(CService newAddr, CTxIn newVin, CPubK
|
||||
activeState = MASTERNODE_ENABLED;
|
||||
sigTime = GetAdjustedTime();
|
||||
lastPing = CMasternodePing();
|
||||
cacheInputAge = 0;
|
||||
cacheInputAgeBlock = 0;
|
||||
nTimeLastPaid = 0;
|
||||
nBlockLastPaid = 0;
|
||||
nCacheCollateralBlock = 0;
|
||||
unitTest = false;
|
||||
allowFreeTx = true;
|
||||
protocolVersion = protocolVersionIn;
|
||||
@ -311,8 +315,9 @@ CMasternodeBroadcast::CMasternodeBroadcast(const CMasternode& mn)
|
||||
activeState = mn.activeState;
|
||||
sigTime = mn.sigTime;
|
||||
lastPing = mn.lastPing;
|
||||
cacheInputAge = mn.cacheInputAge;
|
||||
cacheInputAgeBlock = mn.cacheInputAgeBlock;
|
||||
nTimeLastPaid = mn.nTimeLastPaid;
|
||||
nBlockLastPaid = mn.nBlockLastPaid;
|
||||
nCacheCollateralBlock = mn.nCacheCollateralBlock;
|
||||
unitTest = mn.unitTest;
|
||||
allowFreeTx = mn.allowFreeTx;
|
||||
protocolVersion = mn.protocolVersion;
|
||||
|
@ -122,8 +122,9 @@ public:
|
||||
std::vector<unsigned char> vchSig;
|
||||
int activeState;
|
||||
int64_t sigTime; //mnb message time
|
||||
int cacheInputAge;
|
||||
int cacheInputAgeBlock;
|
||||
int64_t nTimeLastPaid;
|
||||
int nBlockLastPaid;
|
||||
int nCacheCollateralBlock;
|
||||
bool unitTest;
|
||||
bool allowFreeTx;
|
||||
int protocolVersion;
|
||||
@ -155,8 +156,9 @@ public:
|
||||
swap(first.activeState, second.activeState);
|
||||
swap(first.sigTime, second.sigTime);
|
||||
swap(first.lastPing, second.lastPing);
|
||||
swap(first.cacheInputAge, second.cacheInputAge);
|
||||
swap(first.cacheInputAgeBlock, second.cacheInputAgeBlock);
|
||||
swap(first.nTimeLastPaid, second.nTimeLastPaid);
|
||||
swap(first.nBlockLastPaid, second.nBlockLastPaid);
|
||||
swap(first.nCacheCollateralBlock, second.nCacheCollateralBlock);
|
||||
swap(first.unitTest, second.unitTest);
|
||||
swap(first.allowFreeTx, second.allowFreeTx);
|
||||
swap(first.protocolVersion, second.protocolVersion);
|
||||
@ -204,8 +206,9 @@ public:
|
||||
READWRITE(protocolVersion);
|
||||
READWRITE(activeState);
|
||||
READWRITE(lastPing);
|
||||
READWRITE(cacheInputAge);
|
||||
READWRITE(cacheInputAgeBlock);
|
||||
READWRITE(nTimeLastPaid);
|
||||
READWRITE(nBlockLastPaid);
|
||||
READWRITE(nCacheCollateralBlock);
|
||||
READWRITE(unitTest);
|
||||
READWRITE(allowFreeTx);
|
||||
READWRITE(nLastDsq);
|
||||
@ -257,19 +260,6 @@ public:
|
||||
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 strStatus = "unknown";
|
||||
|
||||
@ -283,7 +273,11 @@ public:
|
||||
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 */
|
||||
CMasternodeMan mnodeman;
|
||||
|
||||
struct CompareLastPaid
|
||||
struct CompareLastPaidBlock
|
||||
{
|
||||
bool operator()(const pair<int64_t, CTxIn>& t1,
|
||||
const pair<int64_t, CTxIn>& t2) const
|
||||
bool operator()(const std::pair<int, CTxIn>& t1,
|
||||
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);
|
||||
|
||||
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
|
||||
@ -333,9 +333,9 @@ CMasternode* CMasternodeMan::GetNextMasternodeInQueueForPayment(int nBlockHeight
|
||||
if(fFilterSigTime && mn.sigTime + (nMnCount*2.6*60) > GetAdjustedTime()) continue;
|
||||
|
||||
//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();
|
||||
@ -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
|
||||
if(fFilterSigTime && nCount < nMnCount/3) return GetNextMasternodeInQueueForPayment(nBlockHeight, false, nCount);
|
||||
|
||||
// Sort them high to low
|
||||
sort(vecMasternodeLastPaid.rbegin(), vecMasternodeLastPaid.rend(), CompareLastPaid());
|
||||
// Sort them low to high
|
||||
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
|
||||
// -- 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 nCountTenth = 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);
|
||||
if(!pmn) break;
|
||||
|
||||
@ -769,3 +769,22 @@ bool CMasternodeMan::CheckMnbAndUpdateMasternodeList(CMasternodeBroadcast mnb, i
|
||||
|
||||
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
|
||||
{
|
||||
private:
|
||||
static const int MASTERNODES_LAST_PAID_SCAN_BLOCKS = 100;
|
||||
|
||||
// critical section to protect the inner data structures
|
||||
mutable CCriticalSection cs;
|
||||
|
||||
@ -134,6 +136,7 @@ public:
|
||||
/// Perform complete check and only then update list and maps
|
||||
bool CheckMnbAndUpdateMasternodeList(CMasternodeBroadcast mnb, int& nDos);
|
||||
|
||||
void UpdateLastPaid(const CBlockIndex *pindex);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -477,9 +477,10 @@ UniValue masternodelist(const UniValue& params, bool fHelp)
|
||||
if (params.size() >= 1) strMode = params[0].get_str();
|
||||
if (params.size() == 2) strFilter = params[1].get_str();
|
||||
|
||||
if (fHelp ||
|
||||
(strMode != "status" && strMode != "vin" && strMode != "pubkey" && strMode != "lastseen" && strMode != "activeseconds" && strMode != "rank" && strMode != "addr"
|
||||
&& strMode != "protocol" && strMode != "full" && strMode != "lastpaid"))
|
||||
if (fHelp || (
|
||||
strMode != "activeseconds" && strMode != "addr" && strMode != "full" &&
|
||||
strMode != "lastseen" && strMode != "lastpaidtime" && strMode != "lastpaidblock" &&
|
||||
strMode != "protocol" && strMode != "pubkey" && strMode != "rank" && strMode != "status"))
|
||||
{
|
||||
throw runtime_error(
|
||||
"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"
|
||||
" (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"
|
||||
" 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"
|
||||
" 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"
|
||||
" pubkey - Print public key associated with a masternode (can be additionally filtered,\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);
|
||||
if (strMode == "rank") {
|
||||
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() << " " <<
|
||||
(int64_t)mn.lastPing.sigTime << " " << setw(8) <<
|
||||
(int64_t)(mn.lastPing.sigTime - mn.sigTime) << " " <<
|
||||
(int64_t)mn.GetLastPaid();
|
||||
(int64_t)mn.GetLastPaidTime();
|
||||
std::string output = stringStream.str();
|
||||
stringStream << " " << strVin;
|
||||
if(strFilter !="" && stringStream.str().find(strFilter) == string::npos &&
|
||||
@ -545,10 +556,12 @@ UniValue masternodelist(const UniValue& params, bool fHelp)
|
||||
} else if (strMode == "lastseen") {
|
||||
if(strFilter !="" && strVin.find(strFilter) == string::npos) continue;
|
||||
obj.push_back(Pair(strVin, (int64_t)mn.lastPing.sigTime));
|
||||
} else if (strMode == "lastpaid"){
|
||||
if(strFilter !="" && mn.vin.prevout.hash.ToString().find(strFilter) == string::npos &&
|
||||
strVin.find(strFilter) == string::npos) continue;
|
||||
obj.push_back(Pair(strVin, (int64_t)mn.GetLastPaid()));
|
||||
} else if (strMode == "lastpaidblock") {
|
||||
if (strFilter !="" && strVin.find(strFilter) == std::string::npos) continue;
|
||||
obj.push_back(Pair(strVin, mn.GetLastPaidBlock()));
|
||||
} else if (strMode == "lastpaidtime") {
|
||||
if (strFilter !="" && strVin.find(strFilter) == std::string::npos) continue;
|
||||
obj.push_back(Pair(strVin, mn.GetLastPaidTime()));
|
||||
} else if (strMode == "protocol") {
|
||||
if(strFilter !="" && strFilter != strprintf("%d", mn.protocolVersion) &&
|
||||
strVin.find(strFilter) == string::npos) continue;
|
||||
|
Loading…
Reference in New Issue
Block a user