r1
This commit is contained in:
@@ -0,0 +1,301 @@
|
||||
// Copyright (c) 2014-2015 The Dash developers
|
||||
// Copyright (c) 2015-2019 The PIVX developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef MASTERNODE_PAYMENTS_H
|
||||
#define MASTERNODE_PAYMENTS_H
|
||||
|
||||
#include "key.h"
|
||||
#include "main.h"
|
||||
#include "masternode.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern CCriticalSection cs_vecPayments;
|
||||
extern CCriticalSection cs_mapMasternodeBlocks;
|
||||
extern CCriticalSection cs_mapMasternodePayeeVotes;
|
||||
|
||||
class CMasternodePayments;
|
||||
class CMasternodePaymentWinner;
|
||||
class CMasternodeBlockPayees;
|
||||
|
||||
extern CMasternodePayments masternodePayments;
|
||||
|
||||
#define MNPAYMENTS_SIGNATURES_REQUIRED 6
|
||||
#define MNPAYMENTS_SIGNATURES_TOTAL 10
|
||||
|
||||
void ProcessMessageMasternodePayments(CNode* pfrom, std::string& strCommand, CDataStream& vRecv);
|
||||
bool IsBlockPayeeValid(const CBlock& block, int nBlockHeight);
|
||||
std::string GetRequiredPaymentsString(int nBlockHeight);
|
||||
bool IsBlockValueValid(const CBlock& block, CAmount nExpectedValue, CAmount nMinted);
|
||||
void FillBlockPayee(CMutableTransaction& txNew, CAmount nFees, bool fProofOfStake, bool fZAGRStake);
|
||||
|
||||
void DumpMasternodePayments();
|
||||
|
||||
/** Save Masternode Payment Data (mnpayments.dat)
|
||||
*/
|
||||
class CMasternodePaymentDB
|
||||
{
|
||||
private:
|
||||
boost::filesystem::path pathDB;
|
||||
std::string strMagicMessage;
|
||||
|
||||
public:
|
||||
enum ReadResult {
|
||||
Ok,
|
||||
FileError,
|
||||
HashReadError,
|
||||
IncorrectHash,
|
||||
IncorrectMagicMessage,
|
||||
IncorrectMagicNumber,
|
||||
IncorrectFormat
|
||||
};
|
||||
|
||||
CMasternodePaymentDB();
|
||||
bool Write(const CMasternodePayments& objToSave);
|
||||
ReadResult Read(CMasternodePayments& objToLoad, bool fDryRun = false);
|
||||
};
|
||||
|
||||
class CMasternodePayee
|
||||
{
|
||||
public:
|
||||
CScript scriptPubKey;
|
||||
int nVotes;
|
||||
|
||||
CMasternodePayee()
|
||||
{
|
||||
scriptPubKey = CScript();
|
||||
nVotes = 0;
|
||||
}
|
||||
|
||||
CMasternodePayee(CScript payee, int nVotesIn)
|
||||
{
|
||||
scriptPubKey = payee;
|
||||
nVotes = nVotesIn;
|
||||
}
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
|
||||
{
|
||||
READWRITE(scriptPubKey);
|
||||
READWRITE(nVotes);
|
||||
}
|
||||
};
|
||||
|
||||
// Keep track of votes for payees from masternodes
|
||||
class CMasternodeBlockPayees
|
||||
{
|
||||
public:
|
||||
int nBlockHeight;
|
||||
std::vector<CMasternodePayee> vecPayments;
|
||||
|
||||
CMasternodeBlockPayees()
|
||||
{
|
||||
nBlockHeight = 0;
|
||||
vecPayments.clear();
|
||||
}
|
||||
CMasternodeBlockPayees(int nBlockHeightIn)
|
||||
{
|
||||
nBlockHeight = nBlockHeightIn;
|
||||
vecPayments.clear();
|
||||
}
|
||||
|
||||
void AddPayee(CScript payeeIn, int nIncrement)
|
||||
{
|
||||
LOCK(cs_vecPayments);
|
||||
|
||||
for (CMasternodePayee& payee : vecPayments) {
|
||||
if (payee.scriptPubKey == payeeIn) {
|
||||
payee.nVotes += nIncrement;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CMasternodePayee c(payeeIn, nIncrement);
|
||||
vecPayments.push_back(c);
|
||||
}
|
||||
|
||||
bool GetPayee(CScript& payee)
|
||||
{
|
||||
LOCK(cs_vecPayments);
|
||||
|
||||
int nVotes = -1;
|
||||
for (CMasternodePayee& p : vecPayments) {
|
||||
if (p.nVotes > nVotes) {
|
||||
payee = p.scriptPubKey;
|
||||
nVotes = p.nVotes;
|
||||
}
|
||||
}
|
||||
|
||||
return (nVotes > -1);
|
||||
}
|
||||
|
||||
bool HasPayeeWithVotes(CScript payee, int nVotesReq)
|
||||
{
|
||||
LOCK(cs_vecPayments);
|
||||
|
||||
for (CMasternodePayee& p : vecPayments) {
|
||||
if (p.nVotes >= nVotesReq && p.scriptPubKey == payee) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsTransactionValid(const CTransaction& txNew);
|
||||
std::string GetRequiredPaymentsString();
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
|
||||
{
|
||||
READWRITE(nBlockHeight);
|
||||
READWRITE(vecPayments);
|
||||
}
|
||||
};
|
||||
|
||||
// for storing the winning payments
|
||||
class CMasternodePaymentWinner
|
||||
{
|
||||
public:
|
||||
CTxIn vinMasternode;
|
||||
|
||||
int nBlockHeight;
|
||||
CScript payee;
|
||||
std::vector<unsigned char> vchSig;
|
||||
|
||||
CMasternodePaymentWinner()
|
||||
{
|
||||
nBlockHeight = 0;
|
||||
vinMasternode = CTxIn();
|
||||
payee = CScript();
|
||||
}
|
||||
|
||||
CMasternodePaymentWinner(CTxIn vinIn)
|
||||
{
|
||||
nBlockHeight = 0;
|
||||
vinMasternode = vinIn;
|
||||
payee = CScript();
|
||||
}
|
||||
|
||||
uint256 GetHash()
|
||||
{
|
||||
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
|
||||
ss << payee;
|
||||
ss << nBlockHeight;
|
||||
ss << vinMasternode.prevout;
|
||||
|
||||
return ss.GetHash();
|
||||
}
|
||||
|
||||
bool Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode);
|
||||
bool IsValid(CNode* pnode, std::string& strError);
|
||||
bool SignatureValid();
|
||||
void Relay();
|
||||
|
||||
void AddPayee(CScript payeeIn)
|
||||
{
|
||||
payee = payeeIn;
|
||||
}
|
||||
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
|
||||
{
|
||||
READWRITE(vinMasternode);
|
||||
READWRITE(nBlockHeight);
|
||||
READWRITE(payee);
|
||||
READWRITE(vchSig);
|
||||
}
|
||||
|
||||
std::string ToString()
|
||||
{
|
||||
std::string ret = "";
|
||||
ret += vinMasternode.ToString();
|
||||
ret += ", " + std::to_string(nBlockHeight);
|
||||
ret += ", " + payee.ToString();
|
||||
ret += ", " + std::to_string((int)vchSig.size());
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Masternode Payments Class
|
||||
// Keeps track of who should get paid for which blocks
|
||||
//
|
||||
|
||||
class CMasternodePayments
|
||||
{
|
||||
private:
|
||||
int nSyncedFromPeer;
|
||||
int nLastBlockHeight;
|
||||
|
||||
public:
|
||||
std::map<uint256, CMasternodePaymentWinner> mapMasternodePayeeVotes;
|
||||
std::map<int, CMasternodeBlockPayees> mapMasternodeBlocks;
|
||||
std::map<uint256, int> mapMasternodesLastVote; //prevout.hash + prevout.n, nBlockHeight
|
||||
|
||||
CMasternodePayments()
|
||||
{
|
||||
nSyncedFromPeer = 0;
|
||||
nLastBlockHeight = 0;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
LOCK2(cs_mapMasternodeBlocks, cs_mapMasternodePayeeVotes);
|
||||
mapMasternodeBlocks.clear();
|
||||
mapMasternodePayeeVotes.clear();
|
||||
}
|
||||
|
||||
bool AddWinningMasternode(CMasternodePaymentWinner& winner);
|
||||
bool ProcessBlock(int nBlockHeight);
|
||||
|
||||
void Sync(CNode* node, int nCountNeeded);
|
||||
void CleanPaymentList();
|
||||
int LastPayment(CMasternode& mn);
|
||||
|
||||
bool GetBlockPayee(int nBlockHeight, CScript& payee);
|
||||
bool IsTransactionValid(const CTransaction& txNew, int nBlockHeight);
|
||||
bool IsScheduled(CMasternode& mn, int nNotBlockHeight);
|
||||
|
||||
bool CanVote(COutPoint outMasternode, int nBlockHeight)
|
||||
{
|
||||
LOCK(cs_mapMasternodePayeeVotes);
|
||||
|
||||
if (mapMasternodesLastVote.count(outMasternode.hash + outMasternode.n)) {
|
||||
if (mapMasternodesLastVote[outMasternode.hash + outMasternode.n] == nBlockHeight) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//record this masternode voted
|
||||
mapMasternodesLastVote[outMasternode.hash + outMasternode.n] = nBlockHeight;
|
||||
return true;
|
||||
}
|
||||
|
||||
int GetMinMasternodePaymentsProto();
|
||||
void ProcessMessageMasternodePayments(CNode* pfrom, std::string& strCommand, CDataStream& vRecv);
|
||||
std::string GetRequiredPaymentsString(int nBlockHeight);
|
||||
void FillBlockPayee(CMutableTransaction& txNew, int64_t nFees, bool fProofOfStake, bool fZAGRStake);
|
||||
std::string ToString() const;
|
||||
int GetOldestBlock();
|
||||
int GetNewestBlock();
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
|
||||
{
|
||||
READWRITE(mapMasternodePayeeVotes);
|
||||
READWRITE(mapMasternodeBlocks);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user