PIVX Core  5.6.99
P2P Digital Currency
validation_tests.cpp
Go to the documentation of this file.
1 // Copyright (c) 2020-2021 The PIVX Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or https://www.opensource.org/licenses/mit-license.php.
4 
5 #include "test/test_pivx.h"
6 #include "blockassembler.h"
10 #include "util/blockstatecatcher.h"
12 
13 #include <boost/test/unit_test.hpp>
14 
15 BOOST_AUTO_TEST_SUITE(validation_tests)
16 
17 BOOST_FIXTURE_TEST_CASE(test_simple_shielded_invalid, TestingSetup)
18 {
21  CAmount nDummyValueOut;
22  {
23  CMutableTransaction newTx(tx);
24  CValidationState state;
25 
26  BOOST_CHECK(!CheckTransaction(newTx, state, false));
27  BOOST_CHECK(state.GetRejectReason() == "bad-txns-vin-empty");
28  }
29  {
30  CMutableTransaction newTx(tx);
31  CValidationState state;
32 
33  newTx.sapData->vShieldedSpend.emplace_back();
34  newTx.sapData->vShieldedSpend[0].nullifier = GetRandHash();
35 
36  BOOST_CHECK(!CheckTransaction(newTx, state, false));
37  BOOST_CHECK(state.GetRejectReason() == "bad-txns-vout-empty");
38  }
39  {
40  // Ensure that nullifiers are never duplicated within a transaction.
41  CMutableTransaction newTx(tx);
42  CValidationState state;
43 
44  newTx.sapData->vShieldedSpend.emplace_back();
45  newTx.sapData->vShieldedSpend[0].nullifier = GetRandHash();
46 
47  newTx.sapData->vShieldedOutput.emplace_back();
48 
49  newTx.sapData->vShieldedSpend.emplace_back();
50  newTx.sapData->vShieldedSpend[1].nullifier = newTx.sapData->vShieldedSpend[0].nullifier;
51 
53  BOOST_CHECK(state.GetRejectReason() == "bad-spend-description-nullifiers-duplicate");
54 
55  newTx.sapData->vShieldedSpend[1].nullifier = GetRandHash();
56 
58  }
59  {
60  CMutableTransaction newTx(tx);
61  CValidationState state;
62 
63  // Create a coinbase transaction
64  CTxIn vin;
65  vin.prevout = COutPoint();
66  newTx.vin.emplace_back(vin);
67  CTxOut vout;
68  vout.nValue = 2;
69  newTx.vout.emplace_back(vout);
70 
71  newTx.sapData->vShieldedSpend.emplace_back();
72 
73  BOOST_CHECK(!CheckTransaction(newTx, state, false));
74  BOOST_CHECK(state.GetRejectReason() == "bad-txns-invalid-sapling");
75  }
76  {
77  CMutableTransaction newTx(tx);
78  CValidationState state;
79 
80  // Create a coinstake transaction
81  CTxIn vin;
82  vin.prevout = COutPoint(UINT256_ZERO, 0);
83  newTx.vin.emplace_back(vin);
84  CTxOut vout;
85  vout.nValue = 0;
86  newTx.vout.emplace_back(vout);
87  vout.nValue = 2;
88  newTx.vout.emplace_back(vout);
89 
90  newTx.sapData->vShieldedSpend.emplace_back();
91 
92  BOOST_CHECK(!CheckTransaction(newTx, state, false));
93  BOOST_CHECK(state.GetRejectReason() == "bad-txns-invalid-sapling");
94  }
95 }
96 
97 void CheckBlockZcRejection(std::shared_ptr<CBlock>& pblock, int nHeight, CMutableTransaction& mtx, const std::string& expected_msg)
98 {
99  pblock->vtx.emplace_back(MakeTransactionRef(mtx));
100  BOOST_CHECK(SolveBlock(pblock, nHeight));
101  BlockStateCatcherWrapper stateCatcher(pblock->GetHash());
102  stateCatcher.registerEvent();
103  BOOST_CHECK(!ProcessNewBlock(pblock, nullptr));
104  BOOST_CHECK(stateCatcher.get().found && !stateCatcher.get().state.IsValid());
105  BOOST_CHECK_EQUAL(stateCatcher.get().state.GetRejectReason(), expected_msg);
106  BOOST_CHECK(WITH_LOCK(cs_main, return chainActive.Tip()->GetBlockHash(); ) != pblock->GetHash());
107 }
108 
109 void CheckMempoolZcRejection(CMutableTransaction& mtx, const std::string& expected_msg)
110 {
111  LOCK(cs_main);
112  CValidationState state;
114  mempool, state, MakeTransactionRef(mtx), true, nullptr, false, true));
115  BOOST_CHECK(!state.IsValid());
116  BOOST_CHECK_EQUAL(state.GetRejectReason(), expected_msg);
117 }
118 
119 /*
120  * Running on regtest to have v5 upgrade enforced at block 1 and test in-block zc rejection
121  */
123 {
126  const CChainParams& chainparams = Params();
127 
128  std::unique_ptr<CBlockTemplate> pblocktemplate;
129  CScript scriptPubKey = CScript() << OP_DUP << OP_HASH160 << ParseHex("8d5b4f83212214d6ef693e02e6d71969fddad976") << OP_EQUALVERIFY << OP_CHECKSIG;
130  BOOST_CHECK(pblocktemplate = BlockAssembler(Params(), false).CreateNewBlock(scriptPubKey, &m_wallet, false));
131  pblocktemplate->block.hashPrevBlock = chainparams.GetConsensus().hashGenesisBlock;
132 
133  // Base tx
135  CTxIn vin;
136  vin.prevout = COutPoint(UINT256_ZERO, 0);
137  mtx.vin.emplace_back(vin);
138 
139  // Zerocoin mints rejection test
140  mtx.vout.emplace_back();
141  mtx.vout[0].scriptPubKey = CScript() << OP_ZEROCOINMINT <<
143  mtx.vout[0].nValue = 1 * COIN;
144  std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>(pblocktemplate->block);
145  CheckBlockZcRejection(pblock, 1, mtx, "bad-txns-zc-mint");
146  CheckMempoolZcRejection(mtx, "bad-txns-zc-mint");
147 
148  // Zerocoin spends rejection test
149  mtx.vout[0].scriptPubKey = scriptPubKey;
150  mtx.vin[0].scriptSig = CScript() << OP_ZEROCOINSPEND;
151  pblock = std::make_shared<CBlock>(pblocktemplate->block);
152  CheckBlockZcRejection(pblock, 1, mtx, "bad-txns-zc-private-spend");
153  CheckMempoolZcRejection(mtx, "bad-txns-zc-private-spend");
154 
155  // Zerocoin public spends rejection test
156  mtx.vin[0].scriptSig = CScript() << OP_ZEROCOINPUBLICSPEND;
157  pblock = std::make_shared<CBlock>(pblocktemplate->block);
158  CheckBlockZcRejection(pblock, 1, mtx, "bad-txns-zc-public-spend");
159  CheckMempoolZcRejection(mtx, "bad-txns-zc-public-spend");
160 }
161 
int64_t CAmount
Amount in PIV (Can be negative)
Definition: amount.h:13
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.
const CChainParams & Params()
Return the currently selected parameters.
Generate a new block.
CValidationState state
BlockStateCatcher & get() const
std::vector< unsigned char > getvch() const
Definition: bignum.cpp:139
static CBigNum randBignum(const CBigNum &range)
Generates a cryptographically secure random number between zero and range exclusive i....
Definition: bignum.cpp:58
uint256 GetBlockHash() const
Definition: chain.h:215
CBlockIndex * Tip(bool fProofOfStake=false) const
Returns the index entry for the tip of this chain, or nullptr if none.
Definition: chain.h:405
CChainParams defines various tweakable parameters of a given instance of the PIVX system.
Definition: chainparams.h:43
const Consensus::Params & GetConsensus() const
Definition: chainparams.h:72
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:72
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:381
An input of a transaction.
Definition: transaction.h:94
COutPoint prevout
Definition: transaction.h:96
An output of a transaction.
Definition: transaction.h:137
CAmount nValue
Definition: transaction.h:139
Capture information about block/transaction validation.
Definition: validation.h:24
bool IsValid() const
Definition: validation.h:69
std::string GetRejectReason() const
Definition: validation.h:94
CBigNum groupOrder
The order of the group.
Definition: Params.h:57
IntegerGroupParams coinCommitmentGroup
The Quadratic Residue group from which we form a coin as a commitment to a serial number.
Definition: Params.h:169
BOOST_AUTO_TEST_SUITE(cuckoocache_tests)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END()
@ LOCK
Definition: lockunlock.h:16
@ SAPLING
Definition: logging.h:63
@ UPGRADE_V5_0
Definition: params.h:36
@ UPGRADE_ZC_PUBLIC
Definition: params.h:33
bool CheckTransactionWithoutProofVerification(const CTransaction &tx, CValidationState &state, CAmount &nValueOut)
RecursiveMutex cs_main
Global state.
Definition: validation.cpp:80
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:18
#define BOOST_CHECK(expr)
Definition: object.cpp:17
uint256 GetRandHash() noexcept
Definition: random.cpp:596
@ OP_CHECKSIG
Definition: script.h:166
@ OP_ZEROCOINSPEND
Definition: script.h:186
@ OP_DUP
Definition: script.h:101
@ OP_ZEROCOINMINT
Definition: script.h:185
@ OP_HASH160
Definition: script.h:163
@ OP_EQUALVERIFY
Definition: script.h:123
@ OP_ZEROCOINPUBLICSPEND
Definition: script.h:187
A mutable version of CTransaction.
Definition: transaction.h:409
Optional< SaplingTxData > sapData
Definition: transaction.h:415
std::vector< CTxOut > vout
Definition: transaction.h:411
std::vector< CTxIn > vin
Definition: transaction.h:410
static constexpr int ALWAYS_ACTIVE
Special value for nActivationHeight indicating that the upgrade is always active.
Definition: params.h:67
uint256 hashGenesisBlock
Definition: params.h:172
libzerocoin::ZerocoinParams * Zerocoin_Params(bool useModulusV1) const
Definition: params.h:260
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:247
bool CheckTransaction(const CTransaction &tx, CValidationState &state, bool fColdStakingActive)
Transaction validation functions.
Definition: tx_verify.cpp:54
const uint256 UINT256_ZERO
constant uint256 instances
Definition: uint256.h:175
std::vector< unsigned char > ParseHex(const char *psz)
CTxMemPool mempool(::minRelayTxFee)
bool ProcessNewBlock(const std::shared_ptr< const CBlock > &pblock, const FlatFilePos *dbp)
Process an incoming block.
bool AcceptToMemoryPool(CTxMemPool &pool, CValidationState &state, const CTransactionRef &tx, bool fLimitFree, bool *pfMissingInputs, bool fOverrideMempoolLimit, bool fRejectInsaneFee, bool ignoreFees)
(try to) add transaction to memory pool
Definition: validation.cpp:649
CChain chainActive
The currently-connected chain of blocks (protected by cs_main).
Definition: validation.cpp:84
void CheckBlockZcRejection(std::shared_ptr< CBlock > &pblock, int nHeight, CMutableTransaction &mtx, const std::string &expected_msg)
BOOST_FIXTURE_TEST_CASE(test_simple_shielded_invalid, TestingSetup)
void CheckMempoolZcRejection(CMutableTransaction &mtx, const std::string &expected_msg)