neobytes/src/masternode-payments.h
UdjinM6 7e8f07bb92
A couple of fixes for shutdown sequence (#2406)
* Do not run scheduled DoMaintenance if shutdown was requested

* Don't dump cache files if the load sequence was interrupted

* Stop privatesend and release keys before wallet flush

* fix typo
2018-11-02 00:58:17 +03:00

225 lines
7.0 KiB
C++

// Copyright (c) 2014-2017 The Dash Core 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 "util.h"
#include "core_io.h"
#include "key.h"
#include "masternode.h"
#include "net_processing.h"
#include "utilstrencodings.h"
class CMasternodePayments;
class CMasternodePaymentVote;
class CMasternodeBlockPayees;
static const int MNPAYMENTS_SIGNATURES_REQUIRED = 6;
static const int MNPAYMENTS_SIGNATURES_TOTAL = 10;
//! minimum peer version that can receive and send masternode payment messages,
// vote for masternode and be elected as a payment winner
// V1 - Last protocol version before update
// V2 - Newest protocol version
static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_1 = 70210;
static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_2 = 70210;
extern CCriticalSection cs_vecPayees;
extern CCriticalSection cs_mapMasternodeBlocks;
extern CMasternodePayments mnpayments;
/// TODO: all 4 functions do not belong here really, they should be refactored/moved somewhere (main.cpp ?)
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::map<int, std::string> GetRequiredPaymentsStrings(int nStartHeight, int nEndHeight);
class CMasternodePayee
{
private:
CScript scriptPubKey;
std::vector<uint256> vecVoteHashes;
public:
CMasternodePayee() :
scriptPubKey(),
vecVoteHashes()
{}
CMasternodePayee(CScript payee, uint256 hashIn) :
scriptPubKey(payee),
vecVoteHashes()
{
vecVoteHashes.push_back(hashIn);
}
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action) {
READWRITE(*(CScriptBase*)(&scriptPubKey));
READWRITE(vecVoteHashes);
}
CScript GetPayee() const { return scriptPubKey; }
void AddVoteHash(uint256 hashIn) { vecVoteHashes.push_back(hashIn); }
std::vector<uint256> GetVoteHashes() const { return vecVoteHashes; }
int GetVoteCount() const { return vecVoteHashes.size(); }
};
// Keep track of votes for payees from masternodes
class CMasternodeBlockPayees
{
public:
int nBlockHeight;
std::vector<CMasternodePayee> vecPayees;
CMasternodeBlockPayees() :
nBlockHeight(0),
vecPayees()
{}
CMasternodeBlockPayees(int nBlockHeightIn) :
nBlockHeight(nBlockHeightIn),
vecPayees()
{}
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action) {
READWRITE(nBlockHeight);
READWRITE(vecPayees);
}
void AddPayee(const CMasternodePaymentVote& vote);
bool GetBestPayee(CScript& payeeRet) const;
bool HasPayeeWithVotes(const CScript& payeeIn, int nVotesReq) const;
bool IsTransactionValid(const CTransaction& txNew) const;
std::string GetRequiredPaymentsString() const;
};
// vote for the winning payment
class CMasternodePaymentVote
{
public:
COutPoint masternodeOutpoint;
int nBlockHeight;
CScript payee;
std::vector<unsigned char> vchSig;
CMasternodePaymentVote() :
masternodeOutpoint(),
nBlockHeight(0),
payee(),
vchSig()
{}
CMasternodePaymentVote(COutPoint outpoint, int nBlockHeight, CScript payee) :
masternodeOutpoint(outpoint),
nBlockHeight(nBlockHeight),
payee(payee),
vchSig()
{}
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action) {
READWRITE(masternodeOutpoint);
READWRITE(nBlockHeight);
READWRITE(*(CScriptBase*)(&payee));
if (!(s.GetType() & SER_GETHASH)) {
READWRITE(vchSig);
}
}
uint256 GetHash() const;
uint256 GetSignatureHash() const;
bool Sign();
bool CheckSignature(const CKeyID& keyIDOperator, int nValidationHeight, int &nDos) const;
bool IsValid(CNode* pnode, int nValidationHeight, std::string& strError, CConnman& connman) const;
void Relay(CConnman& connman) const;
bool IsVerified() const { return !vchSig.empty(); }
void MarkAsNotVerified() { vchSig.clear(); }
std::string ToString() const;
};
//
// Masternode Payments Class
// Keeps track of who should get paid for which blocks
//
class CMasternodePayments
{
private:
// masternode count times nStorageCoeff payments blocks should be stored ...
const float nStorageCoeff;
// ... but at least nMinBlocksToStore (payments blocks)
const int nMinBlocksToStore;
// Keep track of current block height
int nCachedBlockHeight;
public:
std::map<uint256, CMasternodePaymentVote> mapMasternodePaymentVotes;
std::map<int, CMasternodeBlockPayees> mapMasternodeBlocks;
std::map<COutPoint, int> mapMasternodesLastVote;
std::map<COutPoint, int> mapMasternodesDidNotVote;
CMasternodePayments() : nStorageCoeff(1.25), nMinBlocksToStore(6000) {}
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action) {
READWRITE(mapMasternodePaymentVotes);
READWRITE(mapMasternodeBlocks);
}
void Clear();
bool AddOrUpdatePaymentVote(const CMasternodePaymentVote& vote);
bool HasVerifiedPaymentVote(const uint256& hashIn) const;
bool ProcessBlock(int nBlockHeight, CConnman& connman);
void CheckBlockVotes(int nBlockHeight);
void Sync(CNode* node, CConnman& connman) const;
void RequestLowDataPaymentBlocks(CNode* pnode, CConnman& connman) const;
void CheckAndRemove();
bool GetBlockTxOuts(int nBlockHeight, CAmount blockReward, std::vector<CTxOut>& voutMasternodePaymentsRet) const;
bool IsTransactionValid(const CTransaction& txNew, int nBlockHeight, CAmount blockReward) const;
bool IsScheduled(const masternode_info_t& mnInfo, int nNotBlockHeight) const;
bool UpdateLastVote(const CMasternodePaymentVote& vote);
int GetMinMasternodePaymentsProto() const;
void ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman);
std::string GetRequiredPaymentsString(int nBlockHeight) const;
bool GetMasternodeTxOuts(int nBlockHeight, CAmount blockReward, std::vector<CTxOut>& voutMasternodePaymentsRet) const;
std::string ToString() const;
int GetBlockCount() const { return mapMasternodeBlocks.size(); }
int GetVoteCount() const { return mapMasternodePaymentVotes.size(); }
bool IsEnoughData() const;
int GetStorageLimit() const;
void UpdatedBlockTip(const CBlockIndex *pindex, CConnman& connman);
void DoMaintenance();
};
#endif