LCOV - code coverage report
Current view: top level - src/evo - mnhftx.h (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 13 13 100.0 %
Date: 2026-06-25 07:23:43 Functions: 28 28 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2021-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             : #ifndef BITCOIN_EVO_MNHFTX_H
       6             : #define BITCOIN_EVO_MNHFTX_H
       7             : 
       8             : #include <saltedhasher.h>
       9             : #include <sync.h>
      10             : #include <threadsafety.h>
      11             : #include <versionbits.h>
      12             : 
      13             : #include <bls/bls.h>
      14             : #include <unordered_lru_cache.h>
      15             : 
      16             : #include <gsl/pointers.h>
      17             : #include <univalue.h>
      18             : 
      19             : #include <optional>
      20             : 
      21             : class BlockValidationState;
      22             : class CBlock;
      23             : class CBlockIndex;
      24             : class CEvoDB;
      25             : class CTransaction;
      26             : class ChainstateManager;
      27             : class TxValidationState;
      28             : struct RPCResult;
      29             : namespace llmq {
      30             : class CQuorumManager;
      31             : }
      32             : 
      33             : // mnhf signal special transaction
      34             : class MNHFTx
      35             : {
      36             : public:
      37       26144 :     uint8_t versionBit{0};
      38       26144 :     uint256 quorumHash{0};
      39       26144 :     CBLSSignature sig{};
      40             : 
      41       78432 :     MNHFTx() = default;
      42             :     bool Verify(const llmq::CQuorumManager& qman, const uint256& quorumHash, const uint256& requestId, const uint256& msgHash,
      43             :                 TxValidationState& state) const;
      44             : 
      45       19875 :     SERIALIZE_METHODS(MNHFTx, obj)
      46             :     {
      47        6625 :         READWRITE(obj.versionBit, obj.quorumHash);
      48        6625 :         READWRITE(CBLSSignatureVersionWrapper(const_cast<CBLSSignature&>(obj.sig), /*legacy=*/false));
      49        6625 :     }
      50             : 
      51             :     std::string ToString() const;
      52             : 
      53             :     [[nodiscard]] static RPCResult GetJsonHelp(const std::string& key, bool optional);
      54             :     [[nodiscard]] UniValue ToJson() const;
      55             : };
      56             : 
      57       26144 : class MNHFTxPayload
      58             : {
      59             : public:
      60             :     static constexpr auto SPECIALTX_TYPE = TRANSACTION_MNHF_SIGNAL;
      61             :     static constexpr uint16_t CURRENT_VERSION = 1;
      62             : 
      63       26144 :     uint8_t nVersion{CURRENT_VERSION};
      64             :     MNHFTx signal;
      65             : 
      66             : public:
      67             :     /**
      68             :      * helper function to calculate Request ID used for signing
      69             :      */
      70             :     uint256 GetRequestId() const;
      71             : 
      72             :     /**
      73             :      * helper function to prepare special transaction for signing
      74             :      */
      75             :     CMutableTransaction PrepareTx() const;
      76             : 
      77       19875 :     SERIALIZE_METHODS(MNHFTxPayload, obj)
      78             :     {
      79        6625 :         READWRITE(obj.nVersion, obj.signal);
      80        6625 :     }
      81             : 
      82             :     std::string ToString() const;
      83             : 
      84             :     [[nodiscard]] static RPCResult GetJsonHelp(const std::string& key, bool optional);
      85             :     [[nodiscard]] UniValue ToJson() const;
      86             : };
      87             : 
      88             : class CMNHFManager : public AbstractEHFManager
      89             : {
      90             : private:
      91             :     CEvoDB& m_evoDb;
      92             :     // TODO: move its functionallity of ProcessBlock, UndoBlock to specialtxman;
      93             :     // it will help to drop dependency on m_chainman, m_qman here (and validation.h)
      94             :     // Secondly, store in database active EHF signals not for each block;
      95             :     // but quite opposite: keep only hash of block where signal is added.
      96             :     // TODO: implement migration to a new format
      97             :     const ChainstateManager& m_chainman;
      98             :     const llmq::CQuorumManager& m_qman;
      99             : 
     100             :     static constexpr size_t MNHFCacheSize = 1000;
     101             :     Mutex cs_cache;
     102             :     // versionBit <-> height
     103             :     Uint256LruHashMap<Signals> mnhfCache GUARDED_BY(cs_cache){MNHFCacheSize};
     104             : 
     105             : public:
     106             :     CMNHFManager() = delete;
     107             :     CMNHFManager(const CMNHFManager&) = delete;
     108             :     CMNHFManager& operator=(const CMNHFManager&) = delete;
     109             :     explicit CMNHFManager(CEvoDB& evoDb, const ChainstateManager& chainman, const llmq::CQuorumManager& qman);
     110             :     ~CMNHFManager();
     111             : 
     112             :     /**
     113             :      * Every new block should be processed when Tip() is updated by calling of CMNHFManager::ProcessBlock.
     114             :      * This function actually does only validate EHF transaction for this block and update internal caches/evodb state
     115             :      */
     116             :     std::optional<Signals> ProcessBlock(const CBlock& block, const CBlockIndex* const pindex, bool fJustCheck,
     117             :                                         BlockValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(!cs_cache);
     118             : 
     119             :     /**
     120             :      * Every undo block should be processed when Tip() is updated by calling of CMNHFManager::UndoBlock
     121             :      * This function actually does nothing at the moment, because status of ancestor block is already known.
     122             :      * Although it should be still called to do some sanity checks
     123             :      */
     124             :     bool UndoBlock(const CBlock& block, const CBlockIndex* const pindex) EXCLUSIVE_LOCKS_REQUIRED(!cs_cache);
     125             : 
     126             :     // Implements interface
     127             :     Signals GetSignalsStage(const CBlockIndex* const pindexPrev) override EXCLUSIVE_LOCKS_REQUIRED(!cs_cache);
     128             : 
     129             :     /**
     130             :      * Helper that used in Unit Test to forcely setup EHF signal for specific block
     131             :      */
     132             :     void AddSignal(const CBlockIndex* const pindex, int bit) EXCLUSIVE_LOCKS_REQUIRED(!cs_cache);
     133             : 
     134             :     bool ForceSignalDBUpdate() EXCLUSIVE_LOCKS_REQUIRED(::cs_main, !cs_cache);
     135             : 
     136             : private:
     137             :     void AddToCache(const Signals& signals, const CBlockIndex* const pindex) EXCLUSIVE_LOCKS_REQUIRED(!cs_cache);
     138             : 
     139             :     /**
     140             :      * This function returns list of signals available on previous block.
     141             :      * if the signals for previous block is not available in cache it would read blocks from disk
     142             :      * until state won't be recovered.
     143             :      * NOTE: that some signals could expired between blocks.
     144             :      */
     145             :     Signals GetForBlock(const CBlockIndex* const pindex) EXCLUSIVE_LOCKS_REQUIRED(!cs_cache);
     146             : 
     147             :     /**
     148             :      * This function access to in-memory cache or to evo db but does not calculate anything
     149             :      * NOTE: that some signals could expired between blocks.
     150             :      */
     151             :     std::optional<Signals> GetFromCache(const CBlockIndex* const pindex) EXCLUSIVE_LOCKS_REQUIRED(!cs_cache);
     152             : };
     153             : 
     154             : std::optional<uint8_t> extractEHFSignal(const CTransaction& tx);
     155             : bool CheckMNHFTx(const ChainstateManager& chainman, const llmq::CQuorumManager& qman, const CTransaction& tx, const CBlockIndex* pindexPrev, TxValidationState& state);
     156             : 
     157             : #endif // BITCOIN_EVO_MNHFTX_H

Generated by: LCOV version 1.16