LCOV - code coverage report
Current view: top level - src/test - validation_tests.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 101 101 100.0 %
Date: 2025-02-23 09:33:43 Functions: 7 7 100.0 %

          Line data    Source code
       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"
       7             : #include "primitives/transaction.h"
       8             : #include "sapling/sapling_validation.h"
       9             : #include "test/librust/utiltest.h"
      10             : #include "util/blockstatecatcher.h"
      11             : #include "wallet/test/wallet_test_fixture.h"
      12             : 
      13             : #include <boost/test/unit_test.hpp>
      14             : 
      15             : BOOST_AUTO_TEST_SUITE(validation_tests)
      16             : 
      17           2 : BOOST_FIXTURE_TEST_CASE(test_simple_shielded_invalid, TestingSetup)
      18             : {
      19           2 :     CMutableTransaction tx;
      20           1 :     tx.nVersion = CTransaction::TxVersion::SAPLING;
      21           1 :     CAmount nDummyValueOut;
      22           1 :     {
      23           2 :         CMutableTransaction newTx(tx);
      24           2 :         CValidationState state;
      25             : 
      26           2 :         BOOST_CHECK(!CheckTransaction(newTx, state, false));
      27           4 :         BOOST_CHECK(state.GetRejectReason() == "bad-txns-vin-empty");
      28             :     }
      29           1 :     {
      30           2 :         CMutableTransaction newTx(tx);
      31           2 :         CValidationState state;
      32             : 
      33           1 :         newTx.sapData->vShieldedSpend.emplace_back();
      34           1 :         newTx.sapData->vShieldedSpend[0].nullifier = GetRandHash();
      35             : 
      36           2 :         BOOST_CHECK(!CheckTransaction(newTx, state, false));
      37           4 :         BOOST_CHECK(state.GetRejectReason() == "bad-txns-vout-empty");
      38             :     }
      39           1 :     {
      40             :         // Ensure that nullifiers are never duplicated within a transaction.
      41           2 :         CMutableTransaction newTx(tx);
      42           2 :         CValidationState state;
      43             : 
      44           1 :         newTx.sapData->vShieldedSpend.emplace_back();
      45           1 :         newTx.sapData->vShieldedSpend[0].nullifier = GetRandHash();
      46             : 
      47           1 :         newTx.sapData->vShieldedOutput.emplace_back();
      48             : 
      49           1 :         newTx.sapData->vShieldedSpend.emplace_back();
      50           1 :         newTx.sapData->vShieldedSpend[1].nullifier = newTx.sapData->vShieldedSpend[0].nullifier;
      51             : 
      52           2 :         BOOST_CHECK(!SaplingValidation::CheckTransactionWithoutProofVerification(newTx, state, nDummyValueOut));
      53           4 :         BOOST_CHECK(state.GetRejectReason() == "bad-spend-description-nullifiers-duplicate");
      54             : 
      55           1 :         newTx.sapData->vShieldedSpend[1].nullifier = GetRandHash();
      56             : 
      57           2 :         BOOST_CHECK(SaplingValidation::CheckTransactionWithoutProofVerification(newTx, state, nDummyValueOut));
      58             :     }
      59           1 :     {
      60           2 :         CMutableTransaction newTx(tx);
      61           1 :         CValidationState state;
      62             : 
      63             :         // Create a coinbase transaction
      64           2 :         CTxIn vin;
      65           1 :         vin.prevout = COutPoint();
      66           1 :         newTx.vin.emplace_back(vin);
      67           2 :         CTxOut vout;
      68           1 :         vout.nValue = 2;
      69           1 :         newTx.vout.emplace_back(vout);
      70             : 
      71           1 :         newTx.sapData->vShieldedSpend.emplace_back();
      72             : 
      73           2 :         BOOST_CHECK(!CheckTransaction(newTx, state, false));
      74           4 :         BOOST_CHECK(state.GetRejectReason() == "bad-txns-invalid-sapling");
      75             :     }
      76           1 :     {
      77           2 :         CMutableTransaction newTx(tx);
      78           1 :         CValidationState state;
      79             : 
      80             :         // Create a coinstake transaction
      81           2 :         CTxIn vin;
      82           1 :         vin.prevout = COutPoint(UINT256_ZERO, 0);
      83           1 :         newTx.vin.emplace_back(vin);
      84           2 :         CTxOut vout;
      85           1 :         vout.nValue = 0;
      86           1 :         newTx.vout.emplace_back(vout);
      87           1 :         vout.nValue = 2;
      88           1 :         newTx.vout.emplace_back(vout);
      89             : 
      90           1 :         newTx.sapData->vShieldedSpend.emplace_back();
      91             : 
      92           2 :         BOOST_CHECK(!CheckTransaction(newTx, state, false));
      93           4 :         BOOST_CHECK(state.GetRejectReason() == "bad-txns-invalid-sapling");
      94             :     }
      95           1 : }
      96             : 
      97           3 : void CheckBlockZcRejection(std::shared_ptr<CBlock>& pblock, int nHeight, CMutableTransaction& mtx, const std::string& expected_msg)
      98             : {
      99           3 :     pblock->vtx.emplace_back(MakeTransactionRef(mtx));
     100           6 :     BOOST_CHECK(SolveBlock(pblock, nHeight));
     101           6 :     BlockStateCatcherWrapper stateCatcher(pblock->GetHash());
     102           3 :     stateCatcher.registerEvent();
     103           9 :     BOOST_CHECK(!ProcessNewBlock(pblock, nullptr));
     104           6 :     BOOST_CHECK(stateCatcher.get().found && !stateCatcher.get().state.IsValid());
     105           9 :     BOOST_CHECK_EQUAL(stateCatcher.get().state.GetRejectReason(), expected_msg);
     106          12 :     BOOST_CHECK(WITH_LOCK(cs_main, return chainActive.Tip()->GetBlockHash(); ) != pblock->GetHash());
     107           3 : }
     108             : 
     109           3 : void CheckMempoolZcRejection(CMutableTransaction& mtx, const std::string& expected_msg)
     110             : {
     111           3 :     LOCK(cs_main);
     112           6 :     CValidationState state;
     113           9 :     BOOST_CHECK(!AcceptToMemoryPool(
     114             :             mempool, state, MakeTransactionRef(mtx), true, nullptr, false, true));
     115           6 :     BOOST_CHECK(!state.IsValid());
     116           9 :     BOOST_CHECK_EQUAL(state.GetRejectReason(), expected_msg);
     117           3 : }
     118             : 
     119             : /*
     120             :  * Running on regtest to have v5 upgrade enforced at block 1 and test in-block zc rejection
     121             :  */
     122           2 : BOOST_FIXTURE_TEST_CASE(zerocoin_rejection_tests, WalletRegTestingSetup)
     123             : {
     124           1 :     UpdateNetworkUpgradeParameters(Consensus::UPGRADE_V5_0, Consensus::NetworkUpgrade::ALWAYS_ACTIVE);
     125           1 :     UpdateNetworkUpgradeParameters(Consensus::UPGRADE_ZC_PUBLIC, Consensus::NetworkUpgrade::ALWAYS_ACTIVE);
     126           1 :     const CChainParams& chainparams = Params();
     127             : 
     128           2 :     std::unique_ptr<CBlockTemplate> pblocktemplate;
     129           3 :     CScript scriptPubKey = CScript() << OP_DUP << OP_HASH160 << ParseHex("8d5b4f83212214d6ef693e02e6d71969fddad976") << OP_EQUALVERIFY << OP_CHECKSIG;
     130           4 :     BOOST_CHECK(pblocktemplate = BlockAssembler(Params(), false).CreateNewBlock(scriptPubKey, &m_wallet, false));
     131           1 :     pblocktemplate->block.hashPrevBlock = chainparams.GetConsensus().hashGenesisBlock;
     132             : 
     133             :     // Base tx
     134           2 :     CMutableTransaction mtx;
     135           2 :     CTxIn vin;
     136           1 :     vin.prevout = COutPoint(UINT256_ZERO, 0);
     137           1 :     mtx.vin.emplace_back(vin);
     138             : 
     139             :     // Zerocoin mints rejection test
     140           1 :     mtx.vout.emplace_back();
     141           2 :     mtx.vout[0].scriptPubKey = CScript() << OP_ZEROCOINMINT <<
     142           2 :                                          CBigNum::randBignum(chainparams.GetConsensus().Zerocoin_Params(false)->coinCommitmentGroup.groupOrder).getvch();
     143           1 :     mtx.vout[0].nValue = 1 * COIN;
     144           2 :     std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>(pblocktemplate->block);
     145           1 :     CheckBlockZcRejection(pblock, 1, mtx, "bad-txns-zc-mint");
     146           1 :     CheckMempoolZcRejection(mtx, "bad-txns-zc-mint");
     147             : 
     148             :     // Zerocoin spends rejection test
     149           1 :     mtx.vout[0].scriptPubKey = scriptPubKey;
     150           1 :     mtx.vin[0].scriptSig = CScript() << OP_ZEROCOINSPEND;
     151           2 :     pblock = std::make_shared<CBlock>(pblocktemplate->block);
     152           1 :     CheckBlockZcRejection(pblock, 1, mtx, "bad-txns-zc-private-spend");
     153           1 :     CheckMempoolZcRejection(mtx, "bad-txns-zc-private-spend");
     154             : 
     155             :     // Zerocoin public spends rejection test
     156           1 :     mtx.vin[0].scriptSig = CScript() << OP_ZEROCOINPUBLICSPEND;
     157           2 :     pblock = std::make_shared<CBlock>(pblocktemplate->block);
     158           1 :     CheckBlockZcRejection(pblock, 1, mtx, "bad-txns-zc-public-spend");
     159           2 :     CheckMempoolZcRejection(mtx, "bad-txns-zc-public-spend");
     160           1 : }
     161             : 
     162             : BOOST_AUTO_TEST_SUITE_END()

Generated by: LCOV version 1.14