Line data Source code
1 : // Copyright (c) 2025-2026 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_LLMQ_NET_QUORUM_H 6 : #define BITCOIN_LLMQ_NET_QUORUM_H 7 : 8 : #include <llmq/options.h> 9 : #include <llmq/quorums.h> 10 : #include <net_processing.h> 11 : #include <sync.h> 12 : #include <unordered_lru_cache.h> 13 : #include <util/threadinterrupt.h> 14 : #include <validationinterface.h> 15 : 16 : #include <ctpl_stl.h> 17 : #include <gsl/pointers.h> 18 : 19 : #include <map> 20 : 21 : class CActiveMasternodeManager; 22 : class CBlockIndex; 23 : class CBLSWorker; 24 : class CConnman; 25 : class CDeterministicMNManager; 26 : class CMasternodeSync; 27 : class CSporkManager; 28 : namespace Consensus { 29 : struct LLMQParams; 30 : } // namespace Consensus 31 : namespace llmq { 32 : class CQuorumManager; 33 : class CQuorumSnapshotManager; 34 : class QuorumRole; 35 : struct UtilParameters; 36 : } // namespace llmq 37 : 38 : namespace llmq { 39 : /** 40 : * NetHandler responsible for all quorum networking: 41 : * - QGETDATA / QDATA message processing (quorum vvec and encrypted contribution exchange) 42 : * - Background quorum peer connection management (CheckQuorumConnections) 43 : * - Background vvec and sk-share data recovery threads 44 : * - Periodic cleanup of old quorum DB entries 45 : * 46 : * Owned exclusively by PeerManagerImpl via AddExtraHandler. No other subsystem 47 : * holds a reference to this object. 48 : */ 49 : class NetQuorum final : public NetHandler, public CValidationInterface 50 : { 51 : public: 52 : NetQuorum(PeerManagerInternal* peer_manager, CBLSWorker& bls_worker, 53 : CConnman& connman, CDeterministicMNManager& dmnman, CQuorumManager& qman, 54 : CQuorumSnapshotManager& qsnapman, const ChainstateManager& chainman, 55 : const CMasternodeSync& mn_sync, const CSporkManager& sporkman, 56 : QuorumRole* quorum_role, CActiveMasternodeManager* nodeman, 57 : int16_t worker_count, const QvvecSyncModeMap& sync_map, bool quorums_recovery); 58 : 59 : // NetHandler 60 : void ProcessMessage(CNode& pfrom, const std::string& msg_type, CDataStream& vRecv) override; 61 : void Start() override; 62 : void Stop() override; 63 0 : void Interrupt() override { quorumThreadInterrupt(); } 64 : 65 : protected: 66 : // CValidationInterface 67 : void InitializeCurrentBlockTip(const CBlockIndex* tip, bool ibd) override; 68 : void UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, 69 : bool fInitialDownload) override; 70 : 71 : private: 72 : DataRequestStatus RequestQuorumData(CNode& peer, const CQuorum& quorum, uint16_t nDataMask, 73 : const uint256& proTxHash = uint256()) const; 74 : 75 : Uint256HashSet GetQuorumsToDelete(const Consensus::LLMQParams& llmqParams, 76 : gsl::not_null<const CBlockIndex*> pindexNew) const; 77 : void CheckQuorumConnections(const Consensus::LLMQParams& llmqParams, 78 : gsl::not_null<const CBlockIndex*> pindexNew) const; 79 : void TriggerQuorumDataRecoveryThreads(gsl::not_null<const CBlockIndex*> block_index) const; 80 : void DataRecoveryThread(gsl::not_null<const CBlockIndex*> block_index, CQuorumCPtr pQuorum, 81 : uint16_t data_mask, const uint256& protx_hash, size_t start_offset) const; 82 : void StartVvecSyncThread(gsl::not_null<const CBlockIndex*> block_index, CQuorumCPtr pQuorum) const; 83 : void TryStartVvecSyncThread(gsl::not_null<const CBlockIndex*> block_index, CQuorumCPtr pQuorum, 84 : bool fWeAreQuorumTypeMember) const; 85 : void StartSkShareRecoveryThread(gsl::not_null<const CBlockIndex*> pIndex, CQuorumCPtr pQuorum, 86 : uint16_t nDataMaskIn) const; 87 : /// Returns the start offset for the masternode with the given proTxHash. This offset is applied when picking data 88 : /// recovery members of a quorum's memberlist and is calculated based on a list of all member of all active quorums 89 : /// for the given llmqType in a way that each member should receive the same number of request if all active 90 : /// llmqType members requests data from one llmqType quorum. 91 : size_t GetQuorumRecoveryStartOffset(const CQuorum& quorum, 92 : gsl::not_null<const CBlockIndex*> pIndex) const; 93 : void StartCleanupOldQuorumDataThread(gsl::not_null<const CBlockIndex*> pIndex) const; 94 : 95 : bool ProcessContribQGETDATA(CDataStream& ssResponseData, const CQuorum& quorum, 96 : CQuorumDataRequest& request, 97 : gsl::not_null<const CBlockIndex*> block_index) const; 98 : bool ProcessContribQDATA(CNode& pfrom, CDataStream& vRecv, 99 : CQuorum& quorum, CQuorumDataRequest& request); 100 : 101 : private: 102 : CBLSWorker& m_bls_worker; 103 : CConnman& m_connman; 104 : CDeterministicMNManager& m_dmnman; 105 : CQuorumManager& m_qman; 106 : CQuorumSnapshotManager& m_qsnapman; 107 : const ChainstateManager& m_chainman; 108 : const CMasternodeSync& m_mn_sync; 109 : const CSporkManager& m_sporkman; 110 : //! Non-null only when masternode or observer mode is active 111 : QuorumRole* const m_role; 112 : //! Non-null only in masternode mode 113 : CActiveMasternodeManager* const m_nodeman; 114 : 115 : const int16_t m_worker_count; 116 : const QvvecSyncModeMap m_sync_map; 117 : const bool m_quorums_recovery; 118 : 119 : mutable Mutex cs_cleanup; 120 : mutable std::map<Consensus::LLMQType, Uint256LruHashMap<uint256>> cleanupQuorumsCache 121 : GUARDED_BY(cs_cleanup); 122 : 123 : mutable ctpl::thread_pool workerPool; 124 : mutable CThreadInterrupt quorumThreadInterrupt; 125 : }; 126 : 127 : bool EnsureQuorumConnections(const Consensus::LLMQParams& llmqParams, CConnman& connman, const CSporkManager& sporkman, 128 : const UtilParameters& util_params, const CDeterministicMNList& tip_mn_list, 129 : const uint256& myProTxHash, bool is_masternode, bool quorums_watch); 130 : 131 : } // namespace llmq 132 : 133 : #endif // BITCOIN_LLMQ_NET_QUORUM_H