neobytes/src/masternode-payments.h
UdjinM6 1e2d61ad0d Implement a way to sync only needed winners (#1028)
* store vote hashes in CMasternodePayee and use them in CMasternodePayments::Sync

* Request low data payment blocks in batches directly from some node instead of/after preliminary Sync.

* remove nVotes
2016-09-19 02:23:52 +04:00

213 lines
6.4 KiB
C++

// Copyright (c) 2014-2016 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 "main.h"
#include "masternode.h"
#include "utilstrencodings.h"
class CMasternodePayments;
class CMasternodePaymentWinner;
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 winner and be elected as a winner
// V1 - Last protocol version before update
// V2 - Newest protocol version
static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_1 = 70103;
static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_2 = 70201;
extern CCriticalSection cs_vecPayees;
extern CCriticalSection cs_mapMasternodeBlocks;
extern CCriticalSection cs_mapMasternodePayeeVotes;
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);
bool IsBlockPayeeValid(const CTransaction& txNew, int nBlockHeight, CAmount blockReward);
void FillBlockPayments(CMutableTransaction& txNew, int nBlockHeight, CAmount blockReward, CTxOut& txoutMasternodeRet, std::vector<CTxOut>& voutSuperblockRet);
std::string GetRequiredPaymentsString(int nBlockHeight);
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, int nType, int nVersion) {
READWRITE(*(CScriptBase*)(&scriptPubKey));
READWRITE(vecVoteHashes);
}
CScript GetPayee() { return scriptPubKey; }
void AddVoteHash(uint256 hashIn) { vecVoteHashes.push_back(hashIn); }
std::vector<uint256> GetVoteHashes() { return vecVoteHashes; }
int GetVoteCount() { return vecVoteHashes.size(); }
};
// Keep track of votes for payees from masternodes
class CMasternodeBlockPayees
{
public:
int nBlockHeight;
std::vector<CMasternodePayee> vecPayees;
CMasternodeBlockPayees() : nBlockHeight(0) {}
CMasternodeBlockPayees(int nBlockHeightIn) : nBlockHeight(nBlockHeightIn) {}
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(nBlockHeight);
READWRITE(vecPayees);
}
void AddPayee(CMasternodePaymentWinner winner);
bool GetPayee(CScript& payeeRet);
bool HasPayeeWithVotes(CScript payeeIn, int nVotesReq);
bool IsTransactionValid(const CTransaction& txNew);
std::string GetRequiredPaymentsString();
};
// for storing the winning payments
class CMasternodePaymentWinner
{
public:
CTxIn vinMasternode;
int nBlockHeight;
CScript payee;
std::vector<unsigned char> vchSig;
CMasternodePaymentWinner() :
vinMasternode(CTxIn()),
nBlockHeight(0),
payee(CScript())
{}
CMasternodePaymentWinner(CTxIn vinMasternode, int nBlockHeight, CScript payee) :
vinMasternode(vinMasternode),
nBlockHeight(nBlockHeight),
payee(payee)
{}
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(*(CScriptBase*)(&payee));
READWRITE(vchSig);
}
uint256 GetHash() const {
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
ss << *(CScriptBase*)(&payee);
ss << nBlockHeight;
ss << vinMasternode.prevout;
return ss.GetHash();
}
bool Sign();
bool CheckSignature();
bool IsValid(CNode* pnode, int nValidationHeight, std::string& strError);
void Relay();
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 index
const CBlockIndex *pCurrentBlockIndex;
public:
std::map<uint256, CMasternodePaymentWinner> mapMasternodePayeeVotes;
std::map<int, CMasternodeBlockPayees> mapMasternodeBlocks;
std::map<COutPoint, int> mapMasternodesLastVote;
CMasternodePayments() : nStorageCoeff(1.25), nMinBlocksToStore(4000) {}
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(mapMasternodePayeeVotes);
READWRITE(mapMasternodeBlocks);
}
void Clear();
bool AddWinningMasternode(CMasternodePaymentWinner& winner);
bool ProcessBlock(int nBlockHeight);
void Sync(CNode* node, int nCountNeeded);
void RequestLowDataPaymentBlocks(CNode* pnode);
void CheckAndRemove();
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);
int GetMinMasternodePaymentsProto();
void ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv);
std::string GetRequiredPaymentsString(int nBlockHeight);
void FillBlockPayee(CMutableTransaction& txNew, int nBlockHeight, CAmount blockReward, CTxOut& txoutMasternodeRet);
std::string ToString() const;
int GetBlockCount() { return mapMasternodeBlocks.size(); }
int GetVoteCount() { return mapMasternodePayeeVotes.size(); }
bool IsEnoughData(int nMnCount);
int GetStorageLimit();
void UpdatedBlockTip(const CBlockIndex *pindex);
};
#endif