Line data Source code
1 : // Copyright (c) 2018-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 : #ifndef BITCOIN_LLMQ_DKGSESSIONMGR_H 6 : #define BITCOIN_LLMQ_DKGSESSIONMGR_H 7 : 8 : #include <bls/bls.h> 9 : #include <chainparams.h> 10 : #include <consensus/params.h> 11 : #include <sync.h> 12 : #include <util/check.h> 13 : #include <util/helpers.h> 14 : 15 : #include <map> 16 : #include <memory> 17 : 18 : template <class T> 19 : class CBLSIESMultiRecipientObjects; 20 : template <class T> 21 : class CBLSIESEncryptedObject; 22 : 23 : class CBlockIndex; 24 : class CDBWrapper; 25 : class CDeterministicMNManager; 26 : class ChainstateManager; 27 : class CSporkManager; 28 : namespace util { 29 : struct DbWrapperParams; 30 : } // namespace util 31 : 32 : namespace llmq 33 : { 34 : class CDKGComplaint; 35 : class CDKGContribution; 36 : class CDKGJustification; 37 : class CDKGPrematureCommitment; 38 : class CDKGSessionHandler; 39 : class CQuorumSnapshotManager; 40 : 41 : class CDKGSessionManager 42 : { 43 : public: 44 : struct SessionHandlerKey { 45 : Consensus::LLMQType llmq_type; 46 : int quorum_idx; 47 59224 : auto operator<=>(const SessionHandlerKey&) const = default; 48 : }; 49 : 50 : using SessionHandlerMap = std::map<SessionHandlerKey, std::unique_ptr<CDKGSessionHandler>>; 51 : 52 : private: 53 : static constexpr auto MAX_CONTRIBUTION_CACHE_TIME = 60s; 54 : 55 : private: 56 : CDeterministicMNManager& m_dmnman; 57 : CQuorumSnapshotManager& m_qsnapman; 58 : const ChainstateManager& m_chainman; 59 : const CSporkManager& m_sporkman; 60 : 61 : private: 62 : std::unique_ptr<CDBWrapper> db{nullptr}; 63 : 64 : SessionHandlerMap dkgSessionHandlers; 65 : 66 : mutable Mutex contributionsCacheCs; 67 : struct ContributionsCacheKey { 68 : Consensus::LLMQType llmqType; 69 : uint256 quorumHash; 70 : uint256 proTxHash; 71 279947 : bool operator<(const ContributionsCacheKey& r) const 72 : { 73 279947 : if (llmqType != r.llmqType) return llmqType < r.llmqType; 74 235943 : if (quorumHash != r.quorumHash) return quorumHash < r.quorumHash; 75 151997 : return proTxHash < r.proTxHash; 76 279947 : } 77 : }; 78 7651 : struct ContributionsCacheEntry { 79 : SteadyClock::time_point entryTime; 80 : BLSVerificationVectorPtr vvec; 81 : CBLSSecretKey skContribution; 82 : }; 83 : mutable std::map<ContributionsCacheKey, ContributionsCacheEntry> contributionsCache GUARDED_BY(contributionsCacheCs); 84 : 85 : public: 86 : CDKGSessionManager() = delete; 87 : CDKGSessionManager(const CDKGSessionManager&) = delete; 88 : CDKGSessionManager& operator=(const CDKGSessionManager&) = delete; 89 : explicit CDKGSessionManager(CDeterministicMNManager& dmnman, CQuorumSnapshotManager& qsnapman, 90 : const ChainstateManager& chainman, const CSporkManager& sporkman, 91 : const util::DbWrapperParams& db_params); 92 : ~CDKGSessionManager(); 93 : 94 : template <typename HandlerFn> 95 666 : void InitializeHandlers(HandlerFn&& handler_fn) 96 : { 97 : // TODO: move it to cpp file and drop chainparams.h and helpers.h 98 666 : const Consensus::Params& consensus_params = Params().GetConsensus(); 99 3996 : for (const auto& params : consensus_params.llmqs) { 100 3330 : auto session_count = (params.useRotation) ? params.signingActiveQuorumCount : 1; 101 7326 : for (const auto i : util::irange(session_count)) { 102 3996 : dkgSessionHandlers.emplace(SessionHandlerKey{params.type, i}, handler_fn(params, i)); 103 : } 104 : } 105 666 : } 106 : 107 : /** 108 : * Visit every registered handler with @p fn(CDKGSessionHandler&). Used by 109 : * the DKG NetHandler to drive per-handler phase threads. 110 : */ 111 : template <typename HandlerFn> 112 44667 : void ForEachHandler(HandlerFn&& fn) 113 : { 114 312669 : for (auto& [_, handler] : dkgSessionHandlers) { 115 536004 : fn(*Assert(handler)); 116 : } 117 44667 : } 118 : 119 : /** 120 : * Invoke @p fn(CDKGSessionHandler&) for the handler registered under @p key, 121 : * if one exists. Returns true iff the handler was found (and the callback ran). 122 : * Returning the handler by reference inside the callback prevents callers from 123 : * keeping a dangling pointer outside the handler's lifetime. 124 : */ 125 : template <typename HandlerFn> 126 13100 : bool DoForHandler(const SessionHandlerKey& key, HandlerFn&& fn) 127 : { 128 13100 : auto it = dkgSessionHandlers.find(key); 129 13100 : if (it == dkgSessionHandlers.end()) return false; 130 13100 : fn(*Assert(it->second)); 131 13100 : return true; 132 13100 : } 133 : 134 : void UpdatedBlockTip(const CBlockIndex* pindexNew, bool fInitialDownload) 135 : EXCLUSIVE_LOCKS_REQUIRED(!contributionsCacheCs); 136 : 137 : bool GetContribution(const uint256& hash, CDKGContribution& ret) const; 138 : bool GetComplaint(const uint256& hash, CDKGComplaint& ret) const; 139 : bool GetJustification(const uint256& hash, CDKGJustification& ret) const; 140 : bool GetPrematureCommitment(const uint256& hash, CDKGPrematureCommitment& ret) const; 141 : 142 : // Contributions are written while in the DKG 143 : void WriteVerifiedVvecContribution(Consensus::LLMQType llmqType, const CBlockIndex* pQuorumBaseBlockIndex, const uint256& proTxHash, const BLSVerificationVectorPtr& vvec); 144 : void WriteVerifiedSkContribution(Consensus::LLMQType llmqType, const CBlockIndex* pQuorumBaseBlockIndex, const uint256& proTxHash, const CBLSSecretKey& skContribution); 145 : bool GetVerifiedContributions(Consensus::LLMQType llmqType, const CBlockIndex* pQuorumBaseBlockIndex, 146 : const std::vector<bool>& validMembers, std::vector<uint16_t>& memberIndexesRet, 147 : std::vector<BLSVerificationVectorPtr>& vvecsRet, 148 : std::vector<CBLSSecretKey>& skContributionsRet) const 149 : EXCLUSIVE_LOCKS_REQUIRED(!contributionsCacheCs); 150 : /// Write encrypted (unverified) DKG contributions for the member with the given proTxHash to the llmqDb 151 : void WriteEncryptedContributions(Consensus::LLMQType llmqType, const CBlockIndex* pQuorumBaseBlockIndex, const uint256& proTxHash, const CBLSIESMultiRecipientObjects<CBLSSecretKey>& contributions); 152 : /// Read encrypted (unverified) DKG contributions for the member with the given proTxHash from the llmqDb 153 : bool GetEncryptedContributions(Consensus::LLMQType llmqType, const CBlockIndex* pQuorumBaseBlockIndex, const std::vector<bool>& validMembers, const uint256& proTxHash, std::vector<CBLSIESEncryptedObject<CBLSSecretKey>>& vecRet) const; 154 : 155 : void CleanupOldContributions() const; 156 : 157 : private: 158 : void CleanupCache() const EXCLUSIVE_LOCKS_REQUIRED(!contributionsCacheCs); 159 : }; 160 : } // namespace llmq 161 : 162 : #endif // BITCOIN_LLMQ_DKGSESSIONMGR_H