LCOV - code coverage report
Current view: top level - src/evo - simplifiedmns.cpp (source / functions) Hit Total Coverage
Test: test_dash_coverage.info Lines: 59 80 73.8 %
Date: 2026-06-25 07:23:51 Functions: 10 11 90.9 %

          Line data    Source code
       1             : // Copyright (c) 2017-2025 The Dash Core developers
       2             : // Distributed under the MIT software license, see the accompanying
       3             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4             : 
       5             : #include <evo/simplifiedmns.h>
       6             : 
       7             : #include <evo/netinfo.h>
       8             : #include <util/std23.h>
       9             : 
      10             : #include <clientversion.h>
      11             : #include <consensus/merkle.h>
      12             : #include <key_io.h>
      13             : #include <logging.h>
      14             : #include <serialize.h>
      15             : #include <sync.h>
      16             : #include <util/time.h>
      17             : #include <version.h>
      18             : 
      19             : #include <univalue.h>
      20             : 
      21       34318 : CSimplifiedMNListEntry::CSimplifiedMNListEntry(const uint256& proreg_tx_hash, const uint256& confirmed_hash,
      22             :                                                const std::shared_ptr<NetInfoInterface>& net_info,
      23             :                                                const CBLSLazyPublicKey& pubkey_operator, const CKeyID& keyid_voting,
      24             :                                                bool is_valid, uint16_t platform_http_port,
      25             :                                                const uint160& platform_node_id, const CScript& script_payout,
      26             :                                                const CScript& script_operator_payout, uint16_t version, MnType type) :
      27       17159 :     proRegTxHash(proreg_tx_hash),
      28       17159 :     confirmedHash(confirmed_hash),
      29       17159 :     netInfo(net_info),
      30       17159 :     pubKeyOperator(pubkey_operator),
      31       17159 :     keyIDVoting(keyid_voting),
      32       17159 :     isValid(is_valid),
      33       17159 :     platformHTTPPort(platform_http_port),
      34       17159 :     platformNodeID(platform_node_id),
      35       17159 :     scriptPayout(script_payout),
      36       17159 :     scriptOperatorPayout(script_operator_payout),
      37       17159 :     nVersion(version),
      38       17159 :     nType(type)
      39       17159 : {
      40       34318 : }
      41             : 
      42         408 : uint256 CSimplifiedMNListEntry::CalcHash() const
      43             : {
      44         408 :     CHashWriter hw(SER_GETHASH, CLIENT_VERSION);
      45         408 :     hw << *this;
      46         408 :     return hw.GetHash();
      47             : }
      48             : 
      49           0 : std::string CSimplifiedMNListEntry::ToString() const
      50             : {
      51           0 :     CTxDestination dest;
      52           0 :     std::string payoutAddress = "unknown";
      53           0 :     std::string operatorPayoutAddress = "none";
      54           0 :     if (ExtractDestination(scriptPayout, dest)) {
      55           0 :         payoutAddress = EncodeDestination(dest);
      56           0 :     }
      57           0 :     if (ExtractDestination(scriptOperatorPayout, dest)) {
      58           0 :         operatorPayoutAddress = EncodeDestination(dest);
      59           0 :     }
      60             : 
      61           0 :     return strprintf("CSimplifiedMNListEntry(nVersion=%d, nType=%d, proRegTxHash=%s, confirmedHash=%s, netInfo=%s, "
      62             :                      "pubKeyOperator=%s, votingAddress=%s, isValid=%d, payoutAddress=%s, operatorPayoutAddress=%s, "
      63             :                      "platformNodeID=%s%s)\n",
      64           0 :                      nVersion, std23::to_underlying(nType), proRegTxHash.ToString(), confirmedHash.ToString(),
      65           0 :                      netInfo->ToString(), pubKeyOperator.ToString(), EncodeDestination(PKHash(keyIDVoting)), isValid,
      66           0 :                      payoutAddress, operatorPayoutAddress, platformNodeID.ToString(),
      67           0 :                      (nVersion >= ProTxVersion::ExtAddr ? "" : strprintf(", platformHTTPPort=%d", platformHTTPPort)));
      68           0 : }
      69             : 
      70         418 : CSimplifiedMNList::CSimplifiedMNList(std::vector<std::unique_ptr<CSimplifiedMNListEntry>>&& smlEntries)
      71         209 : {
      72         209 :     mnList = std::move(smlEntries);
      73             : 
      74        2265 :     std::sort(mnList.begin(), mnList.end(), [&](const std::unique_ptr<CSimplifiedMNListEntry>& a, const std::unique_ptr<CSimplifiedMNListEntry>& b) {
      75        2056 :         return a->proRegTxHash.Compare(b->proRegTxHash) < 0;
      76             :     });
      77         418 : }
      78             : 
      79          59 : uint256 CSimplifiedMNList::CalcMerkleRoot(bool* pmutated) const
      80             : {
      81          59 :     std::vector<uint256> leaves;
      82          59 :     leaves.reserve(mnList.size());
      83         452 :     for (const auto& e : mnList) {
      84         393 :         leaves.emplace_back(e->CalcHash());
      85             :     }
      86          59 :     return ComputeMerkleRoot(leaves, pmutated);
      87          59 : }
      88             : 
      89       36470 : bool CSimplifiedMNList::operator==(const CSimplifiedMNList& rhs) const
      90             : {
      91       72911 :     return mnList.size() == rhs.mnList.size() &&
      92       36441 :             std::equal(mnList.begin(), mnList.end(), rhs.mnList.begin(),
      93       14041 :                 [](const std::unique_ptr<CSimplifiedMNListEntry>& left, const std::unique_ptr<CSimplifiedMNListEntry>& right)
      94             :                 {
      95       14041 :                     return *left == *right;
      96             :                 }
      97             :             );
      98             : }
      99             : 
     100       36470 : bool CalcCbTxMerkleRootMNList(uint256& merkleRootRet, gsl::not_null<std::shared_ptr<const CSimplifiedMNList>> sml,
     101             :                               BlockValidationState& state)
     102             : {
     103             :     try {
     104             :         static std::atomic<int64_t> nTimeMerkle = 0;
     105             : 
     106       36470 :         int64_t nTime1 = GetTimeMicros();
     107             : 
     108       36470 :         static Mutex cached_mutex;
     109       36473 :         static gsl::not_null<std::shared_ptr<const CSimplifiedMNList>> cached_sml GUARDED_BY(cached_mutex){
     110           3 :             std::make_shared<const CSimplifiedMNList>()};
     111             :         static uint256 merkleRootCached GUARDED_BY(cached_mutex);
     112             :         static bool mutatedCached GUARDED_BY(cached_mutex){false};
     113             : 
     114       36470 :         LOCK(cached_mutex);
     115       36470 :         if (sml == cached_sml || *sml == *cached_sml) {
     116       36412 :             merkleRootRet = merkleRootCached;
     117       36412 :             if (mutatedCached) {
     118           0 :                 return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "mutated-cached-calc-cb-mnmerkleroot");
     119             :             }
     120       36412 :             return true;
     121             :         }
     122             : 
     123          58 :         bool mutated = false;
     124          58 :         merkleRootRet = sml->CalcMerkleRoot(&mutated);
     125             : 
     126          58 :         int64_t nTime2 = GetTimeMicros();
     127          58 :         nTimeMerkle += nTime2 - nTime1;
     128          58 :         LogPrint(BCLog::BENCHMARK, "            - CalcMerkleRoot: %.2fms [%.2fs]\n", 0.001 * (nTime2 - nTime1),
     129             :                  nTimeMerkle * 0.000001);
     130             : 
     131          58 :         cached_sml = sml;
     132          58 :         merkleRootCached = merkleRootRet;
     133          58 :         mutatedCached = mutated;
     134             : 
     135          58 :         if (mutated) {
     136           0 :             return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "mutated-calc-cb-mnmerkleroot");
     137             :         }
     138             : 
     139          58 :         return true;
     140       36470 :     } catch (const std::exception& e) {
     141           0 :         LogPrintf("%s -- failed: %s\n", __func__, e.what());
     142           0 :         return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "failed-calc-cb-mnmerkleroot");
     143           0 :     }
     144       36470 : }

Generated by: LCOV version 1.16