16 #include "validation.h"
18 #include <boost/test/unit_test.hpp>
38 static bool CreateMNWinnerPayment(
const CTxIn& mnVinVoter,
int paymentBlockHeight,
const CScript& payeeScript,
42 mnWinner.AddPayee(payeeScript);
84 std::vector<FakeMasternode> ret;
85 for (
int i=0; i < size; i++) {
92 const CPubKey& collateralPubKey = mnPubKey;
95 MNdata mnData(mnCollateral, mnKey, mnPubKey, collateralPubKey, mnPayeeScript);
98 ret.emplace_back(mn, mnData);
105 for (
const auto& item : mnList) {
106 if (item.data.mnPubKey == ref->pubKeyMasternode) {
110 throw std::runtime_error(
"MN not found");
120 CreateAndProcessBlock({}, coinbaseKey);
121 CBlock tipBlock = CreateAndProcessBlock({}, coinbaseKey);
123 int nextBlockHeight = 103;
127 std::vector<FakeMasternode> mnList =
buildMNList(tipBlock.GetHash(), tipBlock.GetBlockTime(), 40);
136 BOOST_CHECK(!CreateMNWinnerPayment(dummyVoter, nextBlockHeight, dummyPayeeScript,
137 dummyKey, dummyKey.
GetPubKey(), state0));
141 auto firstMN =
findMNData(mnList, mnRank[0].second);
142 CTxIn mnVinVoter(firstMN.mn.vin);
143 int paymentBlockHeight = nextBlockHeight;
149 BOOST_CHECK(!CreateMNWinnerPayment(mnVinVoter, paymentBlockHeight, payeeScript,
150 firstMN.
data.mnPrivKey, firstMN.data.mnPubKey, state1));
155 auto secondMn =
findMNData(mnList, mnRank[1].second);
158 payeeScript = secondMn.
data.mnPayeeScript;
160 BOOST_CHECK(!CreateMNWinnerPayment(mnVinVoter, paymentBlockHeight, payeeScript,
161 firstMN.
data.mnPrivKey, firstMN.data.mnPubKey, state2));
167 BOOST_CHECK(!CreateMNWinnerPayment(mnVinVoter, paymentBlockHeight + 20, payeeScript,
168 secondMn.
data.mnPrivKey, secondMn.data.mnPubKey, state2_5));
176 BOOST_CHECK(!CreateMNWinnerPayment(mnVinVoter, paymentBlockHeight, payeeScript,
177 secondMn.
data.mnPrivKey, secondMn.data.mnPubKey, state3));
182 auto thirdMn =
findMNData(mnList, mnRank[2].second);
187 BOOST_CHECK(!CreateMNWinnerPayment(mnVinVoter, paymentBlockHeight, scriptDummy,
188 thirdMn.
data.mnPrivKey, thirdMn.data.mnPubKey, state4));
192 auto voterPos15 =
findMNData(mnList, mnRank[14].second);
195 payeeScript = thirdMn.
data.mnPayeeScript;
197 BOOST_CHECK(!CreateMNWinnerPayment(mnVinVoter, paymentBlockHeight, payeeScript,
198 voterPos15.
data.mnPrivKey, voterPos15.data.mnPubKey, state6));
204 BOOST_CHECK(CreateMNWinnerPayment(mnVinVoter, paymentBlockHeight, payeeScript,
205 thirdMn.
data.mnPrivKey, thirdMn.data.mnPubKey, state7));
209 tipBlock = CreateAndProcessBlock({}, coinbaseKey);
210 BOOST_CHECK_MESSAGE(tipBlock.vtx[0]->vout.back().scriptPubKey == payeeScript,
"error: block not paying to proper MN");
220 payeeScript = firstRankedPayee;
221 for (
int i=0; i<10; i++) {
223 payeeScript = secondRankedPayee;
225 auto voterMn =
findMNData(mnList, mnRank[i].second);
229 BOOST_CHECK(CreateMNWinnerPayment(mnVinVoter, nextBlockHeight, payeeScript,
230 voterMn.
data.mnPrivKey, voterMn.data.mnPubKey, stateInternal));
236 BOOST_CHECK_MESSAGE(blockPayees.
HasPayeeWithVotes(firstRankedPayee, 6),
"first ranked payee with no enough votes");
237 BOOST_CHECK_MESSAGE(blockPayees.
HasPayeeWithVotes(secondRankedPayee, 4),
"second ranked payee with no enough votes");
240 CBlock badBlock = CreateBlock({}, coinbaseKey);
242 coinbase.vout[coinbase.vout.size() - 1].scriptPubKey = secondRankedPayee;
243 badBlock.
vtx[0] = MakeTransactionRef(coinbase);
246 auto pBadBlock = std::make_shared<CBlock>(badBlock);
258 tipBlock = CreateAndProcessBlock({}, coinbaseKey);
259 BOOST_CHECK_MESSAGE(tipBlock.vtx[0]->vout.back().scriptPubKey == firstRankedPayee,
"error: block not paying to first ranked MN");
264 for (
int i = 0; i < 125; i++) {
267 for (
int j=0; j<7; j++) {
268 auto voterMn =
findMNData(mnList, mnRank[j].second);
272 BOOST_CHECK(CreateMNWinnerPayment(mnVinVoter, nextBlockHeight, payeeScript,
273 voterMn.
data.mnPrivKey, voterMn.data.mnPubKey, stateInternal));
277 tipBlock = CreateAndProcessBlock({}, coinbaseKey);
278 BOOST_CHECK_MESSAGE(tipBlock.vtx[0]->vout.back().scriptPubKey == payeeScript,
"error: block not paying to proper MN");
292 for (
int i=0; i<6; i++) {
293 auto voterMn =
findMNData(mnList, mnRank[i].second);
297 BOOST_CHECK(CreateMNWinnerPayment(mnVinVoter, nextBlockHeight, payeeScript,
298 voterMn.
data.mnPrivKey, voterMn.data.mnPubKey, stateInternal));
305 BOOST_CHECK_MESSAGE(!
mnodeman.
Find(mnToPay->vin.prevout),
"error: removed MN is still available");
308 auto voterMn =
findMNData(mnList, mnRank[7].second);
312 BOOST_CHECK(CreateMNWinnerPayment(mnVinVoter, nextBlockHeight, payeeScript,
313 voterMn.
data.mnPrivKey, voterMn.data.mnPubKey, stateInternal));
bool SolveBlock(std::shared_ptr< CBlock > &pblock, int nHeight)
Modify the nonce/extranonce in a block.
void UpdateNetworkUpgradeParameters(Consensus::UpgradeIndex idx, int nActivationHeight)
Allows modifying the network upgrade regtest parameters.
BlockStateCatcher & get() const
std::vector< CTransactionRef > vtx
uint256 GetBlockHash() const
CBlockIndex * Tip(bool fProofOfStake=false) const
Returns the index entry for the tip of this chain, or nullptr if none.
int Height() const
Return the maximal height in the chain.
An encapsulated private key.
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
CPubKey GetPubKey() const
Compute the public key from a private key.
bool HasPayeeWithVotes(const CScript &payee, int nVotesReq)
CPubKey pubKeyCollateralAddress
std::vector< std::pair< int64_t, MasternodeRef > > GetMasternodeRanks(int nBlockHeight) const
void Remove(const COutPoint &collateralOut)
bool Add(CMasternode &mn)
Add an entry.
CMasternode * Find(const COutPoint &collateralOut)
Find an entry.
std::map< int, CMasternodeBlockPayees > mapMasternodeBlocks
bool ProcessMNWinner(CMasternodePaymentWinner &winner, CNode *pfrom, CValidationState &state)
An outpoint - a combination of a transaction hash and an index n into its vout.
An encapsulated public key.
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Serialized script, used inside transaction inputs and outputs.
bool IsSporkActive(SporkId nSporkID)
void AddOrUpdateSporkMessage(const CSporkMessage &spork, bool flush=false)
An input of a transaction.
Capture information about block/transaction validation.
std::string GetRejectReason() const
FakeMasternode(CMasternode &mn, const MNdata &data)
MNdata(const COutPoint &collateralOut, const CKey &mnPrivKey, const CPubKey &mnPubKey, const CPubKey &collateralPubKey, const CScript &mnPayeeScript)
void SetCurrentSyncPhase(int sync_phase)
BOOST_AUTO_TEST_SUITE(cuckoocache_tests)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END()
CMasternodePayments masternodePayments
Object for who's going to get paid on which blocks.
std::shared_ptr< CMasternode > MasternodeRef
CMasternodeMan mnodeman
Masternode manager.
uint256 BlockMerkleRoot(const CBlock &block, bool *mutated)
UniValue spork(const JSONRPCRequest &request)
bool findStrError(CValidationState &state, const std::string &str)
BOOST_FIXTURE_TEST_CASE(mnwinner_test, TestChain100Setup)
CMasternode buildMN(const MNdata &data, const uint256 &tipHash, uint64_t tipTime)
void enableMnSyncAndMNPayments()
FakeMasternode findMNData(std::vector< FakeMasternode > &mnList, const MasternodeRef &ref)
std::vector< FakeMasternode > buildMNList(const uint256 &tipHash, uint64_t tipTime, int size)
RecursiveMutex cs_main
Global state.
#define BOOST_CHECK_EQUAL(v1, v2)
#define BOOST_CHECK(expr)
uint256 GetRandHash() noexcept
CSporkManager sporkManager
@ SPORK_13_ENABLE_SUPERBLOCKS
@ SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a PIVX scriptPubKey for the given CTxDestination.
A mutable version of CTransaction.
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
TierTwoSyncState g_tiertwo_sync_state
#define MASTERNODE_SYNC_FINISHED
int64_t GetTime()
DEPRECATED Use either GetSystemTimeInSeconds (not mockable) or GetTime<T> (mockable)
bool ProcessNewBlock(const std::shared_ptr< const CBlock > &pblock, const FlatFilePos *dbp)
Process an incoming block.
CChain chainActive
The currently-connected chain of blocks (protected by cs_main).