Implement new MN payments logic and add compatibility code

This commit is contained in:
Alexander Block 2018-02-15 19:14:28 +01:00
parent b99886532e
commit dc7292afa9
6 changed files with 129 additions and 29 deletions

View File

@ -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;
@ -267,6 +269,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 +299,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 +334,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 +524,29 @@ 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;
}
voutMasternodePaymentsRet.emplace_back(masternodeReward, dmnPayee->pdmnState->scriptPayout);
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?
@ -698,10 +723,22 @@ 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();
if (deterministicMNManager->IsDeterministicMNsSporkActive(nBlockHeight)) {
LOCK(cs_main);
auto pindex = chainActive[nBlockHeight - 1];
auto payee = deterministicMNManager->GetListForBlock(pindex->GetBlockHash()).GetMNPayee();
if (!payee) {
return "Unknown";
}
CTxDestination dest;
if (!ExtractDestination(payee->pdmnState->scriptPayout, dest))
assert(false);
return CBitcoinAddress(dest).ToString();
} else {
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
@ -713,6 +750,10 @@ bool CMasternodePayments::IsTransactionValid(const CTransaction& txNew, int nBlo
void CMasternodePayments::CheckAndRemove()
{
if (deterministicMNManager->IsDeterministicMNsSporkActive()) {
return;
}
if(!masternodeSync.IsBlockchainSynced()) return;
LOCK2(cs_mapMasternodeBlocks, cs_mapMasternodePaymentVotes);
@ -794,6 +835,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 +974,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 +1179,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);

View File

@ -18,6 +18,8 @@
#include "wallet/wallet.h"
#endif // ENABLE_WALLET
#include "evo/deterministicmns.h"
#include <string>
@ -347,6 +349,19 @@ void CMasternode::UpdateLastPaid(const CBlockIndex *pindex, int nMaxBlocksToScan
{
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 {
LOCK(cs_main);
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);

View File

@ -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;

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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);