2016-12-20 14:26:45 +01:00
|
|
|
// Copyright (c) 2014-2017 The Dash Core developers
|
2015-04-16 21:58:09 +02:00
|
|
|
// Distributed under the MIT/X11 software license, see the accompanying
|
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
2016-09-15 08:50:01 +02:00
|
|
|
|
2015-04-16 21:58:09 +02:00
|
|
|
#ifndef MASTERNODE_PAYMENTS_H
|
|
|
|
#define MASTERNODE_PAYMENTS_H
|
|
|
|
|
2016-08-17 09:08:25 +02:00
|
|
|
#include "util.h"
|
2016-02-02 16:28:56 +01:00
|
|
|
#include "core_io.h"
|
2015-04-16 21:58:09 +02:00
|
|
|
#include "key.h"
|
|
|
|
#include "masternode.h"
|
2017-08-09 02:19:06 +02:00
|
|
|
#include "net_processing.h"
|
2016-02-02 16:28:56 +01:00
|
|
|
#include "utilstrencodings.h"
|
|
|
|
|
2016-09-15 08:50:01 +02:00
|
|
|
class CMasternodePayments;
|
2016-09-21 16:45:29 +02:00
|
|
|
class CMasternodePaymentVote;
|
2016-09-15 08:50:01 +02:00
|
|
|
class CMasternodeBlockPayees;
|
2015-04-16 21:58:09 +02:00
|
|
|
|
2016-09-15 08:50:01 +02:00
|
|
|
static const int MNPAYMENTS_SIGNATURES_REQUIRED = 6;
|
|
|
|
static const int MNPAYMENTS_SIGNATURES_TOTAL = 10;
|
2015-04-16 21:58:09 +02:00
|
|
|
|
2016-09-08 14:04:45 +02:00
|
|
|
//! minimum peer version that can receive and send masternode payment messages,
|
2016-09-21 16:45:29 +02:00
|
|
|
// vote for masternode and be elected as a payment winner
|
2016-09-08 14:04:45 +02:00
|
|
|
// V1 - Last protocol version before update
|
|
|
|
// V2 - Newest protocol version
|
2018-09-05 18:34:56 +02:00
|
|
|
static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_1 = 70210;
|
2018-06-12 13:33:41 +02:00
|
|
|
static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_2 = 70210;
|
2016-09-08 14:04:45 +02:00
|
|
|
|
2016-09-12 17:34:11 +02:00
|
|
|
extern CCriticalSection cs_vecPayees;
|
2015-07-29 17:28:49 +02:00
|
|
|
extern CCriticalSection cs_mapMasternodeBlocks;
|
|
|
|
|
2016-02-04 20:29:09 +01:00
|
|
|
extern CMasternodePayments mnpayments;
|
2015-04-22 16:33:44 +02:00
|
|
|
|
2016-08-22 03:41:40 +02:00
|
|
|
/// TODO: all 4 functions do not belong here really, they should be refactored/moved somewhere (main.cpp ?)
|
2018-02-21 17:32:08 +01:00
|
|
|
bool IsBlockValueValid(const CBlock& block, int nBlockHeight, CAmount blockReward, std::string& strErrorRet);
|
2016-08-22 03:41:40 +02:00
|
|
|
bool IsBlockPayeeValid(const CTransaction& txNew, int nBlockHeight, CAmount blockReward);
|
2018-08-14 11:58:38 +02:00
|
|
|
void FillBlockPayments(CMutableTransaction& txNew, int nBlockHeight, CAmount blockReward, std::vector<CTxOut>& voutMasternodePaymentsRet, std::vector<CTxOut>& voutSuperblockPaymentsRet);
|
2018-04-04 17:20:54 +02:00
|
|
|
std::map<int, std::string> GetRequiredPaymentsStrings(int nStartHeight, int nEndHeight);
|
2015-04-22 16:33:44 +02:00
|
|
|
|
2015-06-25 20:08:50 +02:00
|
|
|
class CMasternodePayee
|
2015-04-22 16:33:44 +02:00
|
|
|
{
|
2016-09-19 00:23:52 +02:00
|
|
|
private:
|
2015-06-25 20:08:50 +02:00
|
|
|
CScript scriptPubKey;
|
2016-09-19 00:23:52 +02:00
|
|
|
std::vector<uint256> vecVoteHashes;
|
2015-04-22 16:33:44 +02:00
|
|
|
|
2016-09-19 00:23:52 +02:00
|
|
|
public:
|
|
|
|
CMasternodePayee() :
|
|
|
|
scriptPubKey(),
|
|
|
|
vecVoteHashes()
|
|
|
|
{}
|
|
|
|
|
|
|
|
CMasternodePayee(CScript payee, uint256 hashIn) :
|
|
|
|
scriptPubKey(payee),
|
|
|
|
vecVoteHashes()
|
|
|
|
{
|
|
|
|
vecVoteHashes.push_back(hashIn);
|
|
|
|
}
|
2015-06-25 20:08:50 +02:00
|
|
|
|
|
|
|
ADD_SERIALIZE_METHODS;
|
|
|
|
|
|
|
|
template <typename Stream, typename Operation>
|
2017-09-19 21:36:55 +02:00
|
|
|
inline void SerializationOp(Stream& s, Operation ser_action) {
|
2016-02-02 16:28:56 +01:00
|
|
|
READWRITE(*(CScriptBase*)(&scriptPubKey));
|
2016-09-19 00:23:52 +02:00
|
|
|
READWRITE(vecVoteHashes);
|
|
|
|
}
|
|
|
|
|
2018-02-06 12:09:33 +01:00
|
|
|
CScript GetPayee() const { return scriptPubKey; }
|
2016-09-19 00:23:52 +02:00
|
|
|
|
|
|
|
void AddVoteHash(uint256 hashIn) { vecVoteHashes.push_back(hashIn); }
|
2018-02-06 12:09:33 +01:00
|
|
|
std::vector<uint256> GetVoteHashes() const { return vecVoteHashes; }
|
|
|
|
int GetVoteCount() const { return vecVoteHashes.size(); }
|
2015-04-22 16:33:44 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
// Keep track of votes for payees from masternodes
|
|
|
|
class CMasternodeBlockPayees
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
int nBlockHeight;
|
2016-09-12 17:34:11 +02:00
|
|
|
std::vector<CMasternodePayee> vecPayees;
|
2015-04-22 16:33:44 +02:00
|
|
|
|
2016-12-02 18:15:37 +01:00
|
|
|
CMasternodeBlockPayees() :
|
|
|
|
nBlockHeight(0),
|
|
|
|
vecPayees()
|
|
|
|
{}
|
|
|
|
CMasternodeBlockPayees(int nBlockHeightIn) :
|
|
|
|
nBlockHeight(nBlockHeightIn),
|
|
|
|
vecPayees()
|
|
|
|
{}
|
2015-07-29 17:28:49 +02:00
|
|
|
|
2016-09-12 17:34:11 +02:00
|
|
|
ADD_SERIALIZE_METHODS;
|
2015-04-22 16:33:44 +02:00
|
|
|
|
2016-09-12 17:34:11 +02:00
|
|
|
template <typename Stream, typename Operation>
|
2017-09-19 21:36:55 +02:00
|
|
|
inline void SerializationOp(Stream& s, Operation ser_action) {
|
2016-09-12 17:34:11 +02:00
|
|
|
READWRITE(nBlockHeight);
|
|
|
|
READWRITE(vecPayees);
|
2015-04-22 16:33:44 +02:00
|
|
|
}
|
|
|
|
|
2016-09-21 16:45:29 +02:00
|
|
|
void AddPayee(const CMasternodePaymentVote& vote);
|
2018-03-08 13:18:38 +01:00
|
|
|
bool GetBestPayee(CScript& payeeRet) const;
|
|
|
|
bool HasPayeeWithVotes(const CScript& payeeIn, int nVotesReq) const;
|
2015-07-21 00:09:42 +02:00
|
|
|
|
2018-03-08 13:18:38 +01:00
|
|
|
bool IsTransactionValid(const CTransaction& txNew) const;
|
2015-04-22 16:33:44 +02:00
|
|
|
|
2018-03-08 13:18:38 +01:00
|
|
|
std::string GetRequiredPaymentsString() const;
|
2015-04-22 16:33:44 +02:00
|
|
|
};
|
2015-04-16 21:58:09 +02:00
|
|
|
|
2016-09-21 16:45:29 +02:00
|
|
|
// vote for the winning payment
|
|
|
|
class CMasternodePaymentVote
|
2015-04-16 21:58:09 +02:00
|
|
|
{
|
|
|
|
public:
|
2018-02-15 08:29:44 +01:00
|
|
|
COutPoint masternodeOutpoint;
|
2015-04-22 16:33:44 +02:00
|
|
|
|
2015-04-16 21:58:09 +02:00
|
|
|
int nBlockHeight;
|
2015-06-25 20:08:50 +02:00
|
|
|
CScript payee;
|
2015-04-16 21:58:09 +02:00
|
|
|
std::vector<unsigned char> vchSig;
|
|
|
|
|
2016-09-21 16:45:29 +02:00
|
|
|
CMasternodePaymentVote() :
|
2018-02-15 08:29:44 +01:00
|
|
|
masternodeOutpoint(),
|
2016-09-15 08:50:01 +02:00
|
|
|
nBlockHeight(0),
|
2016-09-21 16:45:29 +02:00
|
|
|
payee(),
|
|
|
|
vchSig()
|
2016-09-15 08:50:01 +02:00
|
|
|
{}
|
2015-04-16 21:58:09 +02:00
|
|
|
|
2018-02-15 08:29:44 +01:00
|
|
|
CMasternodePaymentVote(COutPoint outpoint, int nBlockHeight, CScript payee) :
|
|
|
|
masternodeOutpoint(outpoint),
|
2016-09-15 08:50:01 +02:00
|
|
|
nBlockHeight(nBlockHeight),
|
2016-09-21 16:45:29 +02:00
|
|
|
payee(payee),
|
|
|
|
vchSig()
|
2016-09-15 08:50:01 +02:00
|
|
|
{}
|
2015-07-24 16:12:48 +02:00
|
|
|
|
2015-04-16 21:58:09 +02:00
|
|
|
ADD_SERIALIZE_METHODS;
|
|
|
|
|
|
|
|
template <typename Stream, typename Operation>
|
2017-09-19 21:36:55 +02:00
|
|
|
inline void SerializationOp(Stream& s, Operation ser_action) {
|
2018-09-15 12:19:31 +02:00
|
|
|
READWRITE(masternodeOutpoint);
|
2015-04-16 21:58:09 +02:00
|
|
|
READWRITE(nBlockHeight);
|
2016-02-02 16:28:56 +01:00
|
|
|
READWRITE(*(CScriptBase*)(&payee));
|
2018-02-16 15:54:53 +01:00
|
|
|
if (!(s.GetType() & SER_GETHASH)) {
|
|
|
|
READWRITE(vchSig);
|
|
|
|
}
|
2015-05-27 21:47:01 +02:00
|
|
|
}
|
|
|
|
|
2018-02-16 15:54:53 +01:00
|
|
|
uint256 GetHash() const;
|
|
|
|
uint256 GetSignatureHash() const;
|
2016-09-15 08:50:01 +02:00
|
|
|
|
|
|
|
bool Sign();
|
2018-08-31 15:31:59 +02:00
|
|
|
bool CheckSignature(const CKeyID& keyIDOperator, int nValidationHeight, int &nDos) const;
|
2016-09-15 08:50:01 +02:00
|
|
|
|
2018-03-08 13:18:38 +01:00
|
|
|
bool IsValid(CNode* pnode, int nValidationHeight, std::string& strError, CConnman& connman) const;
|
|
|
|
void Relay(CConnman& connman) const;
|
2016-09-15 08:50:01 +02:00
|
|
|
|
2018-03-08 13:18:38 +01:00
|
|
|
bool IsVerified() const { return !vchSig.empty(); }
|
2016-12-02 18:15:37 +01:00
|
|
|
void MarkAsNotVerified() { vchSig.clear(); }
|
|
|
|
|
2016-09-15 08:50:01 +02:00
|
|
|
std::string ToString() const;
|
2015-04-16 21:58:09 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
//
|
|
|
|
// Masternode Payments Class
|
|
|
|
// Keeps track of who should get paid for which blocks
|
|
|
|
//
|
|
|
|
|
|
|
|
class CMasternodePayments
|
|
|
|
{
|
|
|
|
private:
|
2016-09-15 08:50:01 +02:00
|
|
|
// masternode count times nStorageCoeff payments blocks should be stored ...
|
2016-05-30 14:11:09 +02:00
|
|
|
const float nStorageCoeff;
|
2016-09-15 08:50:01 +02:00
|
|
|
// ... but at least nMinBlocksToStore (payments blocks)
|
|
|
|
const int nMinBlocksToStore;
|
2016-05-29 20:35:09 +02:00
|
|
|
|
2017-08-25 14:57:05 +02:00
|
|
|
// Keep track of current block height
|
|
|
|
int nCachedBlockHeight;
|
2015-04-16 21:58:09 +02:00
|
|
|
|
|
|
|
public:
|
2016-09-21 16:45:29 +02:00
|
|
|
std::map<uint256, CMasternodePaymentVote> mapMasternodePaymentVotes;
|
2015-07-21 04:24:43 +02:00
|
|
|
std::map<int, CMasternodeBlockPayees> mapMasternodeBlocks;
|
2016-09-12 16:59:56 +02:00
|
|
|
std::map<COutPoint, int> mapMasternodesLastVote;
|
2017-10-17 18:42:44 +02:00
|
|
|
std::map<COutPoint, int> mapMasternodesDidNotVote;
|
2015-04-16 21:58:09 +02:00
|
|
|
|
2018-06-06 09:59:25 +02:00
|
|
|
CMasternodePayments() : nStorageCoeff(1.25), nMinBlocksToStore(6000) {}
|
2015-04-16 21:58:09 +02:00
|
|
|
|
2016-09-15 08:50:01 +02:00
|
|
|
ADD_SERIALIZE_METHODS;
|
|
|
|
|
|
|
|
template <typename Stream, typename Operation>
|
2017-09-19 21:36:55 +02:00
|
|
|
inline void SerializationOp(Stream& s, Operation ser_action) {
|
2016-09-21 16:45:29 +02:00
|
|
|
READWRITE(mapMasternodePaymentVotes);
|
2016-09-15 08:50:01 +02:00
|
|
|
READWRITE(mapMasternodeBlocks);
|
2015-07-21 04:24:43 +02:00
|
|
|
}
|
|
|
|
|
2016-09-15 08:50:01 +02:00
|
|
|
void Clear();
|
|
|
|
|
2018-03-10 13:35:27 +01:00
|
|
|
bool AddOrUpdatePaymentVote(const CMasternodePaymentVote& vote);
|
2018-03-08 13:18:38 +01:00
|
|
|
bool HasVerifiedPaymentVote(const uint256& hashIn) const;
|
2017-09-19 16:51:38 +02:00
|
|
|
bool ProcessBlock(int nBlockHeight, CConnman& connman);
|
2018-03-05 13:27:05 +01:00
|
|
|
void CheckBlockVotes(int nBlockHeight);
|
2015-06-25 20:08:50 +02:00
|
|
|
|
2018-03-08 13:18:38 +01:00
|
|
|
void Sync(CNode* node, CConnman& connman) const;
|
|
|
|
void RequestLowDataPaymentBlocks(CNode* pnode, CConnman& connman) const;
|
2016-04-13 19:49:47 +02:00
|
|
|
void CheckAndRemove();
|
2015-04-16 21:58:09 +02:00
|
|
|
|
2018-08-14 11:58:38 +02:00
|
|
|
bool GetBlockTxOuts(int nBlockHeight, CAmount blockReward, std::vector<CTxOut>& voutMasternodePaymentsRet) const;
|
2018-08-12 17:27:09 +02:00
|
|
|
bool IsTransactionValid(const CTransaction& txNew, int nBlockHeight, CAmount blockReward) const;
|
2018-03-08 13:18:38 +01:00
|
|
|
bool IsScheduled(const masternode_info_t& mnInfo, int nNotBlockHeight) const;
|
2015-04-22 16:33:44 +02:00
|
|
|
|
2018-03-08 13:18:38 +01:00
|
|
|
bool UpdateLastVote(const CMasternodePaymentVote& vote);
|
2015-07-24 16:12:48 +02:00
|
|
|
|
2018-03-08 13:18:38 +01:00
|
|
|
int GetMinMasternodePaymentsProto() const;
|
2017-02-06 14:31:37 +01:00
|
|
|
void ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman);
|
2018-03-08 13:18:38 +01:00
|
|
|
std::string GetRequiredPaymentsString(int nBlockHeight) const;
|
2018-08-14 11:58:38 +02:00
|
|
|
bool GetMasternodeTxOuts(int nBlockHeight, CAmount blockReward, std::vector<CTxOut>& voutMasternodePaymentsRet) const;
|
2015-07-21 04:24:43 +02:00
|
|
|
std::string ToString() const;
|
2016-02-04 20:29:09 +01:00
|
|
|
|
2018-03-08 13:18:38 +01:00
|
|
|
int GetBlockCount() const { return mapMasternodeBlocks.size(); }
|
|
|
|
int GetVoteCount() const { return mapMasternodePaymentVotes.size(); }
|
2016-02-04 20:29:09 +01:00
|
|
|
|
2018-03-08 13:18:38 +01:00
|
|
|
bool IsEnoughData() const;
|
|
|
|
int GetStorageLimit() const;
|
2016-05-29 20:35:09 +02:00
|
|
|
|
2017-09-19 16:51:38 +02:00
|
|
|
void UpdatedBlockTip(const CBlockIndex *pindex, CConnman& connman);
|
2018-07-16 14:47:37 +02:00
|
|
|
|
2018-11-01 22:58:17 +01:00
|
|
|
void DoMaintenance();
|
2015-04-16 21:58:09 +02:00
|
|
|
};
|
|
|
|
|
2015-07-08 03:57:32 +02:00
|
|
|
#endif
|