LCOV - code coverage report
Current view: top level - src/llmq - ehf_signals.cpp (source / functions) Hit Total Coverage
Test: test_dash_coverage.info Lines: 0 73 0.0 %
Date: 2026-06-25 07:23:51 Functions: 0 12 0.0 %

          Line data    Source code
       1             : // Copyright (c) 2023-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 <llmq/ehf_signals.h>
       6             : 
       7             : #include <chainparams.h>
       8             : #include <consensus/validation.h>
       9             : #include <deploymentstatus.h>
      10             : #include <evo/chainhelper.h>
      11             : #include <evo/mnhftx.h>
      12             : #include <index/txindex.h> // g_txindex
      13             : #include <llmq/commitment.h>
      14             : #include <llmq/quorumsman.h>
      15             : #include <llmq/signing_shares.h>
      16             : #include <primitives/transaction.h>
      17             : #include <validation.h>
      18             : #include <versionbits.h>
      19             : 
      20             : namespace llmq {
      21           0 : CEHFSignalsHandler::CEHFSignalsHandler(ChainstateManager& chainman, CSigningManager& sigman,
      22             :                                        CSigSharesManager& shareman, const CQuorumManager& qman) :
      23           0 :     m_chainman(chainman),
      24           0 :     sigman(sigman),
      25           0 :     shareman(shareman),
      26           0 :     qman(qman)
      27           0 : {
      28           0 :     sigman.RegisterRecoveredSigsListener(this);
      29           0 : }
      30             : 
      31           0 : CEHFSignalsHandler::~CEHFSignalsHandler()
      32           0 : {
      33           0 :     sigman.UnregisterRecoveredSigsListener(this);
      34           0 : }
      35             : 
      36           0 : void CEHFSignalsHandler::UpdatedBlockTip(const CBlockIndex* const pindexNew)
      37             : {
      38           0 :     if (!DeploymentActiveAfter(pindexNew, Params().GetConsensus(), Consensus::DEPLOYMENT_V20)) return;
      39             : 
      40           0 :     const auto ehfSignals = m_chainman.ActiveChainstate().ChainHelper().ehf_manager->GetSignalsStage(pindexNew);
      41           0 :     for (const auto& deployment : Params().GetConsensus().vDeployments) {
      42             :         // Skip deployments that do not use dip0023
      43           0 :         if (!deployment.useEHF) continue;
      44             :         // Try to sign only activable deployments that haven't been mined yet
      45           0 :         if (ehfSignals.find(deployment.bit) == ehfSignals.end() && Params().IsValidMNActivation(deployment.bit, pindexNew->GetMedianTimePast())) {
      46           0 :             trySignEHFSignal(deployment.bit, pindexNew);
      47           0 :         }
      48             :     }
      49           0 : }
      50             : 
      51           0 : void CEHFSignalsHandler::trySignEHFSignal(int bit, const CBlockIndex* const pindex)
      52             : {
      53           0 :     MNHFTxPayload mnhfPayload;
      54           0 :     mnhfPayload.signal.versionBit = bit;
      55           0 :     const uint256 requestId = mnhfPayload.GetRequestId();
      56             : 
      57           0 :     const Consensus::LLMQType& llmqType = Params().GetConsensus().llmqTypeMnhf;
      58           0 :     const auto& llmq_params_opt = Params().GetLLMQ(llmqType);
      59           0 :     if (!llmq_params_opt.has_value()) {
      60           0 :         return;
      61             :     }
      62           0 :     if (sigman.HasRecoveredSigForId(llmqType, requestId)) {
      63           0 :         WITH_LOCK(cs, ids.insert(requestId));
      64             : 
      65           0 :         LogPrint(BCLog::EHF, "CEHFSignalsHandler::trySignEHFSignal: already signed bit=%d at height=%d id=%s\n", bit, pindex->nHeight, requestId.ToString());
      66             :         // no need to sign same message one more time
      67           0 :         return;
      68             :     }
      69             : 
      70           0 :     const auto quorum = llmq::SelectQuorumForSigning(llmq_params_opt.value(), m_chainman.ActiveChain(), qman, requestId);
      71           0 :     if (!quorum) {
      72           0 :         LogPrintf("CEHFSignalsHandler::trySignEHFSignal no quorum for id=%s\n", requestId.ToString());
      73           0 :         return;
      74             :     }
      75             : 
      76           0 :     LogPrint(BCLog::EHF, "CEHFSignalsHandler::trySignEHFSignal: bit=%d at height=%d id=%s\n", bit, pindex->nHeight, requestId.ToString());
      77           0 :     mnhfPayload.signal.quorumHash = quorum->qc->quorumHash;
      78           0 :     const uint256 msgHash = mnhfPayload.PrepareTx().GetHash();
      79             : 
      80           0 :     WITH_LOCK(cs, ids.insert(requestId));
      81           0 :     shareman.AsyncSignIfMember(llmqType, sigman, requestId, msgHash, quorum->qc->quorumHash, false, true);
      82           0 : }
      83             : 
      84           0 : RecoveredSigResult CEHFSignalsHandler::HandleNewRecoveredSig(const CRecoveredSig& recoveredSig)
      85             : {
      86           0 :     if (g_txindex) {
      87           0 :         g_txindex->BlockUntilSyncedToCurrentChain();
      88           0 :     }
      89             : 
      90           0 :     if (WITH_LOCK(cs, return ids.find(recoveredSig.getId()) == ids.end())) {
      91             :         // Do nothing, it's not for this handler
      92           0 :         return std::monostate{};
      93             :     }
      94             : 
      95           0 :     const auto ehfSignals = m_chainman.ActiveChainstate().ChainHelper().ehf_manager->GetSignalsStage(
      96           0 :         WITH_LOCK(::cs_main, return m_chainman.ActiveTip()));
      97           0 :     MNHFTxPayload mnhfPayload;
      98           0 :     for (const auto& deployment : Params().GetConsensus().vDeployments) {
      99             :         // skip deployments that do not use dip0023 or that have already been mined
     100           0 :         if (!deployment.useEHF || ehfSignals.find(deployment.bit) != ehfSignals.end()) continue;
     101             : 
     102           0 :         mnhfPayload.signal.versionBit = deployment.bit;
     103           0 :         const uint256 expectedId = mnhfPayload.GetRequestId();
     104           0 :         LogPrint(BCLog::EHF, "CEHFSignalsHandler::HandleNewRecoveredSig expecting ID=%s received=%s\n", expectedId.ToString(), recoveredSig.getId().ToString());
     105           0 :         if (recoveredSig.getId() != expectedId) {
     106             :             // wrong deployment! Check the next one
     107           0 :             continue;
     108             :         }
     109             : 
     110           0 :         mnhfPayload.signal.quorumHash = recoveredSig.getQuorumHash();
     111           0 :         mnhfPayload.signal.sig = recoveredSig.sig.Get();
     112             : 
     113           0 :         CMutableTransaction tx = mnhfPayload.PrepareTx();
     114             : 
     115           0 :         CTransactionRef tx_to_sent = MakeTransactionRef(std::move(tx));
     116           0 :         LogPrintf("CEHFSignalsHandler::HandleNewRecoveredSig Special EHF TX is created hash=%s\n",
     117             :                   tx_to_sent->GetHash().ToString());
     118           0 :         LOCK(::cs_main);
     119           0 :         const MempoolAcceptResult result = m_chainman.ProcessTransaction(tx_to_sent);
     120           0 :         if (result.m_result_type == MempoolAcceptResult::ResultType::VALID) {
     121           0 :             return tx_to_sent;
     122             :         }
     123           0 :         LogPrintf("CEHFSignalsHandler::HandleNewRecoveredSig -- AcceptToMemoryPool failed: %s\n",
     124             :                   result.m_state.ToString());
     125           0 :         return std::monostate{};
     126           0 :     }
     127           0 :     return std::monostate{};
     128           0 : }
     129             : } // namespace llmq

Generated by: LCOV version 1.16