mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 20:12:57 +01:00
Merge pull request #2258 from codablock/pr_dip3_paymentlogic
DIP3 MN reward payment logic
This commit is contained in:
commit
f0166389bd
@ -14,6 +14,8 @@
|
||||
#include "spork.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "evo/deterministicmns.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
/** Object for who's going to get paid on which blocks */
|
||||
@ -150,7 +152,7 @@ bool IsBlockValueValid(const CBlock& block, int nBlockHeight, CAmount blockRewar
|
||||
|
||||
bool IsBlockPayeeValid(const CTransaction& txNew, int nBlockHeight, CAmount blockReward)
|
||||
{
|
||||
if(!masternodeSync.IsSynced() || fLiteMode) {
|
||||
if((!masternodeSync.IsSynced() && !deterministicMNManager->IsDeterministicMNsSporkActive(nBlockHeight)) || fLiteMode) {
|
||||
//there is no budget data to use to check anything, let's just accept the longest chain
|
||||
if(fDebug) LogPrintf("%s -- WARNING: Not enough data, skipping block payee checks\n", __func__);
|
||||
return true;
|
||||
@ -176,7 +178,10 @@ bool IsBlockPayeeValid(const CTransaction& txNew, int nBlockHeight, CAmount bloc
|
||||
if(CSuperblockManager::IsSuperblockTriggered(nBlockHeight)) {
|
||||
if(CSuperblockManager::IsValid(txNew, nBlockHeight, blockReward)) {
|
||||
LogPrint("gobject", "%s -- Valid superblock at height %d: %s", __func__, nBlockHeight, txNew.ToString());
|
||||
return true;
|
||||
// only allow superblock and masternode payments in the same block after spork15 activation
|
||||
if (!deterministicMNManager->IsDeterministicMNsSporkActive(nBlockHeight))
|
||||
return true;
|
||||
// continue validation, should also pay MN
|
||||
} else {
|
||||
LogPrintf("%s -- ERROR: Invalid superblock detected at height %d: %s", __func__, nBlockHeight, txNew.ToString());
|
||||
// should NOT allow such superblocks, when superblocks are enabled
|
||||
@ -196,13 +201,18 @@ bool IsBlockPayeeValid(const CTransaction& txNew, int nBlockHeight, CAmount bloc
|
||||
return true;
|
||||
}
|
||||
|
||||
if(sporkManager.IsSporkActive(SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT)) {
|
||||
LogPrintf("%s -- ERROR: Invalid masternode payment detected at height %d: %s", __func__, nBlockHeight, txNew.ToString());
|
||||
if (deterministicMNManager->IsDeterministicMNsSporkActive(nBlockHeight)) {
|
||||
// always enforce masternode payments when spork15 is active
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if(sporkManager.IsSporkActive(SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT)) {
|
||||
LogPrintf("%s -- ERROR: Invalid masternode payment detected at height %d: %s", __func__, nBlockHeight, txNew.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
LogPrintf("%s -- WARNING: Masternode payment enforcement is disabled, accepting any payee\n", __func__);
|
||||
return true;
|
||||
LogPrintf("%s-- WARNING: Masternode payment enforcement is disabled, accepting any payee\n", __func__);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void FillBlockPayments(CMutableTransaction& txNew, int nBlockHeight, CAmount blockReward, std::vector<CTxOut>& voutMasternodePaymentsRet, std::vector<CTxOut>& voutSuperblockPaymentsRet)
|
||||
@ -215,10 +225,7 @@ void FillBlockPayments(CMutableTransaction& txNew, int nBlockHeight, CAmount blo
|
||||
CSuperblockManager::GetSuperblockPayments(nBlockHeight, voutSuperblockPaymentsRet);
|
||||
}
|
||||
|
||||
// TODO this is a placeholder until DIP3 is merged, which will allow superblock payments and MN reward payments
|
||||
// in the same block. We set this to false for now, which means that we'll always get into the next if statement
|
||||
// when a superblock payment is present
|
||||
bool allowSuperblockAndMNReward = false;
|
||||
bool allowSuperblockAndMNReward = deterministicMNManager->IsDeterministicMNsSporkActive(nBlockHeight);
|
||||
|
||||
// don't allow payments to superblocks AND masternodes before spork15 activation
|
||||
if (!voutSuperblockPaymentsRet.empty() && !allowSuperblockAndMNReward) {
|
||||
@ -247,7 +254,7 @@ void FillBlockPayments(CMutableTransaction& txNew, int nBlockHeight, CAmount blo
|
||||
nBlockHeight, blockReward, voutMasternodeStr, txNew.ToString());
|
||||
}
|
||||
|
||||
std::string GetRequiredPaymentsString(int nBlockHeight)
|
||||
std::string GetLegacyRequiredPaymentsString(int nBlockHeight)
|
||||
{
|
||||
// IF WE HAVE A ACTIVATED TRIGGER FOR THIS HEIGHT - IT IS A SUPERBLOCK, GET THE REQUIRED PAYEES
|
||||
if(CSuperblockManager::IsSuperblockTriggered(nBlockHeight)) {
|
||||
@ -258,6 +265,54 @@ std::string GetRequiredPaymentsString(int nBlockHeight)
|
||||
return mnpayments.GetRequiredPaymentsString(nBlockHeight);
|
||||
}
|
||||
|
||||
std::string GetRequiredPaymentsString(int nBlockHeight, const CDeterministicMNCPtr &payee)
|
||||
{
|
||||
std::string strPayee = "Unknown";
|
||||
if (payee) {
|
||||
CTxDestination dest;
|
||||
if (!ExtractDestination(payee->pdmnState->scriptPayout, dest))
|
||||
assert(false);
|
||||
strPayee = CBitcoinAddress(dest).ToString();
|
||||
}
|
||||
if (CSuperblockManager::IsSuperblockTriggered(nBlockHeight)) {
|
||||
strPayee += ", " + CSuperblockManager::GetRequiredPaymentsString(nBlockHeight);
|
||||
}
|
||||
return strPayee;
|
||||
}
|
||||
|
||||
std::map<int, std::string> GetRequiredPaymentsStrings(int nStartHeight, int nEndHeight)
|
||||
{
|
||||
std::map<int, std::string> mapPayments;
|
||||
|
||||
LOCK(cs_main);
|
||||
int nChainTipHeight = chainActive.Height();
|
||||
|
||||
bool doProjection = false;
|
||||
for(int h = nStartHeight; h < nEndHeight; h++) {
|
||||
if (deterministicMNManager->IsDeterministicMNsSporkActive(h)) {
|
||||
if (h <= nChainTipHeight) {
|
||||
auto payee = deterministicMNManager->GetListForBlock(chainActive[h - 1]->GetBlockHash()).GetMNPayee();
|
||||
mapPayments.emplace(h, GetRequiredPaymentsString(h, payee));
|
||||
} else {
|
||||
doProjection = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
mapPayments.emplace(h, GetLegacyRequiredPaymentsString(h));
|
||||
}
|
||||
}
|
||||
if (doProjection) {
|
||||
auto projection = deterministicMNManager->GetListAtChainTip().GetProjectedMNPayees(nEndHeight - nChainTipHeight);
|
||||
for (size_t i = 0; i < projection.size(); i++) {
|
||||
auto payee = projection[i];
|
||||
int h = nChainTipHeight + 1 + i;
|
||||
mapPayments.emplace(h, GetRequiredPaymentsString(h, payee));
|
||||
}
|
||||
}
|
||||
|
||||
return mapPayments;
|
||||
}
|
||||
|
||||
void CMasternodePayments::Clear()
|
||||
{
|
||||
LOCK2(cs_mapMasternodeBlocks, cs_mapMasternodePaymentVotes);
|
||||
@ -267,6 +322,9 @@ void CMasternodePayments::Clear()
|
||||
|
||||
bool CMasternodePayments::UpdateLastVote(const CMasternodePaymentVote& vote)
|
||||
{
|
||||
if (deterministicMNManager->IsDeterministicMNsSporkActive())
|
||||
return false;
|
||||
|
||||
LOCK(cs_mapMasternodePaymentVotes);
|
||||
|
||||
const auto it = mapMasternodesLastVote.find(vote.masternodeOutpoint);
|
||||
@ -294,6 +352,8 @@ bool CMasternodePayments::GetMasternodeTxOuts(int nBlockHeight, CAmount blockRew
|
||||
voutMasternodePaymentsRet.clear();
|
||||
|
||||
if(!GetBlockTxOuts(nBlockHeight, blockReward, voutMasternodePaymentsRet)) {
|
||||
assert(!deterministicMNManager->IsDeterministicMNsSporkActive(nBlockHeight));
|
||||
|
||||
// no masternode detected...
|
||||
int nCount = 0;
|
||||
masternode_info_t mnInfo;
|
||||
@ -327,6 +387,9 @@ int CMasternodePayments::GetMinMasternodePaymentsProto() const {
|
||||
|
||||
void CMasternodePayments::ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman)
|
||||
{
|
||||
if (deterministicMNManager->IsDeterministicMNsSporkActive())
|
||||
return;
|
||||
|
||||
if(fLiteMode) return; // disable all Dash specific functionality
|
||||
|
||||
if (strCommand == NetMsgType::MASTERNODEPAYMENTSYNC) { //Masternode Payments Request Sync
|
||||
@ -514,14 +577,37 @@ bool CMasternodePayments::GetBlockTxOuts(int nBlockHeight, CAmount blockReward,
|
||||
|
||||
CAmount masternodeReward = GetMasternodePayment(nBlockHeight, blockReward);
|
||||
|
||||
LOCK(cs_mapMasternodeBlocks);
|
||||
auto it = mapMasternodeBlocks.find(nBlockHeight);
|
||||
CScript payee;
|
||||
if (it == mapMasternodeBlocks.end() || !it->second.GetBestPayee(payee)) {
|
||||
return false;
|
||||
if (deterministicMNManager->IsDeterministicMNsSporkActive(nBlockHeight)) {
|
||||
uint256 blockHash;
|
||||
{
|
||||
LOCK(cs_main);
|
||||
blockHash = chainActive[nBlockHeight - 1]->GetBlockHash();
|
||||
}
|
||||
uint256 proTxHash;
|
||||
auto dmnPayee = deterministicMNManager->GetListForBlock(blockHash).GetMNPayee();
|
||||
if (!dmnPayee) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dmnPayee->nOperatorReward == 0 || dmnPayee->pdmnState->scriptOperatorPayout == CScript()) {
|
||||
voutMasternodePaymentsRet.emplace_back(masternodeReward, dmnPayee->pdmnState->scriptPayout);
|
||||
} else {
|
||||
CAmount operatorReward = (masternodeReward * dmnPayee->nOperatorReward) / 10000;
|
||||
masternodeReward -= operatorReward;
|
||||
voutMasternodePaymentsRet.emplace_back(masternodeReward, dmnPayee->pdmnState->scriptPayout);
|
||||
voutMasternodePaymentsRet.emplace_back(operatorReward, dmnPayee->pdmnState->scriptOperatorPayout);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
LOCK(cs_mapMasternodeBlocks);
|
||||
auto it = mapMasternodeBlocks.find(nBlockHeight);
|
||||
CScript payee;
|
||||
if (it == mapMasternodeBlocks.end() || !it->second.GetBestPayee(payee)) {
|
||||
return false;
|
||||
}
|
||||
voutMasternodePaymentsRet.emplace_back(masternodeReward, payee);
|
||||
return true;
|
||||
}
|
||||
voutMasternodePaymentsRet.emplace_back(masternodeReward, payee);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Is this masternode scheduled to get paid soon?
|
||||
@ -530,6 +616,16 @@ bool CMasternodePayments::IsScheduled(const masternode_info_t& mnInfo, int nNotB
|
||||
{
|
||||
LOCK(cs_mapMasternodeBlocks);
|
||||
|
||||
if (deterministicMNManager->IsDeterministicMNsSporkActive()) {
|
||||
auto projectedPayees = deterministicMNManager->GetListAtChainTip().GetProjectedMNPayees(8);
|
||||
for (const auto &dmn : projectedPayees) {
|
||||
if (dmn->proTxHash == mnInfo.outpoint.hash) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!masternodeSync.IsMasternodeListSynced()) return false;
|
||||
|
||||
CScript mnpayee;
|
||||
@ -699,20 +795,49 @@ std::string CMasternodeBlockPayees::GetRequiredPaymentsString() const
|
||||
std::string CMasternodePayments::GetRequiredPaymentsString(int nBlockHeight) const
|
||||
{
|
||||
LOCK(cs_mapMasternodeBlocks);
|
||||
|
||||
const auto it = mapMasternodeBlocks.find(nBlockHeight);
|
||||
return it == mapMasternodeBlocks.end() ? "Unknown" : it->second.GetRequiredPaymentsString();
|
||||
}
|
||||
|
||||
bool CMasternodePayments::IsTransactionValid(const CTransaction& txNew, int nBlockHeight, CAmount blockReward) const
|
||||
{
|
||||
LOCK(cs_mapMasternodeBlocks);
|
||||
const auto it = mapMasternodeBlocks.find(nBlockHeight);
|
||||
return it == mapMasternodeBlocks.end() ? true : it->second.IsTransactionValid(txNew);
|
||||
if (deterministicMNManager->IsDeterministicMNsSporkActive(nBlockHeight)) {
|
||||
std::vector<CTxOut> voutMasternodePayments;
|
||||
if (!GetBlockTxOuts(nBlockHeight, blockReward, voutMasternodePayments)) {
|
||||
LogPrintf("CMasternodePayments::%s -- ERROR failed to get payees for block at height %s\n", __func__, nBlockHeight);
|
||||
return true;
|
||||
}
|
||||
|
||||
for (const auto& txout : voutMasternodePayments) {
|
||||
bool found = false;
|
||||
for (const auto& txout2 : txNew.vout) {
|
||||
if (txout == txout2) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
CTxDestination dest;
|
||||
if (!ExtractDestination(txout.scriptPubKey, dest))
|
||||
assert(false);
|
||||
LogPrintf("CMasternodePayments::%s -- ERROR failed to find expected payee %s in block at height %s\n", __func__, CBitcoinAddress(dest).ToString(), nBlockHeight);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
LOCK(cs_mapMasternodeBlocks);
|
||||
const auto it = mapMasternodeBlocks.find(nBlockHeight);
|
||||
return it == mapMasternodeBlocks.end() ? true : it->second.IsTransactionValid(txNew);
|
||||
}
|
||||
}
|
||||
|
||||
void CMasternodePayments::CheckAndRemove()
|
||||
{
|
||||
if (deterministicMNManager->IsDeterministicMNsSporkActive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!masternodeSync.IsBlockchainSynced()) return;
|
||||
|
||||
LOCK2(cs_mapMasternodeBlocks, cs_mapMasternodePaymentVotes);
|
||||
@ -794,6 +919,10 @@ bool CMasternodePaymentVote::IsValid(CNode* pnode, int nValidationHeight, std::s
|
||||
|
||||
bool CMasternodePayments::ProcessBlock(int nBlockHeight, CConnman& connman)
|
||||
{
|
||||
if (deterministicMNManager->IsDeterministicMNsSporkActive(nBlockHeight)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// DETERMINE IF WE SHOULD BE VOTING FOR THE NEXT PAYEE
|
||||
|
||||
if(fLiteMode || !fMasternodeMode) return false;
|
||||
@ -929,6 +1058,10 @@ void CMasternodePayments::CheckBlockVotes(int nBlockHeight)
|
||||
|
||||
void CMasternodePaymentVote::Relay(CConnman& connman) const
|
||||
{
|
||||
if (deterministicMNManager->IsDeterministicMNsSporkActive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Do not relay until fully synced
|
||||
if(!masternodeSync.IsSynced()) {
|
||||
LogPrint("mnpayments", "CMasternodePayments::%s -- won't relay until fully synced\n", __func__);
|
||||
@ -1130,6 +1263,10 @@ void CMasternodePayments::UpdatedBlockTip(const CBlockIndex *pindex, CConnman& c
|
||||
{
|
||||
if(!pindex) return;
|
||||
|
||||
if (deterministicMNManager->IsDeterministicMNsSporkActive(pindex->nHeight)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nCachedBlockHeight = pindex->nHeight;
|
||||
LogPrint("mnpayments", "CMasternodePayments::%s -- nCachedBlockHeight=%d\n", __func__, nCachedBlockHeight);
|
||||
|
||||
|
@ -36,7 +36,7 @@ extern CMasternodePayments mnpayments;
|
||||
bool IsBlockValueValid(const CBlock& block, int nBlockHeight, CAmount blockReward, std::string& strErrorRet);
|
||||
bool IsBlockPayeeValid(const CTransaction& txNew, int nBlockHeight, CAmount blockReward);
|
||||
void FillBlockPayments(CMutableTransaction& txNew, int nBlockHeight, CAmount blockReward, std::vector<CTxOut>& voutMasternodePaymentsRet, std::vector<CTxOut>& voutSuperblockPaymentsRet);
|
||||
std::string GetRequiredPaymentsString(int nBlockHeight);
|
||||
std::map<int, std::string> GetRequiredPaymentsStrings(int nStartHeight, int nEndHeight);
|
||||
|
||||
class CMasternodePayee
|
||||
{
|
||||
|
@ -18,6 +18,8 @@
|
||||
#include "wallet/wallet.h"
|
||||
#endif // ENABLE_WALLET
|
||||
|
||||
#include "evo/deterministicmns.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
@ -345,8 +347,22 @@ std::string CMasternode::GetStatus() const
|
||||
|
||||
void CMasternode::UpdateLastPaid(const CBlockIndex *pindex, int nMaxBlocksToScanBack)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
|
||||
if(!pindex) return;
|
||||
|
||||
if (deterministicMNManager->IsDeterministicMNsSporkActive(pindex->nHeight)) {
|
||||
auto dmn = deterministicMNManager->GetListForBlock(pindex->GetBlockHash()).GetMN(outpoint.hash);
|
||||
if (!dmn || dmn->pdmnState->nLastPaidHeight == -1) {
|
||||
LogPrint("masternode", "CMasternode::UpdateLastPaidBlock -- searching for block with payment to %s -- not found\n", outpoint.ToStringShort());
|
||||
} else {
|
||||
nBlockLastPaid = (int)dmn->pdmnState->nLastPaidHeight;
|
||||
nTimeLastPaid = chainActive[nBlockLastPaid]->nTime;
|
||||
LogPrint("masternode", "CMasternode::UpdateLastPaidBlock -- searching for block with payment to %s -- found new %d\n", outpoint.ToStringShort(), nBlockLastPaid);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const CBlockIndex *BlockReading = pindex;
|
||||
|
||||
CScript mnpayee = GetScriptForDestination(keyIDCollateralAddress);
|
||||
|
@ -583,6 +583,14 @@ bool CMasternodeMan::Get(const COutPoint& outpoint, CMasternode& masternodeRet)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMasternodeMan::GetMasternodeInfo(const uint256& proTxHash, masternode_info_t& mnInfoRet)
|
||||
{
|
||||
auto dmn = deterministicMNManager->GetListAtChainTip().GetValidMN(proTxHash);
|
||||
if (!dmn)
|
||||
return false;
|
||||
return GetMasternodeInfo(COutPoint(proTxHash, dmn->nCollateralIndex), mnInfoRet);
|
||||
}
|
||||
|
||||
bool CMasternodeMan::GetMasternodeInfo(const COutPoint& outpoint, masternode_info_t& mnInfoRet)
|
||||
{
|
||||
LOCK(cs);
|
||||
@ -654,6 +662,10 @@ bool CMasternodeMan::GetNextMasternodeInQueueForPayment(bool fFilterSigTime, int
|
||||
|
||||
bool CMasternodeMan::GetNextMasternodeInQueueForPayment(int nBlockHeight, bool fFilterSigTime, int& nCountRet, masternode_info_t& mnInfoRet)
|
||||
{
|
||||
if (deterministicMNManager->IsDeterministicMNsSporkActive(nBlockHeight)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mnInfoRet = masternode_info_t();
|
||||
nCountRet = 0;
|
||||
|
||||
@ -1805,7 +1817,7 @@ bool CMasternodeMan::CheckMnbAndUpdateMasternodeList(CNode* pfrom, CMasternodeBr
|
||||
|
||||
void CMasternodeMan::UpdateLastPaid(const CBlockIndex* pindex)
|
||||
{
|
||||
LOCK(cs);
|
||||
LOCK2(cs_main, cs);
|
||||
|
||||
if(fLiteMode || !masternodeSync.IsWinnersListSynced() || mapMasternodes.empty()) return;
|
||||
|
||||
|
@ -171,6 +171,7 @@ public:
|
||||
bool Get(const COutPoint& outpoint, CMasternode& masternodeRet);
|
||||
bool Has(const COutPoint& outpoint);
|
||||
|
||||
bool GetMasternodeInfo(const uint256& proTxHash, masternode_info_t& mnInfoRet);
|
||||
bool GetMasternodeInfo(const COutPoint& outpoint, masternode_info_t& mnInfoRet);
|
||||
bool GetMasternodeInfo(const CKeyID& keyIDOperator, masternode_info_t& mnInfoRet);
|
||||
bool GetMasternodeInfo(const CPubKey& pubKeyOperator, masternode_info_t& mnInfoRet);
|
||||
|
@ -42,6 +42,7 @@
|
||||
#endif // ENABLE_WALLET
|
||||
#include "privatesend-server.h"
|
||||
|
||||
#include "evo/deterministicmns.h"
|
||||
#include "evo/simplifiedmns.h"
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
@ -1178,25 +1179,29 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
|
||||
}
|
||||
|
||||
if (!push && inv.type == MSG_MASTERNODE_PAYMENT_VOTE) {
|
||||
if(mnpayments.HasVerifiedPaymentVote(inv.hash)) {
|
||||
connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::MASTERNODEPAYMENTVOTE, mnpayments.mapMasternodePaymentVotes[inv.hash]));
|
||||
push = true;
|
||||
if (!deterministicMNManager->IsDeterministicMNsSporkActive()) {
|
||||
if (mnpayments.HasVerifiedPaymentVote(inv.hash)) {
|
||||
connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::MASTERNODEPAYMENTVOTE, mnpayments.mapMasternodePaymentVotes[inv.hash]));
|
||||
push = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!push && inv.type == MSG_MASTERNODE_PAYMENT_BLOCK) {
|
||||
BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
|
||||
LOCK(cs_mapMasternodeBlocks);
|
||||
if (mi != mapBlockIndex.end() && mnpayments.mapMasternodeBlocks.count(mi->second->nHeight)) {
|
||||
BOOST_FOREACH(CMasternodePayee& payee, mnpayments.mapMasternodeBlocks[mi->second->nHeight].vecPayees) {
|
||||
std::vector<uint256> vecVoteHashes = payee.GetVoteHashes();
|
||||
BOOST_FOREACH(uint256& hash, vecVoteHashes) {
|
||||
if(mnpayments.HasVerifiedPaymentVote(hash)) {
|
||||
connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::MASTERNODEPAYMENTVOTE, mnpayments.mapMasternodePaymentVotes[hash]));
|
||||
if (!deterministicMNManager->IsDeterministicMNsSporkActive()) {
|
||||
BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
|
||||
LOCK(cs_mapMasternodeBlocks);
|
||||
if (mi != mapBlockIndex.end() && mnpayments.mapMasternodeBlocks.count(mi->second->nHeight)) {
|
||||
BOOST_FOREACH(CMasternodePayee& payee, mnpayments.mapMasternodeBlocks[mi->second->nHeight].vecPayees) {
|
||||
std::vector<uint256> vecVoteHashes = payee.GetVoteHashes();
|
||||
BOOST_FOREACH(uint256& hash, vecVoteHashes) {
|
||||
if(mnpayments.HasVerifiedPaymentVote(hash)) {
|
||||
connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::MASTERNODEPAYMENTVOTE, mnpayments.mapMasternodePaymentVotes[hash]));
|
||||
}
|
||||
}
|
||||
}
|
||||
push = true;
|
||||
}
|
||||
push = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,8 @@
|
||||
#include "evo/specialtx.h"
|
||||
#include "evo/deterministicmns.h"
|
||||
|
||||
#include "evo/deterministicmns.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <univalue.h>
|
||||
@ -223,10 +225,15 @@ UniValue masternode_count(const JSONRPCRequest& request)
|
||||
masternode_count_help();
|
||||
|
||||
int nCount;
|
||||
masternode_info_t mnInfo;
|
||||
mnodeman.GetNextMasternodeInQueueForPayment(true, nCount, mnInfo);
|
||||
int total;
|
||||
if (deterministicMNManager->IsDeterministicMNsSporkActive()) {
|
||||
nCount = total = mnodeman.CountEnabled();
|
||||
} else {
|
||||
masternode_info_t mnInfo;
|
||||
mnodeman.GetNextMasternodeInQueueForPayment(true, nCount, mnInfo);
|
||||
total = mnodeman.size();
|
||||
}
|
||||
|
||||
int total = mnodeman.size();
|
||||
int ps = mnodeman.CountEnabled(MIN_PRIVATESEND_PEER_PROTO_VERSION);
|
||||
int enabled = mnodeman.CountEnabled();
|
||||
|
||||
@ -272,11 +279,18 @@ UniValue GetNextMasternodeForPayment(int heightShift)
|
||||
LOCK(cs_main);
|
||||
pindex = chainActive.Tip();
|
||||
}
|
||||
|
||||
nHeight = pindex->nHeight + heightShift;
|
||||
mnodeman.UpdateLastPaid(pindex);
|
||||
|
||||
if (!mnodeman.GetNextMasternodeInQueueForPayment(nHeight, true, nCount, mnInfo))
|
||||
return "unknown";
|
||||
if (deterministicMNManager->IsDeterministicMNsSporkActive()) {
|
||||
auto payee = deterministicMNManager->GetListAtChainTip().GetMNPayee();
|
||||
if (!payee || !mnodeman.GetMasternodeInfo(payee->proTxHash, mnInfo))
|
||||
return "unknown";
|
||||
} else {
|
||||
if (!mnodeman.GetNextMasternodeInQueueForPayment(nHeight, true, nCount, mnInfo))
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
|
||||
@ -787,11 +801,9 @@ UniValue masternode_winners(const JSONRPCRequest& request)
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Correct usage is 'masternode winners ( \"count\" \"filter\" )'");
|
||||
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
|
||||
for (int i = nHeight - nLast; i < nHeight + 20; i++) {
|
||||
std::string strPayment = GetRequiredPaymentsString(i);
|
||||
if (strFilter !="" && strPayment.find(strFilter) == std::string::npos) continue;
|
||||
obj.push_back(Pair(strprintf("%d", i), strPayment));
|
||||
auto mapPayments = GetRequiredPaymentsStrings(nHeight - nLast, nHeight + 20);
|
||||
for (const auto &p : mapPayments) {
|
||||
obj.push_back(Pair(strprintf("%d", p.first), p.second));
|
||||
}
|
||||
|
||||
return obj;
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "masternode-payments.h"
|
||||
#include "masternode-sync.h"
|
||||
|
||||
#include "evo/deterministicmns.h"
|
||||
#include "evo/specialtx.h"
|
||||
#include "evo/cbtx.h"
|
||||
|
||||
@ -720,7 +721,7 @@ UniValue getblocktemplate(const JSONRPCRequest& request)
|
||||
|
||||
result.push_back(Pair("masternode", masternodeObj));
|
||||
result.push_back(Pair("masternode_payments_started", pindexPrev->nHeight + 1 > consensusParams.nMasternodePaymentsStartBlock));
|
||||
result.push_back(Pair("masternode_payments_enforced", sporkManager.IsSporkActive(SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT)));
|
||||
result.push_back(Pair("masternode_payments_enforced", deterministicMNManager->IsDeterministicMNsSporkActive() || sporkManager.IsSporkActive(SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT)));
|
||||
|
||||
UniValue superblockObjArray(UniValue::VARR);
|
||||
if(pblocktemplate->voutSuperblockPayments.size()) {
|
||||
|
Loading…
Reference in New Issue
Block a user