LCOV - code coverage report
Current view: top level - src/test - test_pivx.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 126 135 93.3 %
Date: 2025-02-23 09:33:43 Functions: 18 21 85.7 %

          Line data    Source code
       1             : // Copyright (c) 2011-2013 The Bitcoin Core developers
       2             : // Copyright (c) 2017-2022 The PIVX Core developers
       3             : // Distributed under the MIT/X11 software license, see the accompanying
       4             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       5             : 
       6             : #define BOOST_TEST_MODULE Pivx Test Suite
       7             : 
       8             : #include "test/test_pivx.h"
       9             : 
      10             : #include "blockassembler.h"
      11             : #include "consensus/merkle.h"
      12             : #include "bls/bls_wrapper.h"
      13             : #include "guiinterface.h"
      14             : #include "evo/deterministicmns.h"
      15             : #include "evo/evodb.h"
      16             : #include "evo/evonotificationinterface.h"
      17             : #include "llmq/quorums_init.h"
      18             : #include "miner.h"
      19             : #include "net_processing.h"
      20             : #include "rpc/server.h"
      21             : #include "rpc/register.h"
      22             : #include "pow.h"
      23             : #include "script/sigcache.h"
      24             : #include "sporkdb.h"
      25             : #include "streams.h"
      26             : #include "txmempool.h"
      27             : #include "validation.h"
      28             : 
      29             : #include <boost/test/unit_test.hpp>
      30             : 
      31             : std::unique_ptr<CConnman> g_connman;
      32             : 
      33             : CClientUIInterface uiInterface;  // Declared but not defined in guiinterface.h
      34             : 
      35             : FastRandomContext g_insecure_rand_ctx;
      36             : /** Random context to get unique temp data dirs. Separate from g_insecure_rand_ctx, which can be seeded from a const env var */
      37             : static FastRandomContext g_insecure_rand_ctx_temp_path;
      38             : 
      39             : /** Return the unsigned from the environment var if available, otherwise 0 */
      40          84 : static uint256 GetUintFromEnv(const std::string& env_name)
      41             : {
      42          84 :     const char* num = std::getenv(env_name.c_str());
      43          84 :     if (!num) return {};
      44           0 :     return uint256S(num);
      45             : }
      46             : 
      47         479 : void Seed(FastRandomContext& ctx)
      48             : {
      49             :     // Should be enough to get the seed once for the process
      50         563 :     static uint256 seed{};
      51         479 :     static const std::string RANDOM_CTX_SEED{"RANDOM_CTX_SEED"};
      52         958 :     if (seed.IsNull()) seed = GetUintFromEnv(RANDOM_CTX_SEED);
      53         958 :     if (seed.IsNull()) seed = GetRandHash();
      54         479 :     LogPrintf("%s: Setting random seed for current tests to %s=%s\n", __func__, RANDOM_CTX_SEED, seed.GetHex());
      55         479 :     ctx = FastRandomContext(seed);
      56         479 : }
      57             : 
      58             : extern bool fPrintToConsole;
      59             : extern void noui_connect();
      60             : 
      61           0 : std::ostream& operator<<(std::ostream& os, const uint256& num)
      62             : {
      63           0 :     os << num.ToString();
      64           0 :     return os;
      65             : }
      66             : 
      67         415 : BasicTestingSetup::BasicTestingSetup(const std::string& chainName)
      68        1660 :     : m_path_root{fs::temp_directory_path() / "test_pivx" / std::to_string(g_insecure_rand_ctx_temp_path.rand32())}
      69             : {
      70         415 :     ECC_Start();
      71         415 :     BLSInit();
      72         415 :     SetupEnvironment();
      73         415 :     InitSignatureCache();
      74         415 :     fCheckBlockIndex = true;
      75         415 :     SelectParams(chainName);
      76         415 :     SeedInsecureRand();
      77         415 :     evoDb.reset(new CEvoDB(1 << 20, true, true));
      78         415 :     deterministicMNManager.reset(new CDeterministicMNManager(*evoDb));
      79         415 : }
      80             : 
      81         828 : BasicTestingSetup::~BasicTestingSetup()
      82             : {
      83         414 :     fs::remove_all(m_path_root);
      84         414 :     ECC_Stop();
      85         414 :     deterministicMNManager.reset();
      86         414 :     evoDb.reset();
      87         414 : }
      88             : 
      89         130 : fs::path BasicTestingSetup::SetDataDir(const std::string& name)
      90             : {
      91         130 :     fs::path ret = m_path_root / name;
      92         130 :     fs::create_directories(ret);
      93         130 :     gArgs.ForceSetArg("-datadir", ret.string());
      94         130 :     return ret;
      95             : }
      96             : 
      97         118 : TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(chainName)
      98             : {
      99         236 :         SetDataDir("tempdir");
     100         118 :         ClearDatadirCache();
     101             : 
     102             :         // Start the lightweight task scheduler thread
     103         118 :         CScheduler::Function serviceLoop = std::bind(&CScheduler::serviceQueue, &scheduler);
     104         118 :         threadGroup.create_thread(std::bind(&TraceThread<CScheduler::Function>, "scheduler", serviceLoop));
     105             : 
     106             :         // Note that because we don't bother running a scheduler thread here,
     107             :         // callbacks via CValidationInterface are unreliable, but that's OK,
     108             :         // our unit tests aren't testing multiple parts of the code at once.
     109         118 :         GetMainSignals().RegisterBackgroundSignalScheduler(scheduler);
     110             : 
     111         236 :         g_connman = std::make_unique<CConnman>(0x1337, 0x1337); // Deterministic randomness for tests.
     112         118 :         connman = g_connman.get();
     113             : 
     114             :         // Register EvoNotificationInterface
     115         118 :         pEvoNotificationInterface = new EvoNotificationInterface();
     116         118 :         RegisterValidationInterface(pEvoNotificationInterface);
     117             : 
     118             :         // Ideally we'd move all the RPC tests to the functional testing framework
     119             :         // instead of unit tests, but for now we need these here.
     120         118 :         RegisterAllCoreRPCCommands(tableRPC);
     121         118 :         zerocoinDB.reset(new CZerocoinDB(0, true));
     122         118 :         pSporkDB.reset(new CSporkDB(0, true));
     123         118 :         pblocktree.reset(new CBlockTreeDB(1 << 20, true));
     124         118 :         pcoinsdbview.reset(new CCoinsViewDB(1 << 23, true));
     125         118 :         pcoinsTip.reset(new CCoinsViewCache(pcoinsdbview.get()));
     126         118 :         llmq::InitLLMQSystem(*evoDb, &scheduler, true);
     127         118 :         if (!LoadGenesisBlock()) {
     128           0 :             throw std::runtime_error("Error initializing block database");
     129             :         }
     130         118 :         {
     131         236 :             CValidationState state;
     132         118 :             bool ok = ActivateBestChain(state);
     133         236 :             BOOST_CHECK(ok);
     134             :         }
     135         118 :         nScriptCheckThreads = 3;
     136         354 :         for (int i=0; i < nScriptCheckThreads-1; i++)
     137         236 :             threadGroup.create_thread(&ThreadScriptCheck);
     138         236 :         peerLogic.reset(new PeerLogicValidation(connman));
     139         118 : }
     140             : 
     141         118 : TestingSetup::~TestingSetup()
     142             : {
     143         118 :         scheduler.stop();
     144         118 :         llmq::InterruptLLMQSystem();
     145         118 :         threadGroup.interrupt_all();
     146         118 :         threadGroup.join_all();
     147         118 :         GetMainSignals().FlushBackgroundCallbacks();
     148         118 :         UnregisterAllValidationInterfaces();
     149         118 :         GetMainSignals().UnregisterBackgroundSignalScheduler();
     150         118 :         g_connman.reset();
     151         118 :         peerLogic.reset();
     152         118 :         UnloadBlockIndex();
     153         118 :         delete pEvoNotificationInterface;
     154         118 :         pcoinsTip.reset();
     155         118 :         pcoinsdbview.reset();
     156         118 :         pblocktree.reset();
     157         118 :         zerocoinDB.reset();
     158         118 :         pSporkDB.reset();
     159         118 :         llmq::DestroyLLMQSystem();
     160         118 : }
     161             : 
     162             : // Test chain only available on regtest
     163          11 : TestChainSetup::TestChainSetup(int blockCount) : TestingSetup(CBaseChainParams::REGTEST)
     164             : {
     165             :     // if blockCount is over PoS start, delay it to 100 blocks after.
     166          11 :     if (blockCount > Params().GetConsensus().vUpgrades[Consensus::UPGRADE_POS].nActivationHeight) {
     167           2 :         UpdateNetworkUpgradeParameters(Consensus::UPGRADE_POS, blockCount + 100);
     168           2 :         UpdateNetworkUpgradeParameters(Consensus::UPGRADE_V3_4, blockCount + 101);
     169             :     }
     170             : 
     171             :     // Generate a blockCount-block chain:
     172          11 :     coinbaseKey.MakeNewKey(true);
     173          22 :     CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;
     174        1511 :     for (int i = 0; i < blockCount; i++)
     175             :     {
     176        3000 :         std::vector<CMutableTransaction> noTxns;
     177        3000 :         CBlock b = CreateAndProcessBlock(noTxns, scriptPubKey);
     178        1500 :         coinbaseTxns.push_back(*b.vtx[0]);
     179             :     }
     180          11 : }
     181             : 
     182             : // Create a new block with coinbase paying to scriptPubKey, and try to add it to the current chain.
     183             : // Include given transactions, and, if fNoMempoolTx=true, remove transactions coming from the mempool.
     184        2407 : CBlock TestChainSetup::CreateAndProcessBlock(const std::vector<CMutableTransaction>& txns, const CScript& scriptPubKey, bool fNoMempoolTx)
     185             : {
     186        2407 :     CBlock block = CreateBlock(txns, scriptPubKey, fNoMempoolTx);
     187        2407 :     ProcessNewBlock(std::make_shared<const CBlock>(block), nullptr);
     188        2407 :     return block;
     189             : }
     190             : 
     191         884 : CBlock TestChainSetup::CreateAndProcessBlock(const std::vector<CMutableTransaction>& txns, const CKey& scriptKey)
     192             : {
     193        1768 :     CScript scriptPubKey = CScript() <<  ToByteVector(scriptKey.GetPubKey()) << OP_CHECKSIG;
     194        1768 :     return CreateAndProcessBlock(txns, scriptPubKey);
     195             : }
     196             : 
     197        2435 : CBlock TestChainSetup::CreateBlock(const std::vector<CMutableTransaction>& txns,
     198             :                                    const CScript& scriptPubKey,
     199             :                                    bool fNoMempoolTx,
     200             :                                    bool fTestBlockValidity,
     201             :                                    bool fIncludeQfc,
     202             :                                    CBlockIndex* customPrevBlock)
     203             : {
     204        2435 :     std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler(
     205             :             Params(), DEFAULT_PRINTPRIORITY).CreateNewBlock(scriptPubKey,
     206             :                                                             nullptr,       // wallet
     207             :                                                             false,   // fProofOfStake
     208             :                                                             nullptr, // availableCoins
     209             :                                                             fNoMempoolTx,
     210             :                                                             fTestBlockValidity,
     211             :                                                             customPrevBlock,
     212             :                                                             true,
     213        2435 :                                                             fIncludeQfc);
     214        4870 :     std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>(pblocktemplate->block);
     215             : 
     216             :     // Add passed-in txns:
     217        2498 :     for (const CMutableTransaction& tx : txns) {
     218          63 :         pblock->vtx.push_back(MakeTransactionRef(tx));
     219             :     }
     220             : 
     221        4869 :     const int nHeight = (customPrevBlock != nullptr ? customPrevBlock->nHeight + 1
     222        4868 :                                                     : WITH_LOCK(cs_main, return chainActive.Height()) + 1);
     223             : 
     224             :     // Re-compute sapling root
     225        2435 :     pblock->hashFinalSaplingRoot = CalculateSaplingTreeRoot(pblock.get(), nHeight, Params());
     226             : 
     227             :     // Find valid PoW
     228        2435 :     assert(SolveBlock(pblock, nHeight));
     229        4870 :     return *pblock;
     230             : }
     231             : 
     232          11 : CBlock TestChainSetup::CreateBlock(const std::vector<CMutableTransaction>& txns, const CKey& scriptKey,
     233             :                                    bool fTestBlockValidity)
     234             : {
     235          22 :     CScript scriptPubKey = CScript() <<  ToByteVector(scriptKey.GetPubKey()) << OP_CHECKSIG;
     236          22 :     return CreateBlock(txns, scriptPubKey, fTestBlockValidity);
     237             : }
     238             : 
     239         241 : std::shared_ptr<CBlock> FinalizeBlock(std::shared_ptr<CBlock> pblock)
     240             : {
     241         241 :     pblock->hashMerkleRoot = BlockMerkleRoot(*pblock);
     242         522 :     while (!CheckProofOfWork(pblock->GetHash(), pblock->nBits)) { ++(pblock->nNonce); }
     243         241 :     return pblock;
     244             : }
     245             : 
     246          22 : TestChainSetup::~TestChainSetup()
     247             : {
     248          11 : }
     249             : 
     250       19882 : CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(const CMutableTransaction& tx)
     251             : {
     252       39764 :     CTransaction txn(tx);
     253       39764 :     return FromTx(txn);
     254             : }
     255             : 
     256       19882 : CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(const CTransaction& txn)
     257             : {
     258       59646 :     return CTxMemPoolEntry(MakeTransactionRef(txn), nFee, nTime, nHeight,
     259       39764 :                            spendsCoinbaseOrCoinstake, sigOpCount);
     260             : }
     261             : 
     262           0 : [[noreturn]] void Shutdown(void* parg)
     263             : {
     264           0 :     std::exit(0);
     265             : }
     266             : 
     267           0 : [[noreturn]] void StartShutdown()
     268             : {
     269           0 :     std::exit(0);
     270             : }
     271             : 
     272        3159 : bool ShutdownRequested()
     273             : {
     274        3159 :   return false;
     275             : }

Generated by: LCOV version 1.14