LCOV - code coverage report
Current view: top level - src/test - coinjoin_dstxmanager_tests.cpp (source / functions) Hit Total Coverage
Test: test_dash_coverage.info Lines: 76 76 100.0 %
Date: 2026-06-25 07:23:51 Functions: 25 25 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2025 The Dash Core developers
       2             : // Distributed under the MIT/X11 software license, see the accompanying
       3             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4             : 
       5             : #include <test/util/setup_common.h>
       6             : 
       7             : #include <chain.h>
       8             : #include <coinjoin/coinjoin.h>
       9             : #include <coinjoin/common.h>
      10             : #include <script/script.h>
      11             : #include <uint256.h>
      12             : 
      13             : #include <algorithm>
      14             : #include <array>
      15             : #include <vector>
      16             : 
      17             : #include <boost/test/unit_test.hpp>
      18             : 
      19         146 : BOOST_FIXTURE_TEST_SUITE(coinjoin_dstxmanager_tests, TestingSetup)
      20             : 
      21           2 : static CCoinJoinBroadcastTx MakeDSTX(int vin_vout_count = 3)
      22             : {
      23           2 :     CCoinJoinBroadcastTx dstx;
      24           2 :     CMutableTransaction mtx;
      25           2 :     const int count = std::max(vin_vout_count, 1);
      26           8 :     for (int i = 0; i < count; ++i) {
      27           6 :         mtx.vin.emplace_back(COutPoint(uint256S("0a"), i));
      28             :         // Use denominated P2PKH outputs
      29           6 :         CScript spk;
      30           6 :         spk << OP_DUP << OP_HASH160 << std::vector<unsigned char>(20, i) << OP_EQUALVERIFY << OP_CHECKSIG;
      31           6 :         mtx.vout.emplace_back(CoinJoin::GetSmallestDenomination(), spk);
      32           6 :     }
      33           2 :     dstx.tx = MakeTransactionRef(mtx);
      34           2 :     dstx.m_protxHash = uint256::ONE;
      35           2 :     return dstx;
      36           2 : }
      37             : 
      38         149 : BOOST_AUTO_TEST_CASE(add_get_dstx)
      39             : {
      40           1 :     CCoinJoinBroadcastTx dstx = MakeDSTX();
      41           1 :     auto& man = *Assert(m_node.dstxman);
      42             :     // Not present initially
      43           1 :     BOOST_CHECK(!man.GetDSTX(dstx.tx->GetHash()));
      44             :     // Add
      45           1 :     man.AddDSTX(dstx);
      46             :     // Fetch back
      47           1 :     auto got = man.GetDSTX(dstx.tx->GetHash());
      48           1 :     BOOST_CHECK(static_cast<bool>(got));
      49           1 :     BOOST_CHECK_EQUAL(got.tx->GetHash().ToString(), dstx.tx->GetHash().ToString());
      50           1 : }
      51             : 
      52         149 : BOOST_AUTO_TEST_CASE(broadcasttx_expiry_height_logic)
      53             : {
      54             :     // Build a valid-looking CCoinJoinBroadcastTx with confirmed height
      55           1 :     CCoinJoinBroadcastTx dstx;
      56             :     {
      57           1 :         CMutableTransaction mtx;
      58           1 :         const int participants = std::max(3, CoinJoin::GetMinPoolParticipants());
      59           4 :         for (int i = 0; i < participants; ++i) {
      60           3 :             mtx.vin.emplace_back(COutPoint(uint256::TWO, i));
      61           3 :             CScript spk;
      62           3 :             spk << OP_DUP << OP_HASH160 << std::vector<unsigned char>(20, i) << OP_EQUALVERIFY << OP_CHECKSIG;
      63           3 :             mtx.vout.emplace_back(CoinJoin::GetSmallestDenomination(), spk);
      64           3 :         }
      65           1 :         dstx.tx = MakeTransactionRef(mtx);
      66           1 :         dstx.m_protxHash = uint256::ONE;
      67             :         // mark as confirmed at height 100
      68           1 :         dstx.SetConfirmedHeight(100);
      69           1 :     }
      70             : 
      71           1 :     int expiry_height = 124; // 125 - 100 == 25 > 24 → expired by height
      72             : 
      73             :     // Minimal CBlockIndex with required fields
      74             :     // Create a minimal block index to satisfy the interface
      75           1 :     CBlockIndex index;
      76           1 :     uint256 blk_hash = uint256S("03");
      77           1 :     index.nHeight = expiry_height;
      78           1 :     index.phashBlock = &blk_hash;
      79             : 
      80           1 :     auto& man = *Assert(m_node.dstxman);
      81           1 :     auto& hash = dstx.tx->GetHash();
      82           1 :     man.AddDSTX(dstx);
      83           1 :     BOOST_CHECK(static_cast<bool>(man.GetDSTX(hash)));
      84             : 
      85           1 :     man.UpdatedBlockTip(&index);
      86           1 :     BOOST_CHECK(static_cast<bool>(man.GetDSTX(hash)));
      87             : 
      88           1 :     index.nHeight = expiry_height + 1;
      89           1 :     man.UpdatedBlockTip(&index);
      90           1 :     BOOST_CHECK(!static_cast<bool>(man.GetDSTX(hash)));
      91           1 : }
      92             : 
      93         149 : BOOST_AUTO_TEST_CASE(update_heights_block_connect_disconnect)
      94             : {
      95           1 :     CCoinJoinBroadcastTx dstx = MakeDSTX();
      96           1 :     auto& man = *Assert(m_node.dstxman);
      97           1 :     man.AddDSTX(dstx);
      98             : 
      99             :     // Create a fake block containing the tx
     100           1 :     auto block = std::make_shared<CBlock>();
     101           1 :     block->vtx.push_back(dstx.tx);
     102           1 :     CBlockIndex index;
     103           1 :     index.nHeight = 100;
     104           1 :     uint256 bh = uint256S("0b");
     105           1 :     index.phashBlock = &bh;
     106             : 
     107             :     // Height should set to 100 on connect
     108           1 :     man.BlockConnected(block, &index);
     109             :     {
     110           1 :         auto got = man.GetDSTX(dstx.tx->GetHash());
     111           1 :         BOOST_CHECK(static_cast<bool>(got));
     112           1 :         BOOST_CHECK(got.GetConfirmedHeight().has_value());
     113           1 :         BOOST_CHECK_EQUAL(*got.GetConfirmedHeight(), 100);
     114           1 :     }
     115             : 
     116             :     // Height should clear on disconnect
     117           1 :     man.BlockDisconnected(block, nullptr);
     118             :     {
     119           1 :         auto got = man.GetDSTX(dstx.tx->GetHash());
     120           1 :         BOOST_CHECK(static_cast<bool>(got));
     121           1 :         BOOST_CHECK(!got.GetConfirmedHeight().has_value());
     122           1 :     }
     123           1 : }
     124             : 
     125         146 : BOOST_AUTO_TEST_SUITE_END()

Generated by: LCOV version 1.16