30 static const int MNPAYMENTS_DB_VERSION = 1;
48 ssObj << MNPAYMENTS_DB_VERSION;
59 return error(
"%s : Failed to open file %s", __func__,
pathDB.string());
64 }
catch (
const std::exception& e) {
65 return error(
"%s : Serialize or I/O error - %s", __func__, e.what());
81 error(
"%s : Failed to open file %s", __func__,
pathDB.string());
86 int fileSize = fs::file_size(
pathDB);
87 int dataSize = fileSize -
sizeof(
uint256);
91 std::vector<unsigned char> vchData;
92 vchData.resize(dataSize);
97 filein.
read((
char*)vchData.data(), dataSize);
99 }
catch (
const std::exception& e) {
100 error(
"%s : Deserialize or I/O error - %s", __func__, e.what());
109 if (hashIn != hashTmp) {
110 error(
"%s : Checksum mismatch, data corrupted", __func__);
115 std::string strMagicMessageTmp;
119 ssObj >> strMagicMessageTmp;
123 error(
"%s : Invalid masternode payement cache magic message", __func__);
128 std::vector<unsigned char> pchMsgTmp(4);
132 if (memcmp(pchMsgTmp.data(),
Params().MessageStart(), pchMsgTmp.size()) != 0) {
133 error(
"%s : Invalid network magic number", __func__);
139 }
catch (
const std::exception& e) {
141 error(
"%s : Deserialize or I/O error - %s", __func__, e.what());
174 return state.
Error(
"payee must be a P2PKH");
204 if (
Params().IsTestnet()) {
215 nExpectedValue += nBudgetAmt;
224 return nMinted <= nExpectedValue;
229 int nBlockHeight = pindexPrev->
nHeight + 1;
301 return error(
"%s: Failed to get payees for block at height %d", __func__, pindexPrev->
nHeight + 1);
304 if (dmnPayee->nOperatorReward != 0 && !dmnPayee->pdmnState->scriptOperatorPayout.empty()) {
305 operatorReward = (masternodeReward * dmnPayee->nOperatorReward) / 10000;
308 if (masternodeReward > 0) {
309 voutMasternodePaymentsRet.emplace_back(masternodeReward, dmnPayee->pdmnState->scriptPayout);
312 voutMasternodePaymentsRet.emplace_back(
operatorReward, dmnPayee->pdmnState->scriptOperatorPayout);
323 voutMasternodePaymentsRet.clear();
331 payee = winningNode->GetPayeeScript();
343 assert (stakerOuts >= 2);
345 if (stakerOuts == 2) {
347 txCoinstake.
vout[1].nValue -= masternodePayment;
350 unsigned int outputs = stakerOuts-1;
351 CAmount mnPaymentSplit = masternodePayment / outputs;
352 CAmount mnPaymentRemainder = masternodePayment - (mnPaymentSplit * outputs);
353 for (
unsigned int j=1; j<=outputs; j++) {
354 txCoinstake.
vout[j].nValue -= mnPaymentSplit;
357 txCoinstake.
vout[outputs].nValue -= mnPaymentRemainder;
363 std::vector<CTxOut> vecMnOuts;
369 const int nHeight = pindexPrev->
nHeight + 1;
373 if (fProofOfStake && !fPayCoinstake) txCoinbase.
vout.clear();
375 const int initial_cstake_outs = txCoinstake.
vout.size();
378 for (
const CTxOut& mnOut: vecMnOuts) {
381 txCoinstake.
vout.emplace_back(mnOut);
383 txCoinbase.
vout.emplace_back(mnOut);
385 masternodePayment += mnOut.nValue;
393 SubtractMnPaymentFromCoinstake(txCoinstake, masternodePayment, initial_cstake_outs);
412 vRecv >> nCountNeeded;
417 return state.
DoS(20,
false, REJECT_INVALID,
"getmnwinners-request-already-fulfilled");
422 Sync(pfrom, nCountNeeded);
456 return state.
Error(
"block height out of range");
462 return state.
Error(
"mnw old message version");
468 if (dmn ==
nullptr) {
471 if (pmn ==
nullptr) {
476 return state.
Error(
"Non-existent mnwinner voter");
480 assert((dmn && !pmn) || (!dmn && pmn));
483 if (!winner.
IsValid(pfrom, state, nHeight)) {
490 return state.
Error(
"MN already voted");
494 bool is_valid_sig = dmn ? winner.
CheckSignature(dmn->pdmnState->pubKeyOperator.Get())
500 return state.
DoS(20,
false, REJECT_INVALID,
"invalid voter mnwinner signature");
522 return it->second.GetPayee(payee);
538 for (int64_t h = nHeight; h <= nHeight + 8; h++) {
539 if (h == nNotBlockHeight)
continue;
542 if (mnpayee == payee) {
576 int nMaxSignatures = 0;
579 nMaxSignatures = payee.nVotes;
584 std::string strPayeesPossible =
"";
591 if(out.
nValue == requiredMasternodePayment)
594 LogPrintf(
"%s : Masternode payment value (%s) different from required value (%s).\n",
600 if (found)
return true;
605 if (strPayeesPossible !=
"")
606 strPayeesPossible +=
",";
612 LogPrint(
BCLog::MASTERNODE,
"CMasternodePayments::IsTransactionValid - Missing required payment of %s to %s\n",
FormatMoney(requiredMasternodePayment).c_str(), strPayeesPossible.c_str());
620 std::string ret =
"";
631 return ret.empty() ?
"Unknown" : ret;
647 const int nBlockHeight = pindexPrev->
nHeight + 1;
649 std::vector<CTxOut> vecMnOuts;
655 for (
const CTxOut& o : vecMnOuts) {
656 if (std::find(txNew.
vout.begin(), txNew.
vout.end(), o) == txNew.
vout.end()) {
684 int nLimit = std::max(
int(mnCount * 1.25), 1000);
728 LogPrintf(
"%s: ERROR: active masternode is not registered yet\n", __func__);
746 LogPrintf(
"%s: mnw - invalid height %d > %d\n", __func__, nBlockHeight - 100,
mnodeman.
GetBestHeight() + 1);
754 if (pmn ==
nullptr) {
755 LogPrintf(
"%s: Failed to find masternode to pay\n", __func__);
760 newWinner.
AddPayee(pmn->GetPayeeScript());
761 if (mnKey != nullopt) {
763 if (!newWinner.
Sign(*mnKey, mnKey->GetPubKey().GetID())) {
764 LogPrintf(
"%s: Failed to sign masternode winner\n", __func__);
769 if (!newWinner.
Sign(blsKey)) {
770 LogPrintf(
"%s: Failed to sign masternode winner with DMN\n", __func__);
777 LogPrintf(
"%s: Relayed winner %s\n", __func__, newWinner.
GetHash().
ToString());
787 if (nCountNeeded > nCount) nCountNeeded = nCount;
804 std::ostringstream info;
826 assert(tx->IsCoinBase());
828 const CAmount nCBaseOutAmt = tx->GetValueOut();
829 if (nBudgetAmt > 0) {
831 if (nCBaseOutAmt != nBudgetAmt) {
832 const std::string strError =
strprintf(
"%s: invalid coinbase payment for budget (%s vs expected=%s)",
834 return _state.
DoS(100,
error(strError.c_str()), REJECT_INVALID,
"bad-superblock-cb-amt");
843 const std::string strError =
strprintf(
"%s: invalid coinbase payment for masternode (%s vs expected=%s)",
845 if (sporkEnforced && nCBaseOutAmt != nMnAmt) {
846 return _state.
DoS(100,
error(strError.c_str()), REJECT_INVALID,
"bad-cb-amt");
848 if (!sporkEnforced && nCBaseOutAmt > nMnAmt) {
849 return _state.
DoS(100,
error(strError.c_str()), REJECT_INVALID,
"bad-cb-amt-spork8-disabled");
bool GetActiveMasternodeKeys(CTxIn &vin, Optional< CKey > &key, CBLSSecretKey &blsKey)
int64_t CAmount
Amount in PIV (Can be negative)
CBudgetManager g_budgetman
const CChainParams & Params()
Return the currently selected parameters.
std::string ToStringShort() const
Non-refcounted RAII wrapper for FILE*.
bool IsNull() const
Return true if the wrapped FILE* is nullptr, false otherwise.
void read(char *pch, size_t nSize)
static const std::string MAIN
Chain name strings.
const_iterator end() const
const_iterator begin() const
std::vector< CTransactionRef > vtx
The block chain is a tree shaped structure starting with the genesis block at the root,...
int nHeight
height of the entry in the chain. The genesis block has height 0
TrxValidationStatus IsTransactionValid(const CTransaction &txNew, const uint256 &nBlockHash, int nBlockHeight) const
static CAmount GetTotalBudget(int nHeight)
bool FillBlockPayee(CMutableTransaction &txCoinbase, CMutableTransaction &txCoinstake, const int nHeight, bool fProofOfStake) const
std::string GetRequiredPaymentsString(int nBlockHeight)
bool GetExpectedPayeeAmount(int chainHeight, CAmount &nAmountRet) const
bool IsBudgetPaymentBlock(int nBlockHeight) const
const CMessageHeader::MessageStartChars & MessageStart() const
const Consensus::Params & GetConsensus() const
A writer stream (for serialization) that computes a 256-bit hash.
std::string GetRequiredPaymentsString()
std::vector< CMasternodePayee > vecPayments
bool IsTransactionValid(const CTransaction &txNew, int nBlockHeight)
CScript GetPayeeScript() const
int CountEnabled(bool only_legacy=false) const
void AskForMN(CNode *pnode, const CTxIn &vin)
Ask (source) node for mnb.
uint256 GetHashAtHeight(int nHeight) const
MasternodeRef GetNextMasternodeInQueueForPayment(int nBlockHeight, bool fFilterSigTime, int &nCount, const CBlockIndex *pChainTip=nullptr) const
Find an entry in the masternode list that is next to be paid.
int GetBestHeight() const
int GetMasternodeRank(const CTxIn &vin, int64_t nBlockHeight) const
CMasternode * Find(const COutPoint &collateralOut)
Find an entry.
MasternodeRef GetCurrentMasterNode(const uint256 &hash) const
Get the winner for this block hash.
Save Masternode Payment Data (mnpayments.dat)
bool Write(const CMasternodePayments &objToSave)
ReadResult Read(CMasternodePayments &objToLoad)
std::string strMagicMessage
void AddPayee(const CScript &payeeIn)
bool IsValid(CNode *pnode, CValidationState &state, int chainHeight)
std::string GetStrMessage() const override
bool CanVote(const COutPoint &outMasternode, int nBlockHeight) const
void ProcessBlock(int nBlockHeight)
void AddWinningMasternode(CMasternodePaymentWinner &winner)
void CleanPaymentList(int mnCount, int nHeight)
bool GetMasternodeTxOuts(const CBlockIndex *pindexPrev, std::vector< CTxOut > &voutMasternodePaymentsRet) const
bool IsTransactionValid(const CTransaction &txNew, const CBlockIndex *pindexPrev)
std::string GetRequiredPaymentsString(int nBlockHeight)
void RecordWinnerVote(const COutPoint &outMasternode, int nBlockHeight)
std::map< int, CMasternodeBlockPayees > mapMasternodeBlocks
void Sync(CNode *node, int nCountNeeded)
bool IsScheduled(const CMasternode &mn, int nNotBlockHeight)
std::map< COutPoint, int > mapMasternodesLastVote
bool GetBlockPayee(int nBlockHeight, CScript &payee) const
void FillBlockPayee(CMutableTransaction &txCoinbase, CMutableTransaction &txCoinstake, const CBlockIndex *pindexPrev, bool fProofOfStake) const
std::map< uint256, CMasternodePaymentWinner > mapMasternodePayeeVotes
std::string ToString() const
bool ProcessMNWinner(CMasternodePaymentWinner &winner, CNode *pfrom, CValidationState &state)
bool ProcessMessageMasternodePayments(CNode *pfrom, std::string &strCommand, CDataStream &vRecv, CValidationState &state)
bool GetLegacyMasternodeTxOut(int nHeight, std::vector< CTxOut > &voutMasternodePaymentsRet) const
void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) override
Notifies listeners when the block chain tip advances.
void AddFulfilledRequest(const CService &addr, const std::string &strRequest)
bool HasFulfilledRequest(const CService &addr, const std::string &strRequest) const
CSerializedNetMsg Make(int nFlags, std::string sCommand, Args &&... args)
Information about a peer.
std::atomic< int > nVersion
int GetSendVersion() const
void PushInventory(const CInv &inv)
An outpoint - a combination of a transaction hash and an index n into its vout.
Serialized script, used inside transaction inputs and outputs.
bool IsPayToPublicKeyHash() const
bool Sign(const CKey &key, const CKeyID &keyID)
CSignedMessage Class Functions inherited by network signed-messages.
bool CheckSignature(const CKeyID &keyID) const
bool IsSporkActive(SporkId nSporkID)
The basic transaction that is broadcasted on the network and contained in blocks.
const uint256 & GetHash() const
std::string ToString() const
std::vector< CTxOut > vout
An input of a transaction.
An output of a transaction.
Capture information about block/transaction validation.
bool DoS(int level, bool ret=false, unsigned int chRejectCodeIn=0, std::string strRejectReasonIn="", bool corruptionIn=false, const std::string &strDebugMessageIn="")
bool Error(std::string strRejectReasonIn="")
bool IsBlockchainSynced() const
void AddedMasternodeWinner(const uint256 &hash)
bool IsMasternodeListSynced() const
void EraseSeenMNW(const uint256 &hash)
std::string ToString() const
std::unique_ptr< CDeterministicMNManager > deterministicMNManager
@ Valid
Transaction verification failed.
uint256 Hash(const T1 pbegin, const T1 pend)
Compute the 256-bit hash of an object.
std::unique_ptr< CConnman > g_connman
#define LogPrint(category,...)
RecursiveMutex cs_mapMasternodePayeeVotes
bool IsBlockValueValid(int nHeight, CAmount &nExpectedValue, CAmount nMinted, CAmount &nBudgetAmt)
std::string GetRequiredPaymentsString(int nBlockHeight)
RecursiveMutex cs_mapMasternodeBlocks
CMasternodePayments masternodePayments
Object for who's going to get paid on which blocks.
void DumpMasternodePayments()
bool IsCoinbaseValueValid(const CTransactionRef &tx, CAmount nBudgetAmt, CValidationState &_state)
Check coinbase output value for blocks after v6.0 enforcement.
bool IsBlockPayeeValid(const CBlock &block, const CBlockIndex *pindexPrev)
RecursiveMutex cs_vecPayments
void FillBlockPayee(CMutableTransaction &txCoinbase, CMutableTransaction &txCoinstake, const CBlockIndex *pindexPrev, bool fProofOfStake)
#define MNPAYMENTS_SIGNATURES_TOTAL
#define MNPAYMENTS_SIGNATURES_REQUIRED
std::shared_ptr< CMasternode > MasternodeRef
CMasternodeMan mnodeman
Masternode manager.
const char * MNWINNER
The mnwinner message is used to relay and distribute consensus for masternode payout ordering.
const char * GETMNWINNERS
The getmnwinners message is used to request winning masternode data from connected peers.
const char * SYNCSTATUSCOUNT
The syncstatuscount message is used to track the layer 2 syncing process.
std::string EncodeDestination(const CWDestination &address, const CChainParams::Base58Type addrType)
FILE * fopen(const fs::path &p, const char *mode)
RecursiveMutex cs_main
Global state.
CNetFulfilledRequestManager g_netfulfilledman(DEFAULT_ITEMS_FILTER_SIZE)
boost::optional< T > Optional
Substitute for C++17 std::optional.
constexpr Span< A > MakeSpan(A(&a)[N])
MakeSpan for arrays:
CSporkManager sporkManager
@ SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT
@ SPORK_13_ENABLE_SUPERBLOCKS
@ SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet, bool fColdStake)
Parse a standard scriptPubKey for the destination address.
boost::variant< CNoDestination, CKeyID, CScriptID, CExchangeKeyID > CTxDestination
A txout script template with a specific destination.
A mutable version of CTransaction.
std::vector< CTxOut > vout
Parameters that influence chain consensus.
bool NetworkUpgradeActive(int nHeight, Consensus::UpgradeIndex idx) const
Returns true if the given network upgrade is active as of the given block height.
const fs::path & GetDataDir(bool fNetSpecific)
std::atomic< bool > fMasterNode
bool error(const char *fmt, const Args &... args)
TierTwoSyncState g_tiertwo_sync_state
#define MASTERNODE_SYNC_MNW
#define MASTERNODE_SYNC_LIST
std::shared_ptr< const CTransaction > CTransactionRef
std::string FormatMoney(const CAmount &n, bool fPlus)
Money parsing/formatting utilities.
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
int64_t GetTimeMillis()
Returns the system time (not mockable)
int ActiveProtocol()
See whether the protocol update is enforced for connected nodes.
int64_t GetMasternodePayment(int nHeight)
CAmount GetBlockValue(int nHeight)