LCOV - code coverage report
Current view: top level - src/instantsend - instantsend.h (source / functions) Hit Total Coverage
Test: test_dash_coverage.info Lines: 0 7 0.0 %
Date: 2026-06-25 07:23:51 Functions: 0 22 0.0 %

          Line data    Source code
       1             : // Copyright (c) 2019-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_INSTANTSEND_INSTANTSEND_H
       6             : #define BITCOIN_INSTANTSEND_INSTANTSEND_H
       7             : 
       8             : #include <instantsend/db.h>
       9             : #include <instantsend/lock.h>
      10             : 
      11             : #include <net_types.h>
      12             : #include <protocol.h>
      13             : #include <saltedhasher.h>
      14             : #include <sync.h>
      15             : #include <threadsafety.h>
      16             : #include <unordered_lru_cache.h>
      17             : 
      18             : #include <optional>
      19             : #include <vector>
      20             : 
      21             : class CBlockIndex;
      22             : class CDataStream;
      23             : class CSporkManager;
      24             : namespace Consensus {
      25             : struct LLMQParams;
      26             : } // namespace Consensus
      27             : namespace util {
      28             : struct DbWrapperParams;
      29             : } // namespace util
      30             : typedef std::shared_ptr<const CTransaction> CTransactionRef;
      31             : 
      32             : namespace instantsend {
      33             : 
      34             : struct PendingISLockFromPeer {
      35             :     NodeId node_id;
      36             :     InstantSendLockPtr islock;
      37             : };
      38             : 
      39             : struct PendingISLockEntry : PendingISLockFromPeer {
      40             :     uint256 islock_hash;
      41             : };
      42             : 
      43           0 : struct PendingState {
      44           0 :     bool m_pending_work{false};
      45             :     std::vector<PendingISLockEntry> m_pending_is;
      46             : };
      47             : } // namespace instantsend
      48             : 
      49             : namespace llmq {
      50             : 
      51             : class CInstantSendManager
      52             : {
      53             : private:
      54             :     instantsend::CInstantSendDb db;
      55             :     CSporkManager& spork_manager;
      56             : 
      57             :     mutable Mutex cs_pendingLocks;
      58             :     // Incoming and not verified yet
      59             :     Uint256HashMap<instantsend::PendingISLockFromPeer> pendingInstantSendLocks GUARDED_BY(cs_pendingLocks);
      60             :     // Tried to verify but there is no tx yet
      61             :     Uint256HashMap<instantsend::PendingISLockFromPeer> pendingNoTxInstantSendLocks GUARDED_BY(cs_pendingLocks);
      62             : 
      63             :     // TXs which are neither IS locked nor ChainLocked. We use this to determine for which TXs we need to retry IS
      64             :     // locking of child TXs
      65             :     struct NonLockedTxInfo {
      66             :         const CBlockIndex* pindexMined;
      67             :         CTransactionRef tx;
      68             :         Uint256HashSet children;
      69             :     };
      70             : 
      71             :     mutable Mutex cs_nonLocked;
      72             :     Uint256HashMap<NonLockedTxInfo> nonLockedTxs GUARDED_BY(cs_nonLocked);
      73             :     std::unordered_map<COutPoint, uint256, SaltedOutpointHasher> nonLockedTxsByOutpoints GUARDED_BY(cs_nonLocked);
      74             : 
      75             :     mutable Mutex cs_pendingRetry;
      76             :     Uint256HashSet pendingRetryTxs GUARDED_BY(cs_pendingRetry);
      77             : 
      78             :     mutable Mutex cs_timingsTxSeen;
      79             :     Uint256HashMap<SteadyClock::time_point> timingsTxSeen GUARDED_BY(cs_timingsTxSeen);
      80             : 
      81             :     mutable Mutex cs_height_cache;
      82             :     static constexpr size_t MAX_BLOCK_HEIGHT_CACHE{16384};
      83             :     mutable unordered_lru_cache<uint256, int, StaticSaltedHasher, MAX_BLOCK_HEIGHT_CACHE> m_cached_block_heights
      84             :         GUARDED_BY(cs_height_cache);
      85             :     mutable int m_cached_tip_height GUARDED_BY(cs_height_cache){-1};
      86             : 
      87             : public:
      88             :     CInstantSendManager() = delete;
      89             :     CInstantSendManager(const CInstantSendManager&) = delete;
      90             :     CInstantSendManager& operator=(const CInstantSendManager&) = delete;
      91             :     explicit CInstantSendManager(CSporkManager& sporkman, const util::DbWrapperParams& db_params);
      92             :     ~CInstantSendManager();
      93             : 
      94             :     void AddNonLockedTx(const CTransactionRef& tx, const CBlockIndex* pindexMined)
      95             :         EXCLUSIVE_LOCKS_REQUIRED(!cs_nonLocked, !cs_pendingLocks, !cs_timingsTxSeen);
      96             :     void RemoveNonLockedTx(const uint256& txid, bool retryChildren)
      97             :         EXCLUSIVE_LOCKS_REQUIRED(!cs_nonLocked, !cs_pendingRetry);
      98             : 
      99             :     instantsend::InstantSendLockPtr AttachISLockToTx(const CTransactionRef& tx) EXCLUSIVE_LOCKS_REQUIRED(!cs_pendingLocks);
     100             : 
     101             :     std::unordered_map<const CBlockIndex*, Uint256HashMap<CTransactionRef>> RetrieveISConflicts(
     102             :         const uint256& islockHash, const instantsend::InstantSendLock& islock)
     103             :         EXCLUSIVE_LOCKS_REQUIRED(!cs_nonLocked, !cs_pendingLocks);
     104             :     bool HasTxForLock(const uint256& islockHash) const EXCLUSIVE_LOCKS_REQUIRED(!cs_pendingLocks);
     105             : 
     106             :     bool IsLocked(const uint256& txHash) const;
     107             :     bool IsWaitingForTx(const uint256& txHash) const EXCLUSIVE_LOCKS_REQUIRED(!cs_pendingLocks);
     108             :     instantsend::InstantSendLockPtr GetConflictingLock(const CTransaction& tx) const;
     109             : 
     110             :     /* Helpers for communications between CInstantSendManager & NetInstantSend */
     111             :     // This helper returns up to 32 pending locks and remove them from queue of pending
     112             :     [[nodiscard]] instantsend::PendingState FetchPendingLocks() EXCLUSIVE_LOCKS_REQUIRED(!cs_pendingLocks);
     113             :     void EnqueueInstantSendLock(NodeId from, const uint256& hash, std::shared_ptr<instantsend::InstantSendLock> islock)
     114             :         EXCLUSIVE_LOCKS_REQUIRED(!cs_pendingLocks);
     115             :     [[nodiscard]] std::vector<CTransactionRef> PrepareTxToRetry()
     116             :         EXCLUSIVE_LOCKS_REQUIRED(!cs_nonLocked, !cs_pendingRetry);
     117             : 
     118             :     void RemoveBlockISLocks(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindex);
     119             :     void WriteBlockISLocks(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindex);
     120             :     void WriteNewISLock(const uint256& hash, const instantsend::InstantSendLockPtr& islock, std::optional<int> minedHeight);
     121             :     void AddPendingISLock(const uint256& hash, const instantsend::InstantSendLockPtr& islock, NodeId from)
     122             :         EXCLUSIVE_LOCKS_REQUIRED(!cs_pendingLocks);
     123             : 
     124             :     bool PreVerifyIsLock(const uint256& hash, const instantsend::InstantSendLockPtr& islock, NodeId from) const;
     125             : 
     126             :     bool AlreadyHave(const CInv& inv) const EXCLUSIVE_LOCKS_REQUIRED(!cs_pendingLocks);
     127             :     bool GetInstantSendLockByHash(const uint256& hash, instantsend::InstantSendLock& ret) const
     128             :         EXCLUSIVE_LOCKS_REQUIRED(!cs_pendingLocks);
     129             :     instantsend::InstantSendLockPtr GetInstantSendLockByTxid(const uint256& txid) const;
     130             : 
     131             :     void TransactionIsRemoved(const CTransactionRef& tx) EXCLUSIVE_LOCKS_REQUIRED(!cs_height_cache);
     132             :     void RemoveConflictingLock(const uint256& islockHash, const instantsend::InstantSendLock& islock)
     133             :         EXCLUSIVE_LOCKS_REQUIRED(!cs_height_cache);
     134             :     void TryEmplacePendingLock(const uint256& hash, const NodeId id, const instantsend::InstantSendLockPtr& islock)
     135             :         EXCLUSIVE_LOCKS_REQUIRED(!cs_pendingLocks);
     136             : 
     137             :     size_t GetInstantSendLockCount() const;
     138             : 
     139           0 :     struct Counts {
     140           0 :         size_t m_verified{0};
     141           0 :         size_t m_unverified{0};
     142           0 :         size_t m_awaiting_tx{0};
     143           0 :         size_t m_unprotected_tx{0};
     144             :     };
     145             :     Counts GetCounts() const EXCLUSIVE_LOCKS_REQUIRED(!cs_pendingLocks, !cs_nonLocked);
     146             : 
     147             :     void CacheBlockHeight(const CBlockIndex* const block_index) const EXCLUSIVE_LOCKS_REQUIRED(!cs_height_cache);
     148             :     void CacheDisconnectBlock(const CBlockIndex* pindexDisconnected) EXCLUSIVE_LOCKS_REQUIRED(!cs_height_cache);
     149             :     std::optional<int> GetCachedHeight(const uint256& hash) const EXCLUSIVE_LOCKS_REQUIRED(!cs_height_cache);
     150             :     void CacheTipHeight(const CBlockIndex* const tip) const EXCLUSIVE_LOCKS_REQUIRED(!cs_height_cache);
     151             :     int GetTipHeight() const EXCLUSIVE_LOCKS_REQUIRED(!cs_height_cache);
     152             : 
     153             :     bool IsInstantSendEnabled() const;
     154             :     Uint256HashMap<instantsend::InstantSendLockPtr> RemoveConfirmedInstantSendLocks(const CBlockIndex* pindex)
     155             :         EXCLUSIVE_LOCKS_REQUIRED(!cs_nonLocked, !cs_pendingRetry);
     156             : };
     157             : } // namespace llmq
     158             : 
     159             : #endif // BITCOIN_INSTANTSEND_INSTANTSEND_H

Generated by: LCOV version 1.16