From 3161546100d530ef7045a2dfdcc5d4890093fb31 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Sat, 28 Dec 2024 09:38:51 +0000 Subject: [PATCH 01/11] refactor: use `GetNodeContext` to access `LLMQContext` members in REST --- src/rest.cpp | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/src/rest.cpp b/src/rest.cpp index 961891c49b316..027137dcee845 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -132,6 +132,27 @@ static ChainstateManager* GetChainman(const CoreContext& context, HTTPRequest* r return node_context->chainman.get(); } +/** + * Get the node context LLMQContext. + * + * @param[in] req The HTTP request, whose status code will be set if node + * context LLMQContext is not found. + * @returns Pointer to the LLMQContext or nullptr if none found. + */ +static LLMQContext* GetLLMQContext(const CoreContext& context, HTTPRequest* req) +{ + auto node_context = GetContext(context); + if (!node_context || !node_context->llmq_ctx) { + RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, + strprintf("%s:%d (%s)\n" + "Internal bug detected: LLMQ context not found!\n" + "You may report this issue here: %s\n", + __FILE__, __LINE__, __func__, PACKAGE_BUGREPORT)); + return nullptr; + } + return node_context->llmq_ctx.get(); +} + static RetFormat ParseDataFormat(std::string& param, const std::string& strReq) { const std::string::size_type pos = strReq.rfind('.'); @@ -247,9 +268,12 @@ static bool rest_headers(const CoreContext& context, return true; } case RetFormat::JSON: { + const LLMQContext* llmq_ctx = GetLLMQContext(context, req); + if (!llmq_ctx) return false; + UniValue jsonHeaders(UniValue::VARR); for (const CBlockIndex *pindex : headers) { - jsonHeaders.push_back(blockheaderToJSON(tip, pindex, *llmq::chainLocksHandler)); + jsonHeaders.push_back(blockheaderToJSON(tip, pindex, *llmq_ctx->clhandler)); } std::string strJSON = jsonHeaders.write() + "\n"; req->WriteHeader("Content-Type", "application/json"); @@ -317,7 +341,10 @@ static bool rest_block(const CoreContext& context, } case RetFormat::JSON: { - UniValue objBlock = blockToJSON(chainman.m_blockman, block, tip, pblockindex, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, showTxDetails); + const LLMQContext* llmq_ctx = GetLLMQContext(context, req); + if (!llmq_ctx) return false; + + UniValue objBlock = blockToJSON(chainman.m_blockman, block, tip, pblockindex, *llmq_ctx->clhandler, *llmq_ctx->isman, showTxDetails); std::string strJSON = objBlock.write() + "\n"; req->WriteHeader("Content-Type", "application/json"); req->WriteReply(HTTP_OK, strJSON); @@ -580,7 +607,10 @@ static bool rest_mempool_info(const CoreContext& context, HTTPRequest* req, cons switch (rf) { case RetFormat::JSON: { - UniValue mempoolInfoObject = MempoolInfoToJSON(*mempool, *llmq::quorumInstantSendManager); + const LLMQContext* llmq_ctx = GetLLMQContext(context, req); + if (!llmq_ctx) return false; + + UniValue mempoolInfoObject = MempoolInfoToJSON(*mempool, *llmq_ctx->isman); std::string strJSON = mempoolInfoObject.write() + "\n"; req->WriteHeader("Content-Type", "application/json"); @@ -603,7 +633,10 @@ static bool rest_mempool_contents(const CoreContext& context, HTTPRequest* req, switch (rf) { case RetFormat::JSON: { - UniValue mempoolObject = MempoolToJSON(*mempool, llmq::quorumInstantSendManager.get(), true); + const LLMQContext* llmq_ctx = GetLLMQContext(context, req); + if (!llmq_ctx) return false; + + UniValue mempoolObject = MempoolToJSON(*mempool, llmq_ctx->isman, true); std::string strJSON = mempoolObject.write() + "\n"; req->WriteHeader("Content-Type", "application/json"); From 772412a93a564bd22220108152655744c91fbc76 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Thu, 2 Jan 2025 21:21:13 +0000 Subject: [PATCH 02/11] refactor: add passthrough functions to `CChainLocksHandler` --- src/evo/chainhelper.cpp | 29 +++++++++++++++---- src/evo/chainhelper.h | 9 ++++++ src/init.cpp | 2 -- src/node/chainstate.cpp | 5 ++-- src/node/chainstate.h | 2 -- src/test/util/setup_common.cpp | 2 -- src/test/validation_chainstate_tests.cpp | 3 +- .../validation_chainstatemanager_tests.cpp | 11 ++++--- src/test/validation_flush_tests.cpp | 3 +- src/validation.cpp | 15 ++++------ src/validation.h | 3 -- 11 files changed, 46 insertions(+), 38 deletions(-) diff --git a/src/evo/chainhelper.cpp b/src/evo/chainhelper.cpp index 4c6a6ab964694..1408256e310c1 100644 --- a/src/evo/chainhelper.cpp +++ b/src/evo/chainhelper.cpp @@ -6,14 +6,31 @@ #include #include +#include #include -CChainstateHelper::CChainstateHelper(CCreditPoolManager& cpoolman, CDeterministicMNManager& dmnman, CMNHFManager& mnhfman, CGovernanceManager& govman, - llmq::CQuorumBlockProcessor& qblockman, const ChainstateManager& chainman, const Consensus::Params& consensus_params, - const CMasternodeSync& mn_sync, const CSporkManager& sporkman, const llmq::CChainLocksHandler& clhandler, - const llmq::CQuorumManager& qman) - : mn_payments{std::make_unique(dmnman, govman, chainman, consensus_params, mn_sync, sporkman)}, - special_tx{std::make_unique(cpoolman, dmnman, mnhfman, qblockman, chainman, consensus_params, clhandler, qman)} +CChainstateHelper::CChainstateHelper(CCreditPoolManager& cpoolman, CDeterministicMNManager& dmnman, CMNHFManager& mnhfman, + CGovernanceManager& govman, llmq::CQuorumBlockProcessor& qblockman, + const ChainstateManager& chainman, const Consensus::Params& consensus_params, + const CMasternodeSync& mn_sync, const CSporkManager& sporkman, + const llmq::CChainLocksHandler& clhandler, const llmq::CQuorumManager& qman) : + clhandler{clhandler}, + mn_payments{std::make_unique(dmnman, govman, chainman, consensus_params, mn_sync, sporkman)}, + special_tx{std::make_unique(cpoolman, dmnman, mnhfman, qblockman, chainman, consensus_params, + clhandler, qman)} {} CChainstateHelper::~CChainstateHelper() = default; + +/** Passthrough functions to CChainLocksHandler */ +bool CChainstateHelper::HasConflictingChainLock(int nHeight, const uint256& blockHash) const +{ + return clhandler.HasConflictingChainLock(nHeight, blockHash); +} + +bool CChainstateHelper::HasChainLock(int nHeight, const uint256& blockHash) const +{ + return clhandler.HasChainLock(nHeight, blockHash); +} + +int32_t CChainstateHelper::GetBestChainLockHeight() const { return clhandler.GetBestChainLock().getHeight(); } diff --git a/src/evo/chainhelper.h b/src/evo/chainhelper.h index 73db5b3427e6a..5ca4b7a1b0ea6 100644 --- a/src/evo/chainhelper.h +++ b/src/evo/chainhelper.h @@ -16,6 +16,7 @@ class CMasternodeSync; class CGovernanceManager; class CSpecialTxProcessor; class CSporkManager; +class uint256; namespace Consensus { struct Params; } namespace llmq { @@ -26,6 +27,9 @@ class CQuorumManager; class CChainstateHelper { +private: + const llmq::CChainLocksHandler& clhandler; + public: explicit CChainstateHelper(CCreditPoolManager& cpoolman, CDeterministicMNManager& dmnman, CMNHFManager& mnhfman, CGovernanceManager& govman, llmq::CQuorumBlockProcessor& qblockman, const ChainstateManager& chainman, const Consensus::Params& consensus_params, @@ -36,6 +40,11 @@ class CChainstateHelper CChainstateHelper() = delete; CChainstateHelper(const CChainstateHelper&) = delete; + /** Passthrough functions to CChainLocksHandler */ + bool HasConflictingChainLock(int nHeight, const uint256& blockHash) const; + bool HasChainLock(int nHeight, const uint256& blockHash) const; + int32_t GetBestChainLockHeight() const; + public: const std::unique_ptr mn_payments; const std::unique_ptr special_tx; diff --git a/src/init.cpp b/src/init.cpp index 24bef37c05b47..126cfab9360ad 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -99,7 +99,6 @@ #include #include #include -#include #include #include #include @@ -1858,7 +1857,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) node.dmnman, node.evodb, node.mnhf_manager, - llmq::chainLocksHandler, llmq::quorumInstantSendManager, llmq::quorumSnapshotManager, node.llmq_ctx, diff --git a/src/node/chainstate.cpp b/src/node/chainstate.cpp index beeee67477d88..62803e1dff8ea 100644 --- a/src/node/chainstate.cpp +++ b/src/node/chainstate.cpp @@ -4,6 +4,7 @@ #include +#include #include #include #include @@ -14,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -31,7 +31,6 @@ std::optional LoadChainstate(bool fReset, std::unique_ptr& dmnman, std::unique_ptr& evodb, std::unique_ptr& mnhf_manager, - std::unique_ptr& clhandler, std::unique_ptr& isman, std::unique_ptr& qsnapman, std::unique_ptr& llmq_ctx, @@ -66,7 +65,7 @@ std::optional LoadChainstate(bool fReset, mnhf_manager.reset(); mnhf_manager = std::make_unique(*evodb); - chainman.InitializeChainstate(mempool, *evodb, chain_helper, clhandler, isman); + chainman.InitializeChainstate(mempool, *evodb, chain_helper, isman); chainman.m_total_coinstip_cache = nCoinCacheUsage; chainman.m_total_coinsdb_cache = nCoinDBCache; diff --git a/src/node/chainstate.h b/src/node/chainstate.h index aa507b5af374d..de20bfbec2aca 100644 --- a/src/node/chainstate.h +++ b/src/node/chainstate.h @@ -26,7 +26,6 @@ class CTxMemPool; struct LLMQContext; namespace llmq { -class CChainLocksHandler; class CInstantSendManager; class CQuorumSnapshotManager; } @@ -93,7 +92,6 @@ std::optional LoadChainstate(bool fReset, std::unique_ptr& dmnman, std::unique_ptr& evodb, std::unique_ptr& mnhf_manager, - std::unique_ptr& clhandler, std::unique_ptr& isman, std::unique_ptr& qsnapman, std::unique_ptr& llmq_ctx, diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index edf088a0392ac..5c8bd3e8b8d0e 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -298,7 +297,6 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector #include #include -#include #include #include #include @@ -43,7 +42,7 @@ BOOST_AUTO_TEST_CASE(validation_chainstate_resize_caches) return outp; }; - CChainState& c1 = WITH_LOCK(cs_main, return manager.InitializeChainstate(&mempool, *m_node.evodb, m_node.chain_helper, llmq::chainLocksHandler, llmq::quorumInstantSendManager)); + CChainState& c1 = WITH_LOCK(cs_main, return manager.InitializeChainstate(&mempool, *m_node.evodb, m_node.chain_helper, llmq::quorumInstantSendManager)); c1.InitCoinsDB( /* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false); WITH_LOCK(::cs_main, c1.InitCoinsCache(1 << 23)); diff --git a/src/test/validation_chainstatemanager_tests.cpp b/src/test/validation_chainstatemanager_tests.cpp index e99f157b95c52..52598c5b6b084 100644 --- a/src/test/validation_chainstatemanager_tests.cpp +++ b/src/test/validation_chainstatemanager_tests.cpp @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include @@ -45,7 +44,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager) // Create a legacy (IBD) chainstate. // - CChainState& c1 = WITH_LOCK(::cs_main, return manager.InitializeChainstate(&mempool, evodb, m_node.chain_helper, llmq::chainLocksHandler, llmq::quorumInstantSendManager)); + CChainState& c1 = WITH_LOCK(::cs_main, return manager.InitializeChainstate(&mempool, evodb, m_node.chain_helper, llmq::quorumInstantSendManager)); chainstates.push_back(&c1); c1.InitCoinsDB( /* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false); @@ -81,7 +80,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager) // const uint256 snapshot_blockhash = GetRandHash(); CChainState& c2 = WITH_LOCK(::cs_main, return manager.InitializeChainstate( - &mempool, evodb, m_node.chain_helper, llmq::chainLocksHandler, llmq::quorumInstantSendManager, + &mempool, evodb, m_node.chain_helper, llmq::quorumInstantSendManager, snapshot_blockhash) ); chainstates.push_back(&c2); @@ -144,7 +143,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager_rebalance_caches) // Create a legacy (IBD) chainstate. // - CChainState& c1 = WITH_LOCK(cs_main, return manager.InitializeChainstate(&mempool, evodb, m_node.chain_helper, llmq::chainLocksHandler, llmq::quorumInstantSendManager)); + CChainState& c1 = WITH_LOCK(cs_main, return manager.InitializeChainstate(&mempool, evodb, m_node.chain_helper, llmq::quorumInstantSendManager)); chainstates.push_back(&c1); c1.InitCoinsDB( /* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false); @@ -162,7 +161,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager_rebalance_caches) // Create a snapshot-based chainstate. // - CChainState& c2 = WITH_LOCK(cs_main, return manager.InitializeChainstate(&mempool, evodb, m_node.chain_helper, llmq::chainLocksHandler, llmq::quorumInstantSendManager, GetRandHash())); + CChainState& c2 = WITH_LOCK(cs_main, return manager.InitializeChainstate(&mempool, evodb, m_node.chain_helper, llmq::quorumInstantSendManager, GetRandHash())); chainstates.push_back(&c2); c2.InitCoinsDB( /* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false); @@ -403,7 +402,7 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_loadblockindex, TestChain100Setup) BOOST_CHECK_EQUAL(expected_assumed_valid, num_assumed_valid); CChainState& cs2 = WITH_LOCK(::cs_main, - return chainman.InitializeChainstate(&mempool, *m_node.evodb, m_node.chain_helper, llmq::chainLocksHandler, llmq::quorumInstantSendManager, GetRandHash())); + return chainman.InitializeChainstate(&mempool, *m_node.evodb, m_node.chain_helper, llmq::quorumInstantSendManager, GetRandHash())); reload_all_block_indexes(); diff --git a/src/test/validation_flush_tests.cpp b/src/test/validation_flush_tests.cpp index 5cb274d7d6c02..33781a4e6f17d 100644 --- a/src/test/validation_flush_tests.cpp +++ b/src/test/validation_flush_tests.cpp @@ -3,7 +3,6 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. // #include -#include #include #include #include @@ -24,7 +23,7 @@ BOOST_AUTO_TEST_CASE(getcoinscachesizestate) CTxMemPool mempool; BlockManager blockman{}; CChainState chainstate(&mempool, blockman, *Assert(m_node.chainman), *m_node.evodb, m_node.chain_helper, - llmq::chainLocksHandler, llmq::quorumInstantSendManager); + llmq::quorumInstantSendManager); chainstate.InitCoinsDB(/*cache_size_bytes*/ 1 << 10, /*in_memory*/ true, /*should_wipe*/ false); WITH_LOCK(::cs_main, chainstate.InitCoinsCache(1 << 10)); diff --git a/src/validation.cpp b/src/validation.cpp index 4bbdc3be5ed45..c419d0a8aaa64 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1523,12 +1523,10 @@ CChainState::CChainState(CTxMemPool* mempool, ChainstateManager& chainman, CEvoDB& evoDb, const std::unique_ptr& chain_helper, - const std::unique_ptr& clhandler, const std::unique_ptr& isman, std::optional from_snapshot_blockhash) : m_mempool(mempool), m_chain_helper(chain_helper), - m_clhandler(clhandler), m_isman(isman), m_evoDb(evoDb), m_blockman(blockman), @@ -2146,7 +2144,6 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, assert(*pindex->phashBlock == block_hash); assert(m_chain_helper); - assert(m_clhandler); assert(m_isman); // Check it again in case a previous version let a bad block in @@ -2172,7 +2169,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, return error("%s: Consensus::CheckBlock: %s", __func__, state.ToString()); } - if (pindex->pprev && pindex->phashBlock && m_clhandler->HasConflictingChainLock(pindex->nHeight, pindex->GetBlockHash())) { + if (pindex->pprev && pindex->phashBlock && m_chain_helper->HasConflictingChainLock(pindex->nHeight, pindex->GetBlockHash())) { LogPrintf("ERROR: %s: conflicting with chainlock\n", __func__); return state.Invalid(BlockValidationResult::BLOCK_CHAINLOCK, "bad-chainlock"); } @@ -2471,7 +2468,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, if (m_isman->RejectConflictingBlocks()) { // Require other nodes to comply, send them some data in case they are missing it. - const bool has_chainlock = m_clhandler->HasChainLock(pindex->nHeight, pindex->GetBlockHash()); + const bool has_chainlock = m_chain_helper->HasChainLock(pindex->nHeight, pindex->GetBlockHash()); for (const auto& tx : block.vtx) { // skip txes that have no inputs if (tx->vin.empty()) continue; @@ -2511,7 +2508,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, int64_t nTime5_3 = GetTimeMicros(); nTimeCreditPool += nTime5_3 - nTime5_2; LogPrint(BCLog::BENCHMARK, " - CheckCreditPoolDiffForBlock: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime5_3 - nTime5_2), nTimeCreditPool * MICRO, nTimeCreditPool * MILLI / nBlocksTotal); - const bool check_superblock = m_clhandler->GetBestChainLock().getHeight() < pindex->nHeight; + const bool check_superblock = m_chain_helper->GetBestChainLockHeight() < pindex->nHeight; if (!m_chain_helper->mn_payments->IsBlockValueValid(block, pindex->nHeight, blockSubsidy + feeReward, strError, check_superblock)) { // NOTE: Do not punish, the node might be missing governance data @@ -4121,7 +4118,7 @@ bool ChainstateManager::AcceptBlockHeader(const CBlockHeader& block, BlockValida } } - if (llmq::chainLocksHandler->HasConflictingChainLock(pindexPrev->nHeight + 1, hash)) { + if (ActiveChainstate().m_chain_helper->HasConflictingChainLock(pindexPrev->nHeight + 1, hash)) { if (miSelf == m_blockman.m_block_index.end()) { m_blockman.AddToBlockIndex(block, hash, m_best_header, BLOCK_CONFLICT_CHAINLOCK); } @@ -5491,7 +5488,6 @@ std::vector ChainstateManager::GetAll() CChainState& ChainstateManager::InitializeChainstate(CTxMemPool* mempool, CEvoDB& evoDb, const std::unique_ptr& chain_helper, - const std::unique_ptr& clhandler, const std::unique_ptr& isman, const std::optional& snapshot_blockhash) { @@ -5504,7 +5500,7 @@ CChainState& ChainstateManager::InitializeChainstate(CTxMemPool* mempool, throw std::logic_error("should not be overwriting a chainstate"); } - to_modify.reset(new CChainState(mempool, m_blockman, *this, evoDb, chain_helper, clhandler, isman, snapshot_blockhash)); + to_modify.reset(new CChainState(mempool, m_blockman, *this, evoDb, chain_helper, isman, snapshot_blockhash)); // Snapshot chainstates and initial IBD chaintates always become active. if (is_snapshot || (!is_snapshot && !m_active_chainstate)) { @@ -5577,7 +5573,6 @@ bool ChainstateManager::ActivateSnapshot( /* mempool */ nullptr, m_blockman, *this, this->ActiveChainstate().m_evoDb, this->ActiveChainstate().m_chain_helper, - this->ActiveChainstate().m_clhandler, this->ActiveChainstate().m_isman, base_blockhash ) diff --git a/src/validation.h b/src/validation.h index 224a44d295ecd..39a39158797be 100644 --- a/src/validation.h +++ b/src/validation.h @@ -485,7 +485,6 @@ class CChainState //! Dash const std::unique_ptr& m_chain_helper; - const std::unique_ptr& m_clhandler; const std::unique_ptr& m_isman; CEvoDB& m_evoDb; @@ -507,7 +506,6 @@ class CChainState ChainstateManager& chainman, CEvoDB& evoDb, const std::unique_ptr& chain_helper, - const std::unique_ptr& clhandler, const std::unique_ptr& isman, std::optional from_snapshot_blockhash = std::nullopt); @@ -940,7 +938,6 @@ class ChainstateManager CChainState& InitializeChainstate(CTxMemPool* mempool, CEvoDB& evoDb, const std::unique_ptr& chain_helper, - const std::unique_ptr& clhandler, const std::unique_ptr& isman, const std::optional& snapshot_blockhash = std::nullopt) LIFETIMEBOUND EXCLUSIVE_LOCKS_REQUIRED(::cs_main); From 41c8c8f8af30cefc546a66b0767e99ae0f14d2be Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Sun, 22 Dec 2024 20:03:37 +0000 Subject: [PATCH 03/11] refactor: remove `llmq::chainLocksHandler` global, move to `LLMQContext` --- src/llmq/chainlocks.cpp | 2 -- src/llmq/chainlocks.h | 2 -- src/llmq/context.cpp | 18 +++++------------- src/llmq/context.h | 2 +- 4 files changed, 6 insertions(+), 18 deletions(-) diff --git a/src/llmq/chainlocks.cpp b/src/llmq/chainlocks.cpp index 1b6f56f5c8632..d7059d6f543a0 100644 --- a/src/llmq/chainlocks.cpp +++ b/src/llmq/chainlocks.cpp @@ -29,8 +29,6 @@ static bool ChainLocksSigningEnabled(const CSporkManager& sporkman) namespace llmq { -std::unique_ptr chainLocksHandler; - CChainLocksHandler::CChainLocksHandler(CChainState& chainstate, CQuorumManager& _qman, CSigningManager& _sigman, CSigSharesManager& _shareman, CSporkManager& sporkman, CTxMemPool& _mempool, const CMasternodeSync& mn_sync, bool is_masternode) : diff --git a/src/llmq/chainlocks.h b/src/llmq/chainlocks.h index 04c080453b63c..be2065300241b 100644 --- a/src/llmq/chainlocks.h +++ b/src/llmq/chainlocks.h @@ -126,8 +126,6 @@ class CChainLocksHandler : public CRecoveredSigsListener void Cleanup() EXCLUSIVE_LOCKS_REQUIRED(!cs); }; -extern std::unique_ptr chainLocksHandler; - bool AreChainLocksEnabled(const CSporkManager& sporkman); } // namespace llmq diff --git a/src/llmq/context.cpp b/src/llmq/context.cpp index 8e8307b5c5075..312e00c2b0860 100644 --- a/src/llmq/context.cpp +++ b/src/llmq/context.cpp @@ -34,16 +34,11 @@ LLMQContext::LLMQContext(ChainstateManager& chainman, CDeterministicMNManager& d wipe)}, sigman{std::make_unique(mn_activeman, chainman.ActiveChainstate(), *qman, unit_tests, wipe)}, shareman{std::make_unique(*sigman, mn_activeman, *qman, sporkman)}, - clhandler{[&]() -> llmq::CChainLocksHandler* const { - assert(llmq::chainLocksHandler == nullptr); - llmq::chainLocksHandler = std::make_unique(chainman.ActiveChainstate(), *qman, - *sigman, *shareman, sporkman, mempool, - mn_sync, is_masternode); - return llmq::chainLocksHandler.get(); - }()}, + clhandler{std::make_unique(chainman.ActiveChainstate(), *qman, *sigman, *shareman, + sporkman, mempool, mn_sync, is_masternode)}, isman{[&]() -> llmq::CInstantSendManager* const { assert(llmq::quorumInstantSendManager == nullptr); - llmq::quorumInstantSendManager = std::make_unique(*llmq::chainLocksHandler, + llmq::quorumInstantSendManager = std::make_unique(*clhandler, chainman.ActiveChainstate(), *qman, *sigman, *shareman, sporkman, mempool, mn_sync, is_masternode, @@ -61,7 +56,6 @@ LLMQContext::~LLMQContext() { // LLMQContext doesn't own these objects, but still need to care of them for consistency: llmq::quorumInstantSendManager.reset(); - llmq::chainLocksHandler.reset(); } void LLMQContext::Interrupt() { @@ -74,7 +68,6 @@ void LLMQContext::Interrupt() { void LLMQContext::Start(CConnman& connman, PeerManager& peerman) { - assert(clhandler == llmq::chainLocksHandler.get()); assert(isman == llmq::quorumInstantSendManager.get()); if (is_masternode) { @@ -85,16 +78,15 @@ void LLMQContext::Start(CConnman& connman, PeerManager& peerman) shareman->StartWorkerThread(connman, peerman); sigman->StartWorkerThread(peerman); - llmq::chainLocksHandler->Start(); + clhandler->Start(); llmq::quorumInstantSendManager->Start(peerman); } void LLMQContext::Stop() { - assert(clhandler == llmq::chainLocksHandler.get()); assert(isman == llmq::quorumInstantSendManager.get()); llmq::quorumInstantSendManager->Stop(); - llmq::chainLocksHandler->Stop(); + clhandler->Stop(); shareman->StopWorkerThread(); shareman->UnregisterAsRecoveredSigsListener(); diff --git a/src/llmq/context.h b/src/llmq/context.h index 0e92e6a90fce6..b7f77b063a679 100644 --- a/src/llmq/context.h +++ b/src/llmq/context.h @@ -66,7 +66,7 @@ struct LLMQContext { const std::unique_ptr qman; const std::unique_ptr sigman; const std::unique_ptr shareman; - llmq::CChainLocksHandler* const clhandler; + const std::unique_ptr clhandler; llmq::CInstantSendManager* const isman; const std::unique_ptr ehfSignalsHandler; }; From a167c0eed184320fb40d322d3d968d3706fba8db Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Mon, 6 Jan 2025 16:00:59 +0000 Subject: [PATCH 04/11] refactor: add passthrough functions to `CInstantSendManager` --- src/evo/chainhelper.cpp | 28 +++++++++++++++-- src/evo/chainhelper.h | 18 +++++++++-- src/init.cpp | 2 -- src/node/chainstate.cpp | 8 ++--- src/node/chainstate.h | 2 -- src/test/util/setup_common.cpp | 2 -- src/test/validation_chainstate_tests.cpp | 3 +- .../validation_chainstatemanager_tests.cpp | 11 ++++--- src/test/validation_flush_tests.cpp | 4 +-- src/validation.cpp | 30 ++++++++----------- src/validation.h | 4 --- 11 files changed, 63 insertions(+), 49 deletions(-) diff --git a/src/evo/chainhelper.cpp b/src/evo/chainhelper.cpp index 1408256e310c1..b0413dade5a40 100644 --- a/src/evo/chainhelper.cpp +++ b/src/evo/chainhelper.cpp @@ -7,13 +7,16 @@ #include #include #include +#include #include -CChainstateHelper::CChainstateHelper(CCreditPoolManager& cpoolman, CDeterministicMNManager& dmnman, CMNHFManager& mnhfman, - CGovernanceManager& govman, llmq::CQuorumBlockProcessor& qblockman, +CChainstateHelper::CChainstateHelper(CCreditPoolManager& cpoolman, CDeterministicMNManager& dmnman, + CMNHFManager& mnhfman, CGovernanceManager& govman, + llmq::CInstantSendManager& isman, llmq::CQuorumBlockProcessor& qblockman, const ChainstateManager& chainman, const Consensus::Params& consensus_params, const CMasternodeSync& mn_sync, const CSporkManager& sporkman, const llmq::CChainLocksHandler& clhandler, const llmq::CQuorumManager& qman) : + isman{isman}, clhandler{clhandler}, mn_payments{std::make_unique(dmnman, govman, chainman, consensus_params, mn_sync, sporkman)}, special_tx{std::make_unique(cpoolman, dmnman, mnhfman, qblockman, chainman, consensus_params, @@ -34,3 +37,24 @@ bool CChainstateHelper::HasChainLock(int nHeight, const uint256& blockHash) cons } int32_t CChainstateHelper::GetBestChainLockHeight() const { return clhandler.GetBestChainLock().getHeight(); } + +/** Passthrough functions to CInstantSendManager */ +std::optional> CChainstateHelper::ConflictingISLockIfAny( + const CTransaction& tx) const +{ + const auto islock = isman.GetConflictingLock(tx); + if (!islock) return std::nullopt; + return std::make_pair(::SerializeHash(*islock), islock->txid); +} + +bool CChainstateHelper::IsInstantSendWaitingForTx(const uint256& hash) const { return isman.IsWaitingForTx(hash); } + +bool CChainstateHelper::RemoveConflictingISLockByTx(const CTransaction& tx) +{ + const auto islock = isman.GetConflictingLock(tx); + if (!islock) return false; + isman.RemoveConflictingLock(::SerializeHash(*islock), *islock); + return true; +} + +bool CChainstateHelper::ShouldInstantSendRejectConflicts() const { return isman.RejectConflictingBlocks(); } diff --git a/src/evo/chainhelper.h b/src/evo/chainhelper.h index 5ca4b7a1b0ea6..2954d24fb39cf 100644 --- a/src/evo/chainhelper.h +++ b/src/evo/chainhelper.h @@ -6,6 +6,7 @@ #define BITCOIN_EVO_CHAINHELPER_H #include +#include class CCreditPoolManager; class CDeterministicMNManager; @@ -16,11 +17,13 @@ class CMasternodeSync; class CGovernanceManager; class CSpecialTxProcessor; class CSporkManager; +class CTransaction; class uint256; namespace Consensus { struct Params; } namespace llmq { class CChainLocksHandler; +class CInstantSendManager; class CQuorumBlockProcessor; class CQuorumManager; } @@ -28,12 +31,15 @@ class CQuorumManager; class CChainstateHelper { private: + llmq::CInstantSendManager& isman; const llmq::CChainLocksHandler& clhandler; public: - explicit CChainstateHelper(CCreditPoolManager& cpoolman, CDeterministicMNManager& dmnman, CMNHFManager& mnhfman, CGovernanceManager& govman, - llmq::CQuorumBlockProcessor& qblockman, const ChainstateManager& chainman, const Consensus::Params& consensus_params, - const CMasternodeSync& mn_sync, const CSporkManager& sporkman, const llmq::CChainLocksHandler& clhandler, + explicit CChainstateHelper(CCreditPoolManager& cpoolman, CDeterministicMNManager& dmnman, CMNHFManager& mnhfman, + CGovernanceManager& govman, llmq::CInstantSendManager& isman, + llmq::CQuorumBlockProcessor& qblockman, const ChainstateManager& chainman, + const Consensus::Params& consensus_params, const CMasternodeSync& mn_sync, + const CSporkManager& sporkman, const llmq::CChainLocksHandler& clhandler, const llmq::CQuorumManager& qman); ~CChainstateHelper(); @@ -45,6 +51,12 @@ class CChainstateHelper bool HasChainLock(int nHeight, const uint256& blockHash) const; int32_t GetBestChainLockHeight() const; + /** Passthrough functions to CInstantSendManager */ + std::optional> ConflictingISLockIfAny(const CTransaction& tx) const; + bool IsInstantSendWaitingForTx(const uint256& hash) const; + bool RemoveConflictingISLockByTx(const CTransaction& tx); + bool ShouldInstantSendRejectConflicts() const; + public: const std::unique_ptr mn_payments; const std::unique_ptr special_tx; diff --git a/src/init.cpp b/src/init.cpp index 126cfab9360ad..6b99393b0a9a0 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -100,7 +100,6 @@ #include #include #include -#include #include #include #include @@ -1857,7 +1856,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) node.dmnman, node.evodb, node.mnhf_manager, - llmq::quorumInstantSendManager, llmq::quorumSnapshotManager, node.llmq_ctx, Assert(node.mempool.get()), diff --git a/src/node/chainstate.cpp b/src/node/chainstate.cpp index 62803e1dff8ea..6365f1dde3804 100644 --- a/src/node/chainstate.cpp +++ b/src/node/chainstate.cpp @@ -16,7 +16,6 @@ #include #include #include -#include #include std::optional LoadChainstate(bool fReset, @@ -31,7 +30,6 @@ std::optional LoadChainstate(bool fReset, std::unique_ptr& dmnman, std::unique_ptr& evodb, std::unique_ptr& mnhf_manager, - std::unique_ptr& isman, std::unique_ptr& qsnapman, std::unique_ptr& llmq_ctx, CTxMemPool* mempool, @@ -65,7 +63,7 @@ std::optional LoadChainstate(bool fReset, mnhf_manager.reset(); mnhf_manager = std::make_unique(*evodb); - chainman.InitializeChainstate(mempool, *evodb, chain_helper, isman); + chainman.InitializeChainstate(mempool, *evodb, chain_helper); chainman.m_total_coinstip_cache = nCoinCacheUsage; chainman.m_total_coinsdb_cache = nCoinDBCache; @@ -241,8 +239,8 @@ void DashChainstateSetup(ChainstateManager& chainman, mnhf_manager->ConnectManagers(&chainman, llmq_ctx->qman.get()); chain_helper.reset(); - chain_helper = std::make_unique(*cpoolman, *dmnman, *mnhf_manager, govman, *(llmq_ctx->quorum_block_processor), chainman, - consensus_params, mn_sync, sporkman, *(llmq_ctx->clhandler), *(llmq_ctx->qman)); + chain_helper = std::make_unique(*cpoolman, *dmnman, *mnhf_manager, govman, *(llmq_ctx->isman), *(llmq_ctx->quorum_block_processor), + chainman, consensus_params, mn_sync, sporkman, *(llmq_ctx->clhandler), *(llmq_ctx->qman)); } void DashChainstateSetupClose(std::unique_ptr& chain_helper, diff --git a/src/node/chainstate.h b/src/node/chainstate.h index de20bfbec2aca..b2b3d98310811 100644 --- a/src/node/chainstate.h +++ b/src/node/chainstate.h @@ -26,7 +26,6 @@ class CTxMemPool; struct LLMQContext; namespace llmq { -class CInstantSendManager; class CQuorumSnapshotManager; } @@ -92,7 +91,6 @@ std::optional LoadChainstate(bool fReset, std::unique_ptr& dmnman, std::unique_ptr& evodb, std::unique_ptr& mnhf_manager, - std::unique_ptr& isman, std::unique_ptr& qsnapman, std::unique_ptr& llmq_ctx, CTxMemPool* mempool, diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 5c8bd3e8b8d0e..65fa619d1f1fe 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -297,7 +296,6 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector #include #include -#include #include #include #include @@ -42,7 +41,7 @@ BOOST_AUTO_TEST_CASE(validation_chainstate_resize_caches) return outp; }; - CChainState& c1 = WITH_LOCK(cs_main, return manager.InitializeChainstate(&mempool, *m_node.evodb, m_node.chain_helper, llmq::quorumInstantSendManager)); + CChainState& c1 = WITH_LOCK(cs_main, return manager.InitializeChainstate(&mempool, *m_node.evodb, m_node.chain_helper)); c1.InitCoinsDB( /* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false); WITH_LOCK(::cs_main, c1.InitCoinsCache(1 << 23)); diff --git a/src/test/validation_chainstatemanager_tests.cpp b/src/test/validation_chainstatemanager_tests.cpp index 52598c5b6b084..f4eb2cc50c870 100644 --- a/src/test/validation_chainstatemanager_tests.cpp +++ b/src/test/validation_chainstatemanager_tests.cpp @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -44,7 +43,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager) // Create a legacy (IBD) chainstate. // - CChainState& c1 = WITH_LOCK(::cs_main, return manager.InitializeChainstate(&mempool, evodb, m_node.chain_helper, llmq::quorumInstantSendManager)); + CChainState& c1 = WITH_LOCK(::cs_main, return manager.InitializeChainstate(&mempool, evodb, m_node.chain_helper)); chainstates.push_back(&c1); c1.InitCoinsDB( /* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false); @@ -80,7 +79,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager) // const uint256 snapshot_blockhash = GetRandHash(); CChainState& c2 = WITH_LOCK(::cs_main, return manager.InitializeChainstate( - &mempool, evodb, m_node.chain_helper, llmq::quorumInstantSendManager, + &mempool, evodb, m_node.chain_helper, snapshot_blockhash) ); chainstates.push_back(&c2); @@ -143,7 +142,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager_rebalance_caches) // Create a legacy (IBD) chainstate. // - CChainState& c1 = WITH_LOCK(cs_main, return manager.InitializeChainstate(&mempool, evodb, m_node.chain_helper, llmq::quorumInstantSendManager)); + CChainState& c1 = WITH_LOCK(cs_main, return manager.InitializeChainstate(&mempool, evodb, m_node.chain_helper)); chainstates.push_back(&c1); c1.InitCoinsDB( /* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false); @@ -161,7 +160,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager_rebalance_caches) // Create a snapshot-based chainstate. // - CChainState& c2 = WITH_LOCK(cs_main, return manager.InitializeChainstate(&mempool, evodb, m_node.chain_helper, llmq::quorumInstantSendManager, GetRandHash())); + CChainState& c2 = WITH_LOCK(cs_main, return manager.InitializeChainstate(&mempool, evodb, m_node.chain_helper, GetRandHash())); chainstates.push_back(&c2); c2.InitCoinsDB( /* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false); @@ -402,7 +401,7 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_loadblockindex, TestChain100Setup) BOOST_CHECK_EQUAL(expected_assumed_valid, num_assumed_valid); CChainState& cs2 = WITH_LOCK(::cs_main, - return chainman.InitializeChainstate(&mempool, *m_node.evodb, m_node.chain_helper, llmq::quorumInstantSendManager, GetRandHash())); + return chainman.InitializeChainstate(&mempool, *m_node.evodb, m_node.chain_helper, GetRandHash())); reload_all_block_indexes(); diff --git a/src/test/validation_flush_tests.cpp b/src/test/validation_flush_tests.cpp index 33781a4e6f17d..111eb8500e84a 100644 --- a/src/test/validation_flush_tests.cpp +++ b/src/test/validation_flush_tests.cpp @@ -3,7 +3,6 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. // #include -#include #include #include #include @@ -22,8 +21,7 @@ BOOST_AUTO_TEST_CASE(getcoinscachesizestate) { CTxMemPool mempool; BlockManager blockman{}; - CChainState chainstate(&mempool, blockman, *Assert(m_node.chainman), *m_node.evodb, m_node.chain_helper, - llmq::quorumInstantSendManager); + CChainState chainstate(&mempool, blockman, *Assert(m_node.chainman), *m_node.evodb, m_node.chain_helper); chainstate.InitCoinsDB(/*cache_size_bytes*/ 1 << 10, /*in_memory*/ true, /*should_wipe*/ false); WITH_LOCK(::cs_main, chainstate.InitCoinsCache(1 << 10)); diff --git a/src/validation.cpp b/src/validation.cpp index c419d0a8aaa64..f2367cb259600 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -62,7 +62,6 @@ #include #include -#include #include #include @@ -728,18 +727,18 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws) return state.Invalid(TxValidationResult::TX_CONFLICT, "txn-already-in-mempool"); } - llmq::CInstantSendLockPtr conflictLock = llmq::quorumInstantSendManager->GetConflictingLock(tx); - if (conflictLock) { + if (auto conflictLockOpt = m_chain_helper.ConflictingISLockIfAny(tx); conflictLockOpt.has_value()) { + auto& [_, conflict_txid] = conflictLockOpt.value(); uint256 hashBlock; - CTransactionRef txConflict = GetTransaction(/* block_index */ nullptr, &m_pool, conflictLock->txid, chainparams.GetConsensus(), hashBlock); + CTransactionRef txConflict = GetTransaction(/* block_index */ nullptr, &m_pool, conflict_txid, chainparams.GetConsensus(), hashBlock); if (txConflict) { GetMainSignals().NotifyInstantSendDoubleSpendAttempt(ptx, txConflict); } - LogPrintf("ERROR: AcceptToMemoryPool : Transaction %s conflicts with locked TX %s\n", hash.ToString(), conflictLock->txid.ToString()); + LogPrintf("ERROR: AcceptToMemoryPool : Transaction %s conflicts with locked TX %s\n", hash.ToString(), conflict_txid.ToString()); return state.Invalid(TxValidationResult::TX_CONFLICT_LOCK, "tx-txlock-conflict"); } - if (llmq::quorumInstantSendManager->IsWaitingForTx(hash)) { + if (m_chain_helper.IsInstantSendWaitingForTx(hash)) { m_pool.removeConflicts(tx); m_pool.removeProTxConflicts(tx); } else { @@ -1523,11 +1522,9 @@ CChainState::CChainState(CTxMemPool* mempool, ChainstateManager& chainman, CEvoDB& evoDb, const std::unique_ptr& chain_helper, - const std::unique_ptr& isman, std::optional from_snapshot_blockhash) : m_mempool(mempool), m_chain_helper(chain_helper), - m_isman(isman), m_evoDb(evoDb), m_blockman(blockman), m_params(::Params()), @@ -2144,7 +2141,6 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, assert(*pindex->phashBlock == block_hash); assert(m_chain_helper); - assert(m_isman); // Check it again in case a previous version let a bad block in // NOTE: We don't currently (re-)invoke ContextualCheckBlock() or @@ -2466,21 +2462,21 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, // DASH : CHECK TRANSACTIONS FOR INSTANTSEND - if (m_isman->RejectConflictingBlocks()) { + if (m_chain_helper->ShouldInstantSendRejectConflicts()) { // Require other nodes to comply, send them some data in case they are missing it. const bool has_chainlock = m_chain_helper->HasChainLock(pindex->nHeight, pindex->GetBlockHash()); for (const auto& tx : block.vtx) { // skip txes that have no inputs if (tx->vin.empty()) continue; - while (llmq::CInstantSendLockPtr conflictLock = m_isman->GetConflictingLock(*tx)) { + while (auto conflictLockOpt = m_chain_helper->ConflictingISLockIfAny(*tx)) { + auto [conflict_islock_hash, conflict_txid] = conflictLockOpt.value(); if (has_chainlock) { - LogPrint(BCLog::ALL, "ConnectBlock(DASH): chain-locked transaction %s overrides islock %s\n", - tx->GetHash().ToString(), ::SerializeHash(*conflictLock).ToString()); - m_isman->RemoveConflictingLock(::SerializeHash(*conflictLock), *conflictLock); + LogPrint(BCLog::ALL, "ConnectBlock(DASH): chain-locked transaction %s overrides islock %s\n", tx->GetHash().ToString(), conflict_islock_hash.ToString()); + m_chain_helper->RemoveConflictingISLockByTx(*tx); } else { // The node which relayed this should switch to correct chain. // TODO: relay instantsend data/proof. - LogPrintf("ERROR: ConnectBlock(DASH): transaction %s conflicts with transaction lock %s\n", tx->GetHash().ToString(), conflictLock->txid.ToString()); + LogPrintf("ERROR: ConnectBlock(DASH): transaction %s conflicts with transaction lock %s\n", tx->GetHash().ToString(), conflict_txid.ToString()); return state.Invalid(BlockValidationResult::BLOCK_CHAINLOCK, "conflict-tx-lock"); } } @@ -5488,7 +5484,6 @@ std::vector ChainstateManager::GetAll() CChainState& ChainstateManager::InitializeChainstate(CTxMemPool* mempool, CEvoDB& evoDb, const std::unique_ptr& chain_helper, - const std::unique_ptr& isman, const std::optional& snapshot_blockhash) { AssertLockHeld(::cs_main); @@ -5500,7 +5495,7 @@ CChainState& ChainstateManager::InitializeChainstate(CTxMemPool* mempool, throw std::logic_error("should not be overwriting a chainstate"); } - to_modify.reset(new CChainState(mempool, m_blockman, *this, evoDb, chain_helper, isman, snapshot_blockhash)); + to_modify.reset(new CChainState(mempool, m_blockman, *this, evoDb, chain_helper, snapshot_blockhash)); // Snapshot chainstates and initial IBD chaintates always become active. if (is_snapshot || (!is_snapshot && !m_active_chainstate)) { @@ -5573,7 +5568,6 @@ bool ChainstateManager::ActivateSnapshot( /* mempool */ nullptr, m_blockman, *this, this->ActiveChainstate().m_evoDb, this->ActiveChainstate().m_chain_helper, - this->ActiveChainstate().m_isman, base_blockhash ) ); diff --git a/src/validation.h b/src/validation.h index 39a39158797be..62312138c32e6 100644 --- a/src/validation.h +++ b/src/validation.h @@ -59,7 +59,6 @@ struct AssumeutxoData; namespace llmq { class CChainLocksHandler; -class CInstantSendManager; } // namespace llmq /** Default for -mempoolexpiry, expiration time for mempool transactions in hours */ @@ -485,7 +484,6 @@ class CChainState //! Dash const std::unique_ptr& m_chain_helper; - const std::unique_ptr& m_isman; CEvoDB& m_evoDb; public: @@ -506,7 +504,6 @@ class CChainState ChainstateManager& chainman, CEvoDB& evoDb, const std::unique_ptr& chain_helper, - const std::unique_ptr& isman, std::optional from_snapshot_blockhash = std::nullopt); /** @@ -938,7 +935,6 @@ class ChainstateManager CChainState& InitializeChainstate(CTxMemPool* mempool, CEvoDB& evoDb, const std::unique_ptr& chain_helper, - const std::unique_ptr& isman, const std::optional& snapshot_blockhash = std::nullopt) LIFETIMEBOUND EXCLUSIVE_LOCKS_REQUIRED(::cs_main); From 9c989a133c0a32d5794663cc5fde59d843a054f7 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Mon, 6 Jan 2025 15:50:12 +0000 Subject: [PATCH 05/11] refactor: trim down `llmq::quorumInstantSendManager` use --- src/coinjoin/client.cpp | 12 ++++++++---- src/coinjoin/client.h | 10 ++++++++-- src/coinjoin/coinjoin.cpp | 12 ++++++++---- src/coinjoin/coinjoin.h | 8 ++++++-- src/coinjoin/context.cpp | 6 +++--- src/coinjoin/context.h | 6 +++++- src/coinjoin/server.cpp | 7 ++++--- src/coinjoin/server.h | 4 +++- src/dsnotificationinterface.cpp | 2 +- src/init.cpp | 3 ++- src/llmq/chainlocks.cpp | 14 +++++++------- src/llmq/chainlocks.h | 7 ++++--- src/llmq/context.cpp | 2 +- src/node/chainstate.cpp | 2 +- src/test/evo_deterministicmns_tests.cpp | 6 ++++-- src/test/util/setup_common.cpp | 3 ++- src/txmempool.cpp | 7 +++++-- src/txmempool.h | 20 ++++++++++++++------ 18 files changed, 86 insertions(+), 45 deletions(-) diff --git a/src/coinjoin/client.cpp b/src/coinjoin/client.cpp index a25f32510d513..4858223e07cce 100644 --- a/src/coinjoin/client.cpp +++ b/src/coinjoin/client.cpp @@ -166,6 +166,7 @@ void CCoinJoinClientManager::ProcessMessage(CNode& peer, CChainState& active_cha CCoinJoinClientSession::CCoinJoinClientSession(const std::shared_ptr& wallet, CoinJoinWalletManager& walletman, CCoinJoinClientManager& clientman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, const CMasternodeSync& mn_sync, + const llmq::CInstantSendManager& isman, const std::unique_ptr& queueman, bool is_masternode) : m_wallet(wallet), @@ -174,6 +175,7 @@ CCoinJoinClientSession::CCoinJoinClientSession(const std::shared_ptr& w m_dmnman(dmnman), m_mn_metaman(mn_metaman), m_mn_sync(mn_sync), + m_isman{isman}, m_queueman(queueman), m_is_masternode{is_masternode} {} @@ -589,7 +591,8 @@ bool CCoinJoinClientSession::SignFinalTransaction(CNode& peer, CChainState& acti // Make sure all inputs/outputs are valid PoolMessage nMessageID{MSG_NOERR}; - if (!IsValidInOuts(active_chainstate, mempool, finalMutableTransaction.vin, finalMutableTransaction.vout, nMessageID, nullptr)) { + if (!IsValidInOuts(active_chainstate, m_isman, mempool, finalMutableTransaction.vin, finalMutableTransaction.vout, + nMessageID, nullptr)) { WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::%s -- ERROR! IsValidInOuts() failed: %s\n", __func__, CoinJoin::GetMessageByID(nMessageID).translated); UnlockCoins(); keyHolderStorage.ReturnAll(); @@ -953,7 +956,7 @@ bool CCoinJoinClientSession::DoAutomaticDenominating(ChainstateManager& chainman return false; } } else { - if (!CoinJoin::IsCollateralValid(chainman, mempool, CTransaction(txMyCollateral))) { + if (!CoinJoin::IsCollateralValid(chainman, m_isman, mempool, CTransaction(txMyCollateral))) { WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::DoAutomaticDenominating -- invalid collateral, recreating...\n"); if (!CreateCollateralTransaction(txMyCollateral, strReason)) { WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::DoAutomaticDenominating -- create collateral error: %s\n", strReason); @@ -1012,7 +1015,7 @@ bool CCoinJoinClientManager::DoAutomaticDenominating(ChainstateManager& chainman AssertLockNotHeld(cs_deqsessions); LOCK(cs_deqsessions); if (int(deqSessions.size()) < CCoinJoinClientOptions::GetSessions()) { - deqSessions.emplace_back(m_wallet, m_walletman, *this, m_dmnman, m_mn_metaman, m_mn_sync, m_queueman, + deqSessions.emplace_back(m_wallet, m_walletman, *this, m_dmnman, m_mn_metaman, m_mn_sync, m_isman, m_queueman, m_is_masternode); } for (auto& session : deqSessions) { @@ -1915,7 +1918,8 @@ void CoinJoinWalletManager::Add(const std::shared_ptr& wallet) LOCK(cs_wallet_manager_map); m_wallet_manager_map.try_emplace(wallet->GetName(), std::make_unique(wallet, *this, m_dmnman, m_mn_metaman, - m_mn_sync, m_queueman, m_is_masternode)); + m_mn_sync, m_isman, m_queueman, + m_is_masternode)); } g_wallet_init_interface.InitCoinJoinSettings(*this); } diff --git a/src/coinjoin/client.h b/src/coinjoin/client.h index 2eccc1cfc28cc..da8f850c923c1 100644 --- a/src/coinjoin/client.h +++ b/src/coinjoin/client.h @@ -77,13 +77,14 @@ class CoinJoinWalletManager { public: CoinJoinWalletManager(ChainstateManager& chainman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, - const CTxMemPool& mempool, const CMasternodeSync& mn_sync, + const CTxMemPool& mempool, const CMasternodeSync& mn_sync, const llmq::CInstantSendManager& isman, const std::unique_ptr& queueman, bool is_masternode) : m_chainman(chainman), m_dmnman(dmnman), m_mn_metaman(mn_metaman), m_mempool(mempool), m_mn_sync(mn_sync), + m_isman{isman}, m_queueman(queueman), m_is_masternode{is_masternode} {} @@ -125,6 +126,7 @@ class CoinJoinWalletManager { CMasternodeMetaMan& m_mn_metaman; const CTxMemPool& m_mempool; const CMasternodeSync& m_mn_sync; + const llmq::CInstantSendManager& m_isman; const std::unique_ptr& m_queueman; const bool m_is_masternode; @@ -142,6 +144,7 @@ class CCoinJoinClientSession : public CCoinJoinBaseSession CDeterministicMNManager& m_dmnman; CMasternodeMetaMan& m_mn_metaman; const CMasternodeSync& m_mn_sync; + const llmq::CInstantSendManager& m_isman; const std::unique_ptr& m_queueman; // Track node type @@ -201,6 +204,7 @@ class CCoinJoinClientSession : public CCoinJoinBaseSession explicit CCoinJoinClientSession(const std::shared_ptr& wallet, CoinJoinWalletManager& walletman, CCoinJoinClientManager& clientman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, const CMasternodeSync& mn_sync, + const llmq::CInstantSendManager& isman, const std::unique_ptr& queueman, bool is_masternode); void ProcessMessage(CNode& peer, CChainState& active_chainstate, CConnman& connman, const CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv); @@ -266,6 +270,7 @@ class CCoinJoinClientManager CDeterministicMNManager& m_dmnman; CMasternodeMetaMan& m_mn_metaman; const CMasternodeSync& m_mn_sync; + const llmq::CInstantSendManager& m_isman; const std::unique_ptr& m_queueman; // Track node type @@ -302,13 +307,14 @@ class CCoinJoinClientManager explicit CCoinJoinClientManager(const std::shared_ptr& wallet, CoinJoinWalletManager& walletman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, - const CMasternodeSync& mn_sync, + const CMasternodeSync& mn_sync, const llmq::CInstantSendManager& isman, const std::unique_ptr& queueman, bool is_masternode) : m_wallet(wallet), m_walletman(walletman), m_dmnman(dmnman), m_mn_metaman(mn_metaman), m_mn_sync(mn_sync), + m_isman{isman}, m_queueman(queueman), m_is_masternode{is_masternode} { diff --git a/src/coinjoin/coinjoin.cpp b/src/coinjoin/coinjoin.cpp index 74fc644a70911..c4282f0f69de7 100644 --- a/src/coinjoin/coinjoin.cpp +++ b/src/coinjoin/coinjoin.cpp @@ -207,7 +207,10 @@ std::string CCoinJoinBaseSession::GetStateString() const } } -bool CCoinJoinBaseSession::IsValidInOuts(CChainState& active_chainstate, const CTxMemPool& mempool, const std::vector& vin, const std::vector& vout, PoolMessage& nMessageIDRet, bool* fConsumeCollateralRet) const +bool CCoinJoinBaseSession::IsValidInOuts(CChainState& active_chainstate, const llmq::CInstantSendManager& isman, + const CTxMemPool& mempool, const std::vector& vin, + const std::vector& vout, PoolMessage& nMessageIDRet, + bool* fConsumeCollateralRet) const { std::set setScripPubKeys; nMessageIDRet = MSG_NOERR; @@ -268,7 +271,7 @@ bool CCoinJoinBaseSession::IsValidInOuts(CChainState& active_chainstate, const C Coin coin; if (!viewMemPool.GetCoin(txin.prevout, coin) || coin.IsSpent() || - (coin.nHeight == MEMPOOL_HEIGHT && !llmq::quorumInstantSendManager->IsLocked(txin.prevout.hash))) { + (coin.nHeight == MEMPOOL_HEIGHT && !isman.IsLocked(txin.prevout.hash))) { LogPrint(BCLog::COINJOIN, "CCoinJoinBaseSession::%s -- ERROR: missing, spent or non-locked mempool input! txin=%s\n", __func__, txin.ToString()); nMessageIDRet = ERR_MISSING_TX; return false; @@ -313,7 +316,8 @@ bool ATMPIfSaneFee(ChainstateManager& chainman, const CTransactionRef& tx, bool } // check to make sure the collateral provided by the client is valid -bool CoinJoin::IsCollateralValid(ChainstateManager& chainman, const CTxMemPool& mempool, const CTransaction& txCollateral) +bool CoinJoin::IsCollateralValid(ChainstateManager& chainman, const llmq::CInstantSendManager& isman, + const CTxMemPool& mempool, const CTransaction& txCollateral) { if (txCollateral.vout.empty()) return false; if (txCollateral.nLockTime != 0) return false; @@ -334,7 +338,7 @@ bool CoinJoin::IsCollateralValid(ChainstateManager& chainman, const CTxMemPool& Coin coin; auto mempoolTx = mempool.get(txin.prevout.hash); if (mempoolTx != nullptr) { - if (mempool.isSpent(txin.prevout) || !llmq::quorumInstantSendManager->IsLocked(txin.prevout.hash)) { + if (mempool.isSpent(txin.prevout) || !isman.IsLocked(txin.prevout.hash)) { LogPrint(BCLog::COINJOIN, "CoinJoin::IsCollateralValid -- spent or non-locked mempool input! txin=%s\n", txin.ToString()); return false; } diff --git a/src/coinjoin/coinjoin.h b/src/coinjoin/coinjoin.h index 68e2f40c05549..3d5e1f8022dde 100644 --- a/src/coinjoin/coinjoin.h +++ b/src/coinjoin/coinjoin.h @@ -33,6 +33,7 @@ class TxValidationState; namespace llmq { class CChainLocksHandler; +class CInstantSendManager; } // namespace llmq extern RecursiveMutex cs_main; @@ -308,7 +309,9 @@ class CCoinJoinBaseSession virtual void SetNull() EXCLUSIVE_LOCKS_REQUIRED(cs_coinjoin); - bool IsValidInOuts(CChainState& active_chainstate, const CTxMemPool& mempool, const std::vector& vin, const std::vector& vout, PoolMessage& nMessageIDRet, bool* fConsumeCollateralRet) const; + bool IsValidInOuts(CChainState& active_chainstate, const llmq::CInstantSendManager& isman, + const CTxMemPool& mempool, const std::vector& vin, const std::vector& vout, + PoolMessage& nMessageIDRet, bool* fConsumeCollateralRet) const; public: int nSessionDenom{0}; // Users must submit a denom matching this @@ -365,7 +368,8 @@ namespace CoinJoin constexpr CAmount GetMaxPoolAmount() { return COINJOIN_ENTRY_MAX_SIZE * vecStandardDenominations.front(); } /// If the collateral is valid given by a client - bool IsCollateralValid(ChainstateManager& chainman, const CTxMemPool& mempool, const CTransaction& txCollateral); + bool IsCollateralValid(ChainstateManager& chainman, const llmq::CInstantSendManager& isman, + const CTxMemPool& mempool, const CTransaction& txCollateral); } class CDSTXManager diff --git a/src/coinjoin/context.cpp b/src/coinjoin/context.cpp index 8ab6f9e6360ae..0bd9da7c9d4c5 100644 --- a/src/coinjoin/context.cpp +++ b/src/coinjoin/context.cpp @@ -12,17 +12,17 @@ CJContext::CJContext(ChainstateManager& chainman, CConnman& connman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, CTxMemPool& mempool, const CActiveMasternodeManager* const mn_activeman, const CMasternodeSync& mn_sync, - std::unique_ptr& peerman, bool relay_txes) : + const llmq::CInstantSendManager& isman, std::unique_ptr& peerman, bool relay_txes) : dstxman{std::make_unique()}, #ifdef ENABLE_WALLET - walletman{std::make_unique(chainman, dmnman, mn_metaman, mempool, mn_sync, queueman, + walletman{std::make_unique(chainman, dmnman, mn_metaman, mempool, mn_sync, isman, queueman, /*is_masternode=*/mn_activeman != nullptr)}, queueman{relay_txes ? std::make_unique(*walletman, dmnman, mn_metaman, mn_sync, /*is_masternode=*/mn_activeman != nullptr) : nullptr}, #endif // ENABLE_WALLET server{std::make_unique(chainman, connman, dmnman, *dstxman, mn_metaman, mempool, mn_activeman, - mn_sync, peerman)} + mn_sync, isman, peerman)} {} CJContext::~CJContext() {} diff --git a/src/coinjoin/context.h b/src/coinjoin/context.h index b4e8c6a47f557..0fad302749e9d 100644 --- a/src/coinjoin/context.h +++ b/src/coinjoin/context.h @@ -22,6 +22,9 @@ class CMasternodeMetaMan; class CMasternodeSync; class CTxMemPool; class PeerManager; +namespace llmq { +class CInstantSendManager; +}; #ifdef ENABLE_WALLET class CCoinJoinClientQueueManager; @@ -33,7 +36,8 @@ struct CJContext { CJContext(const CJContext&) = delete; CJContext(ChainstateManager& chainman, CConnman& connman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, CTxMemPool& mempool, const CActiveMasternodeManager* const mn_activeman, - const CMasternodeSync& mn_sync, std::unique_ptr& peerman, bool relay_txes); + const CMasternodeSync& mn_sync, const llmq::CInstantSendManager& isman, + std::unique_ptr& peerman, bool relay_txes); ~CJContext(); const std::unique_ptr dstxman; diff --git a/src/coinjoin/server.cpp b/src/coinjoin/server.cpp index 6e0ee38474b7f..ac9acd40bbef4 100644 --- a/src/coinjoin/server.cpp +++ b/src/coinjoin/server.cpp @@ -583,7 +583,7 @@ bool CCoinJoinServer::AddEntry(const CCoinJoinEntry& entry, PoolMessage& nMessag return false; } - if (!CoinJoin::IsCollateralValid(m_chainman, mempool, *entry.txCollateral)) { + if (!CoinJoin::IsCollateralValid(m_chainman, m_isman, mempool, *entry.txCollateral)) { LogPrint(BCLog::COINJOIN, "CCoinJoinServer::%s -- ERROR: collateral not valid!\n", __func__); nMessageIDRet = ERR_INVALID_COLLATERAL; return false; @@ -617,7 +617,8 @@ bool CCoinJoinServer::AddEntry(const CCoinJoinEntry& entry, PoolMessage& nMessag } bool fConsumeCollateral{false}; - if (!IsValidInOuts(m_chainman.ActiveChainstate(), mempool, vin, entry.vecTxOut, nMessageIDRet, &fConsumeCollateral)) { + if (!IsValidInOuts(m_chainman.ActiveChainstate(), m_isman, mempool, vin, entry.vecTxOut, nMessageIDRet, + &fConsumeCollateral)) { LogPrint(BCLog::COINJOIN, "CCoinJoinServer::%s -- ERROR! IsValidInOuts() failed: %s\n", __func__, CoinJoin::GetMessageByID(nMessageIDRet).translated); if (fConsumeCollateral) { ConsumeCollateral(entry.txCollateral); @@ -694,7 +695,7 @@ bool CCoinJoinServer::IsAcceptableDSA(const CCoinJoinAccept& dsa, PoolMessage& n } // check collateral - if (!fUnitTest && !CoinJoin::IsCollateralValid(m_chainman, mempool, CTransaction(dsa.txCollateral))) { + if (!fUnitTest && !CoinJoin::IsCollateralValid(m_chainman, m_isman, mempool, CTransaction(dsa.txCollateral))) { LogPrint(BCLog::COINJOIN, "CCoinJoinServer::%s -- collateral not valid!\n", __func__); nMessageIDRet = ERR_INVALID_COLLATERAL; return false; diff --git a/src/coinjoin/server.h b/src/coinjoin/server.h index c33e98fbf8e70..f7048816ba840 100644 --- a/src/coinjoin/server.h +++ b/src/coinjoin/server.h @@ -36,6 +36,7 @@ class CCoinJoinServer : public CCoinJoinBaseSession, public CCoinJoinBaseManager CTxMemPool& mempool; const CActiveMasternodeManager* const m_mn_activeman; const CMasternodeSync& m_mn_sync; + const llmq::CInstantSendManager& m_isman; std::unique_ptr& m_peerman; // Mixing uses collateral transactions to trust parties entering the pool @@ -94,7 +95,7 @@ class CCoinJoinServer : public CCoinJoinBaseSession, public CCoinJoinBaseManager explicit CCoinJoinServer(ChainstateManager& chainman, CConnman& _connman, CDeterministicMNManager& dmnman, CDSTXManager& dstxman, CMasternodeMetaMan& mn_metaman, CTxMemPool& mempool, const CActiveMasternodeManager* const mn_activeman, const CMasternodeSync& mn_sync, - std::unique_ptr& peerman) : + const llmq::CInstantSendManager& isman, std::unique_ptr& peerman) : m_chainman(chainman), connman(_connman), m_dmnman(dmnman), @@ -103,6 +104,7 @@ class CCoinJoinServer : public CCoinJoinBaseSession, public CCoinJoinBaseManager mempool(mempool), m_mn_activeman(mn_activeman), m_mn_sync(mn_sync), + m_isman{isman}, m_peerman(peerman), vecSessionCollaterals(), fUnitTest(false) diff --git a/src/dsnotificationinterface.cpp b/src/dsnotificationinterface.cpp index 3f412026f8582..86965e1380fe7 100644 --- a/src/dsnotificationinterface.cpp +++ b/src/dsnotificationinterface.cpp @@ -91,7 +91,7 @@ void CDSNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, con #endif // ENABLE_WALLET m_llmq_ctx->isman->UpdatedBlockTip(pindexNew); - m_llmq_ctx->clhandler->UpdatedBlockTip(); + m_llmq_ctx->clhandler->UpdatedBlockTip(*m_llmq_ctx->isman); m_llmq_ctx->qman->UpdatedBlockTip(pindexNew, m_connman, fInitialDownload); m_llmq_ctx->qdkgsman->UpdatedBlockTip(pindexNew, fInitialDownload); diff --git a/src/init.cpp b/src/init.cpp index 6b99393b0a9a0..deaf8d237d9ca 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -2031,7 +2031,8 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) // ********************************************************* Step 7c: Setup CoinJoin node.cj_ctx = std::make_unique(chainman, *node.connman, *node.dmnman, *node.mn_metaman, *node.mempool, - node.mn_activeman.get(), *node.mn_sync, node.peerman, !ignores_incoming_txs); + node.mn_activeman.get(), *node.mn_sync, *node.llmq_ctx->isman, node.peerman, + !ignores_incoming_txs); #ifdef ENABLE_WALLET node.coinjoin_loader = interfaces::MakeCoinJoinLoader(*node.cj_ctx->walletman); diff --git a/src/llmq/chainlocks.cpp b/src/llmq/chainlocks.cpp index d7059d6f543a0..a8abd6f951178 100644 --- a/src/llmq/chainlocks.cpp +++ b/src/llmq/chainlocks.cpp @@ -52,14 +52,14 @@ CChainLocksHandler::~CChainLocksHandler() scheduler_thread->join(); } -void CChainLocksHandler::Start() +void CChainLocksHandler::Start(const llmq::CInstantSendManager& isman) { sigman.RegisterRecoveredSigsListener(this); scheduler->scheduleEvery([&]() { CheckActiveState(); EnforceBestChainLock(); // regularly retry signing the current chaintip as it might have failed before due to missing islocks - TrySignChainTip(); + TrySignChainTip(isman); }, std::chrono::seconds{5}); } @@ -183,7 +183,7 @@ void CChainLocksHandler::AcceptedBlockHeader(gsl::not_null p } } -void CChainLocksHandler::UpdatedBlockTip() +void CChainLocksHandler::UpdatedBlockTip(const llmq::CInstantSendManager& isman) { // don't call TrySignChainTip directly but instead let the scheduler call it. This way we ensure that cs_main is // never locked and TrySignChainTip is not called twice in parallel. Also avoids recursive calls due to @@ -193,7 +193,7 @@ void CChainLocksHandler::UpdatedBlockTip() scheduler->scheduleFromNow([&]() { CheckActiveState(); EnforceBestChainLock(); - TrySignChainTip(); + TrySignChainTip(isman); tryLockChainTipScheduled = false; }, std::chrono::seconds{0}); } @@ -215,7 +215,7 @@ void CChainLocksHandler::CheckActiveState() } } -void CChainLocksHandler::TrySignChainTip() +void CChainLocksHandler::TrySignChainTip(const llmq::CInstantSendManager& isman) { Cleanup(); @@ -272,7 +272,7 @@ void CChainLocksHandler::TrySignChainTip() // considered safe when it is islocked or at least known since 10 minutes (from mempool or block). These checks are // performed for the tip (which we try to sign) and the previous 5 blocks. If a ChainLocked block is found on the // way down, we consider all TXs to be safe. - if (quorumInstantSendManager->IsInstantSendEnabled() && quorumInstantSendManager->RejectConflictingBlocks()) { + if (isman.IsInstantSendEnabled() && isman.RejectConflictingBlocks()) { const auto* pindexWalk = pindex; while (pindexWalk != nullptr) { if (pindex->nHeight - pindexWalk->nHeight > 5) { @@ -303,7 +303,7 @@ void CChainLocksHandler::TrySignChainTip() } } - if (txAge < WAIT_FOR_ISLOCK_TIMEOUT && !quorumInstantSendManager->IsLocked(txid)) { + if (txAge < WAIT_FOR_ISLOCK_TIMEOUT && !isman.IsLocked(txid)) { LogPrint(BCLog::CHAINLOCKS, "CChainLocksHandler::%s -- not signing block %s due to TX %s not being islocked and not old enough. age=%d\n", __func__, pindexWalk->GetBlockHash().ToString(), txid.ToString(), txAge); return; diff --git a/src/llmq/chainlocks.h b/src/llmq/chainlocks.h index be2065300241b..3ceb11b1bf3a2 100644 --- a/src/llmq/chainlocks.h +++ b/src/llmq/chainlocks.h @@ -31,6 +31,7 @@ class CTxMemPool; namespace llmq { +class CInstantSendManager; class CSigningManager; class CSigSharesManager; enum class VerifyRecSigStatus; @@ -89,7 +90,7 @@ class CChainLocksHandler : public CRecoveredSigsListener const CMasternodeSync& mn_sync, bool is_masternode); ~CChainLocksHandler(); - void Start(); + void Start(const llmq::CInstantSendManager& isman); void Stop(); bool AlreadyHave(const CInv& inv) const EXCLUSIVE_LOCKS_REQUIRED(!cs); @@ -100,12 +101,12 @@ class CChainLocksHandler : public CRecoveredSigsListener const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(!cs); void AcceptedBlockHeader(gsl::not_null pindexNew) EXCLUSIVE_LOCKS_REQUIRED(!cs); - void UpdatedBlockTip(); + void UpdatedBlockTip(const llmq::CInstantSendManager& isman); void TransactionAddedToMempool(const CTransactionRef& tx, int64_t nAcceptTime) EXCLUSIVE_LOCKS_REQUIRED(!cs); void BlockConnected(const std::shared_ptr& pblock, gsl::not_null pindex) EXCLUSIVE_LOCKS_REQUIRED(!cs); void BlockDisconnected(const std::shared_ptr& pblock, gsl::not_null pindexDisconnected) EXCLUSIVE_LOCKS_REQUIRED(!cs); void CheckActiveState() EXCLUSIVE_LOCKS_REQUIRED(!cs); - void TrySignChainTip() EXCLUSIVE_LOCKS_REQUIRED(!cs); + void TrySignChainTip(const llmq::CInstantSendManager& isman) EXCLUSIVE_LOCKS_REQUIRED(!cs); void EnforceBestChainLock() EXCLUSIVE_LOCKS_REQUIRED(!cs); [[nodiscard]] MessageProcessingResult HandleNewRecoveredSig(const CRecoveredSig& recoveredSig) override EXCLUSIVE_LOCKS_REQUIRED(!cs); diff --git a/src/llmq/context.cpp b/src/llmq/context.cpp index 312e00c2b0860..c31cb04d5b29a 100644 --- a/src/llmq/context.cpp +++ b/src/llmq/context.cpp @@ -78,7 +78,7 @@ void LLMQContext::Start(CConnman& connman, PeerManager& peerman) shareman->StartWorkerThread(connman, peerman); sigman->StartWorkerThread(peerman); - clhandler->Start(); + clhandler->Start(*isman); llmq::quorumInstantSendManager->Start(peerman); } diff --git a/src/node/chainstate.cpp b/src/node/chainstate.cpp index 6365f1dde3804..156eadb615026 100644 --- a/src/node/chainstate.cpp +++ b/src/node/chainstate.cpp @@ -220,7 +220,6 @@ void DashChainstateSetup(ChainstateManager& chainman, // Same logic as pblocktree dmnman.reset(); dmnman = std::make_unique(chainman.ActiveChainstate(), *evodb); - mempool->ConnectManagers(dmnman.get()); cpoolman.reset(); cpoolman = std::make_unique(*evodb); @@ -235,6 +234,7 @@ void DashChainstateSetup(ChainstateManager& chainman, llmq_ctx.reset(); llmq_ctx = std::make_unique(chainman, *dmnman, *evodb, mn_metaman, *mnhf_manager, sporkman, *mempool, mn_activeman.get(), mn_sync, /*unit_tests=*/false, /*wipe=*/fReset || fReindexChainState); + mempool->ConnectManagers(dmnman.get(), llmq_ctx->isman); // Enable CMNHFManager::{Process, Undo}Block mnhf_manager->ConnectManagers(&chainman, llmq_ctx->qman.get()); diff --git a/src/test/evo_deterministicmns_tests.cpp b/src/test/evo_deterministicmns_tests.cpp index 8783081f9c7d6..6fab65178df0e 100644 --- a/src/test/evo_deterministicmns_tests.cpp +++ b/src/test/evo_deterministicmns_tests.cpp @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include @@ -653,7 +655,7 @@ void FuncTestMempoolReorg(TestChainSetup& setup) CTxMemPool testPool; if (setup.m_node.dmnman) { - testPool.ConnectManagers(setup.m_node.dmnman.get()); + testPool.ConnectManagers(setup.m_node.dmnman.get(), setup.m_node.llmq_ctx->isman); } TestMemPoolEntryHelper entry; LOCK2(cs_main, testPool.cs); @@ -727,7 +729,7 @@ void FuncTestMempoolDualProregtx(TestChainSetup& setup) CTxMemPool testPool; if (setup.m_node.dmnman) { - testPool.ConnectManagers(setup.m_node.dmnman.get()); + testPool.ConnectManagers(setup.m_node.dmnman.get(), setup.m_node.llmq_ctx->isman); } TestMemPoolEntryHelper entry; LOCK2(cs_main, testPool.cs); diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 65fa619d1f1fe..657d985a19596 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -125,7 +125,8 @@ void DashChainstateSetupClose(NodeContext& node) void DashPostChainstateSetup(NodeContext& node) { node.cj_ctx = std::make_unique(*node.chainman, *node.connman, *node.dmnman, *node.mn_metaman, *node.mempool, - /*mn_activeman=*/nullptr, *node.mn_sync, node.peerman, /*relay_txes=*/true); + /*mn_activeman=*/nullptr, *node.mn_sync, *node.llmq_ctx->isman, node.peerman, + /*relay_txes=*/true); #ifdef ENABLE_WALLET node.coinjoin_loader = interfaces::MakeCoinJoinLoader(*node.cj_ctx->walletman); #endif // ENABLE_WALLET diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 291599aea201e..d4adf717ce344 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -465,11 +465,13 @@ CTxMemPool::CTxMemPool(CBlockPolicyEstimator* estimator, int check_ratio) _clear(); //lock free clear } -void CTxMemPool::ConnectManagers(gsl::not_null dmnman) +void CTxMemPool::ConnectManagers(gsl::not_null dmnman, gsl::not_null isman) { // Do not allow double-initialization assert(m_dmnman == nullptr); m_dmnman = dmnman; + assert(m_isman == nullptr); + m_isman = isman; } bool CTxMemPool::isSpent(const COutPoint& outpoint) const @@ -1576,11 +1578,12 @@ void CTxMemPool::RemoveStaged(setEntries &stage, bool updateDescendants, MemPool int CTxMemPool::Expire(std::chrono::seconds time) { AssertLockHeld(cs); + assert(m_isman); indexed_transaction_set::index::type::iterator it = mapTx.get().begin(); setEntries toremove; while (it != mapTx.get().end() && it->GetTime() < time) { // locked txes do not expire until mined and have sufficient confirmations - if (llmq::quorumInstantSendManager->IsLocked(it->GetTx().GetHash())) { + if (m_isman->IsLocked(it->GetTx().GetHash())) { it++; continue; } diff --git a/src/txmempool.h b/src/txmempool.h index d7d49b91a7eef..80e12f4e7df58 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -319,6 +319,10 @@ struct ancestor_score {}; class CBlockPolicyEstimator; class CDeterministicMNManager; +namespace llmq { +class CInstantSendManager; +}; + /** * Information about a mempool transaction. */ @@ -430,6 +434,7 @@ class CTxMemPool std::atomic nTransactionsUpdated{0}; //!< Used by getblocktemplate to trigger CreateNewBlock() invocation CBlockPolicyEstimator* const minerPolicyEstimator; CDeterministicMNManager* m_dmnman{nullptr}; + llmq::CInstantSendManager* m_isman{nullptr}; uint64_t totalTxSize GUARDED_BY(cs); //!< sum of all mempool tx' byte sizes CAmount m_total_fee GUARDED_BY(cs); //!< sum of all mempool tx's fees (NOT modified fee) @@ -579,19 +584,19 @@ class CTxMemPool explicit CTxMemPool(CBlockPolicyEstimator* estimator = nullptr, int check_ratio = 0); /** - * Set CDeterministicMNManager pointer. + * Set CDeterministicMNManager and CInstantSendManager pointers. * * Separated from constructor as it's initialized after CTxMemPool * is created. Required for ProTx processing. */ - void ConnectManagers(gsl::not_null dmnman); + void ConnectManagers(gsl::not_null dmnman, gsl::not_null isman); /** - * Reset CDeterministicMNManager pointer. + * Reset CDeterministicMNManager and CInstantSendManager pointers. * - * @pre Must be called before CDeterministicMNManager is destroyed. + * @pre Must be called before CDeterministicMNManager and CInstantSendManager are destroyed. */ - void DisconnectManagers() { m_dmnman = nullptr; } + void DisconnectManagers() { m_dmnman = nullptr; m_isman = nullptr; } /** * If sanity-checking is turned on, check makes sure the pool is @@ -739,7 +744,10 @@ class CTxMemPool */ void TrimToSize(size_t sizelimit, std::vector* pvNoSpendsRemaining = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs); - /** Expire all transaction (and their dependencies) in the mempool older than time. Return the number of removed transactions. */ + /** Expire all transaction (and their dependencies) in the mempool older than time. Return the number of removed transactions. + * @pre Caller must ensure that CInstantSendManager exists and has been set using + * ConnectManagers() for InstantSend awareness + */ int Expire(std::chrono::seconds time) EXCLUSIVE_LOCKS_REQUIRED(cs); /** From 76a98858af51d9ea2b530aea3db18fb67229c64a Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Mon, 6 Jan 2025 16:08:47 +0000 Subject: [PATCH 06/11] refactor: remove `llmq::quorumInstantSendManager` global, move to `LLMQContext` --- src/llmq/context.cpp | 28 +++++-------------------- src/llmq/context.h | 2 +- src/llmq/instantsend.cpp | 2 -- src/llmq/instantsend.h | 3 --- src/node/chainstate.cpp | 2 +- src/rest.cpp | 2 +- src/rpc/mempool.cpp | 8 +++---- src/test/evo_deterministicmns_tests.cpp | 4 ++-- 8 files changed, 14 insertions(+), 37 deletions(-) diff --git a/src/llmq/context.cpp b/src/llmq/context.cpp index c31cb04d5b29a..9e8b4d117e45f 100644 --- a/src/llmq/context.cpp +++ b/src/llmq/context.cpp @@ -36,15 +36,8 @@ LLMQContext::LLMQContext(ChainstateManager& chainman, CDeterministicMNManager& d shareman{std::make_unique(*sigman, mn_activeman, *qman, sporkman)}, clhandler{std::make_unique(chainman.ActiveChainstate(), *qman, *sigman, *shareman, sporkman, mempool, mn_sync, is_masternode)}, - isman{[&]() -> llmq::CInstantSendManager* const { - assert(llmq::quorumInstantSendManager == nullptr); - llmq::quorumInstantSendManager = std::make_unique(*clhandler, - chainman.ActiveChainstate(), *qman, - *sigman, *shareman, sporkman, - mempool, mn_sync, is_masternode, - unit_tests, wipe); - return llmq::quorumInstantSendManager.get(); - }()}, + isman{std::make_unique(*clhandler, chainman.ActiveChainstate(), *qman, *sigman, *shareman, + sporkman, mempool, mn_sync, is_masternode, unit_tests, wipe)}, ehfSignalsHandler{std::make_unique(chainman, mnhfman, *sigman, *shareman, *qman)} { // Have to start it early to let VerifyDB check ChainLock signatures in coinbase @@ -53,23 +46,16 @@ LLMQContext::LLMQContext(ChainstateManager& chainman, CDeterministicMNManager& d LLMQContext::~LLMQContext() { bls_worker->Stop(); - - // LLMQContext doesn't own these objects, but still need to care of them for consistency: - llmq::quorumInstantSendManager.reset(); } void LLMQContext::Interrupt() { sigman->InterruptWorkerThread(); shareman->InterruptWorkerThread(); - - assert(isman == llmq::quorumInstantSendManager.get()); - llmq::quorumInstantSendManager->InterruptWorkerThread(); + isman->InterruptWorkerThread(); } void LLMQContext::Start(CConnman& connman, PeerManager& peerman) { - assert(isman == llmq::quorumInstantSendManager.get()); - if (is_masternode) { qdkgsman->StartThreads(connman, peerman); } @@ -77,17 +63,13 @@ void LLMQContext::Start(CConnman& connman, PeerManager& peerman) shareman->RegisterAsRecoveredSigsListener(); shareman->StartWorkerThread(connman, peerman); sigman->StartWorkerThread(peerman); - clhandler->Start(*isman); - llmq::quorumInstantSendManager->Start(peerman); + isman->Start(peerman); } void LLMQContext::Stop() { - assert(isman == llmq::quorumInstantSendManager.get()); - - llmq::quorumInstantSendManager->Stop(); + isman->Stop(); clhandler->Stop(); - shareman->StopWorkerThread(); shareman->UnregisterAsRecoveredSigsListener(); sigman->StopWorkerThread(); diff --git a/src/llmq/context.h b/src/llmq/context.h index b7f77b063a679..865d525a36fcd 100644 --- a/src/llmq/context.h +++ b/src/llmq/context.h @@ -67,7 +67,7 @@ struct LLMQContext { const std::unique_ptr sigman; const std::unique_ptr shareman; const std::unique_ptr clhandler; - llmq::CInstantSendManager* const isman; + const std::unique_ptr isman; // TODO: split CInstantSendManager and CInstantSendLock to 2 files const std::unique_ptr ehfSignalsHandler; }; diff --git a/src/llmq/instantsend.cpp b/src/llmq/instantsend.cpp index f5d9a9299b519..7e4e8c40567d7 100644 --- a/src/llmq/instantsend.cpp +++ b/src/llmq/instantsend.cpp @@ -41,8 +41,6 @@ static const std::string_view DB_ARCHIVED_BY_HASH = "is_a2"; static const std::string_view DB_VERSION = "is_v"; -std::unique_ptr quorumInstantSendManager; - uint256 CInstantSendLock::GetRequestId() const { CHashWriter hw(SER_GETHASH, 0); diff --git a/src/llmq/instantsend.h b/src/llmq/instantsend.h index 158ce1b699c98..6ccc8eaaa6ba0 100644 --- a/src/llmq/instantsend.h +++ b/src/llmq/instantsend.h @@ -365,9 +365,6 @@ class CInstantSendManager : public CRecoveredSigsListener bool IsInstantSendMempoolSigningEnabled() const; bool RejectConflictingBlocks() const; }; -// TODO: split CInstantSendManager and CInstantSendLock to 2 files -extern std::unique_ptr quorumInstantSendManager; - } // namespace llmq #endif // BITCOIN_LLMQ_INSTANTSEND_H diff --git a/src/node/chainstate.cpp b/src/node/chainstate.cpp index 156eadb615026..11ef560828177 100644 --- a/src/node/chainstate.cpp +++ b/src/node/chainstate.cpp @@ -234,7 +234,7 @@ void DashChainstateSetup(ChainstateManager& chainman, llmq_ctx.reset(); llmq_ctx = std::make_unique(chainman, *dmnman, *evodb, mn_metaman, *mnhf_manager, sporkman, *mempool, mn_activeman.get(), mn_sync, /*unit_tests=*/false, /*wipe=*/fReset || fReindexChainState); - mempool->ConnectManagers(dmnman.get(), llmq_ctx->isman); + mempool->ConnectManagers(dmnman.get(), llmq_ctx->isman.get()); // Enable CMNHFManager::{Process, Undo}Block mnhf_manager->ConnectManagers(&chainman, llmq_ctx->qman.get()); diff --git a/src/rest.cpp b/src/rest.cpp index 027137dcee845..a144b71cf139f 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -636,7 +636,7 @@ static bool rest_mempool_contents(const CoreContext& context, HTTPRequest* req, const LLMQContext* llmq_ctx = GetLLMQContext(context, req); if (!llmq_ctx) return false; - UniValue mempoolObject = MempoolToJSON(*mempool, llmq_ctx->isman, true); + UniValue mempoolObject = MempoolToJSON(*mempool, llmq_ctx->isman.get(), true); std::string strJSON = mempoolObject.write() + "\n"; req->WriteHeader("Content-Type", "application/json"); diff --git a/src/rpc/mempool.cpp b/src/rpc/mempool.cpp index ca1c3af5d0f63..3aa482e42e23d 100644 --- a/src/rpc/mempool.cpp +++ b/src/rpc/mempool.cpp @@ -201,7 +201,7 @@ RPCHelpMan getrawmempool() const CTxMemPool& mempool = EnsureMemPool(node); const LLMQContext& llmq_ctx = EnsureLLMQContext(node); - return MempoolToJSON(mempool, llmq_ctx.isman, fVerbose, include_mempool_sequence); + return MempoolToJSON(mempool, llmq_ctx.isman.get(), fVerbose, include_mempool_sequence); }, }; } @@ -264,7 +264,7 @@ RPCHelpMan getmempoolancestors() const CTxMemPoolEntry &e = *ancestorIt; const uint256& _hash = e.GetTx().GetHash(); UniValue info(UniValue::VOBJ); - entryToJSON(mempool, info, e, llmq_ctx.isman); + entryToJSON(mempool, info, e, llmq_ctx.isman.get()); o.pushKV(_hash.ToString(), info); } return o; @@ -332,7 +332,7 @@ RPCHelpMan getmempooldescendants() const CTxMemPoolEntry &e = *descendantIt; const uint256& _hash = e.GetTx().GetHash(); UniValue info(UniValue::VOBJ); - entryToJSON(mempool, info, e, llmq_ctx.isman); + entryToJSON(mempool, info, e, llmq_ctx.isman.get()); o.pushKV(_hash.ToString(), info); } return o; @@ -372,7 +372,7 @@ RPCHelpMan getmempoolentry() const CTxMemPoolEntry &e = *it; UniValue info(UniValue::VOBJ); const LLMQContext& llmq_ctx = EnsureLLMQContext(node); - entryToJSON(mempool, info, e, llmq_ctx.isman); + entryToJSON(mempool, info, e, llmq_ctx.isman.get()); return info; }, }; diff --git a/src/test/evo_deterministicmns_tests.cpp b/src/test/evo_deterministicmns_tests.cpp index 6fab65178df0e..0f4133fba900f 100644 --- a/src/test/evo_deterministicmns_tests.cpp +++ b/src/test/evo_deterministicmns_tests.cpp @@ -655,7 +655,7 @@ void FuncTestMempoolReorg(TestChainSetup& setup) CTxMemPool testPool; if (setup.m_node.dmnman) { - testPool.ConnectManagers(setup.m_node.dmnman.get(), setup.m_node.llmq_ctx->isman); + testPool.ConnectManagers(setup.m_node.dmnman.get(), setup.m_node.llmq_ctx->isman.get()); } TestMemPoolEntryHelper entry; LOCK2(cs_main, testPool.cs); @@ -729,7 +729,7 @@ void FuncTestMempoolDualProregtx(TestChainSetup& setup) CTxMemPool testPool; if (setup.m_node.dmnman) { - testPool.ConnectManagers(setup.m_node.dmnman.get(), setup.m_node.llmq_ctx->isman); + testPool.ConnectManagers(setup.m_node.dmnman.get(), setup.m_node.llmq_ctx->isman.get()); } TestMemPoolEntryHelper entry; LOCK2(cs_main, testPool.cs); From 9996cd6967c1a04a80967c111a738b4502c491a1 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Mon, 6 Jan 2025 16:10:52 +0000 Subject: [PATCH 07/11] trivial: ensure `LLMQContext::{Start,Stop,Interrupt}` are consistent The order of `Start` should match the initialization order while the order of `Interrupt` and `Stop` should be in the reverse order. --- src/llmq/context.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/llmq/context.cpp b/src/llmq/context.cpp index 9e8b4d117e45f..f1958c4457d15 100644 --- a/src/llmq/context.cpp +++ b/src/llmq/context.cpp @@ -49,9 +49,9 @@ LLMQContext::~LLMQContext() { } void LLMQContext::Interrupt() { - sigman->InterruptWorkerThread(); - shareman->InterruptWorkerThread(); isman->InterruptWorkerThread(); + shareman->InterruptWorkerThread(); + sigman->InterruptWorkerThread(); } void LLMQContext::Start(CConnman& connman, PeerManager& peerman) @@ -60,9 +60,9 @@ void LLMQContext::Start(CConnman& connman, PeerManager& peerman) qdkgsman->StartThreads(connman, peerman); } qman->Start(); + sigman->StartWorkerThread(peerman); shareman->RegisterAsRecoveredSigsListener(); shareman->StartWorkerThread(connman, peerman); - sigman->StartWorkerThread(peerman); clhandler->Start(*isman); isman->Start(peerman); } From dda0cc69090cf0d80126a41e43025b0d8f6f8ca3 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Sun, 22 Dec 2024 20:02:10 +0000 Subject: [PATCH 08/11] trivial: clean up arguments formatting in `src/llmq/utils.{cpp,h}` --- src/llmq/utils.cpp | 91 ++++++++++++++++++++++++++-------------------- src/llmq/utils.h | 21 +++++------ 2 files changed, 61 insertions(+), 51 deletions(-) diff --git a/src/llmq/utils.cpp b/src/llmq/utils.cpp index a9bb1e3c81fec..ea446fa5e464d 100644 --- a/src/llmq/utils.cpp +++ b/src/llmq/utils.cpp @@ -24,12 +24,11 @@ #include class CBLSSignature; -namespace llmq -{ +namespace llmq { class CQuorum; using CQuorumPtr = std::shared_ptr; using CQuorumCPtr = std::shared_ptr; -} +} // namespace llmq /** * Forward declarations @@ -46,13 +45,9 @@ static bool IsV20Active(gsl::not_null pindexPrev) return DeploymentActiveAfter(pindexPrev, Params().GetConsensus(), Consensus::DEPLOYMENT_V20); } -namespace llmq -{ - -namespace utils - -{ -//QuorumMembers per quorumIndex at heights H-Cycle, H-2Cycles, H-3Cycles +namespace llmq { +namespace utils { +// QuorumMembers per quorumIndex at heights H-Cycle, H-2Cycles, H-3Cycles struct PreviousQuorumQuarters { std::vector> quarterHMinusC; std::vector> quarterHMinus2C; @@ -62,16 +57,32 @@ struct PreviousQuorumQuarters { }; // Forward declarations -static std::vector ComputeQuorumMembers(Consensus::LLMQType llmqType, CDeterministicMNManager& dmnman, const CBlockIndex* pQuorumBaseBlockIndex); -static std::vector> ComputeQuorumMembersByQuarterRotation(const Consensus::LLMQParams& llmqParams, CDeterministicMNManager& dmnman, const CBlockIndex* pCycleQuorumBaseBlockIndex); - -static std::vector> BuildNewQuorumQuarterMembers(const Consensus::LLMQParams& llmqParams, CDeterministicMNManager& dmnman, const CBlockIndex* pCycleQuorumBaseBlockIndex, const PreviousQuorumQuarters& quarters); - -static PreviousQuorumQuarters GetPreviousQuorumQuarterMembers(const Consensus::LLMQParams& llmqParams, CDeterministicMNManager& dmnman, const CBlockIndex* pBlockHMinusCIndex, const CBlockIndex* pBlockHMinus2CIndex, const CBlockIndex* pBlockHMinus3CIndex, int nHeight); -static std::vector> GetQuorumQuarterMembersBySnapshot(const Consensus::LLMQParams& llmqParams, CDeterministicMNManager& dmnman, const CBlockIndex* pCycleQuorumBaseBlockIndex, const llmq::CQuorumSnapshot& snapshot, int nHeights); -static std::pair GetMNUsageBySnapshot(const Consensus::LLMQParams& llmqParams, CDeterministicMNManager& dmnman, const CBlockIndex* pCycleQuorumBaseBlockIndex, const llmq::CQuorumSnapshot& snapshot, int nHeight); - -static void BuildQuorumSnapshot(const Consensus::LLMQParams& llmqParams, const CDeterministicMNList& allMns, const CDeterministicMNList& mnUsedAtH, std::vector& sortedCombinedMns, CQuorumSnapshot& quorumSnapshot, int nHeight, std::vector& skipList, const CBlockIndex* pCycleQuorumBaseBlockIndex); +static std::vector ComputeQuorumMembers(Consensus::LLMQType llmqType, CDeterministicMNManager& dmnman, + const CBlockIndex* pQuorumBaseBlockIndex); +static std::vector> ComputeQuorumMembersByQuarterRotation( + const Consensus::LLMQParams& llmqParams, CDeterministicMNManager& dmnman, + const CBlockIndex* pCycleQuorumBaseBlockIndex); + +static std::vector> BuildNewQuorumQuarterMembers( + const Consensus::LLMQParams& llmqParams, CDeterministicMNManager& dmnman, + const CBlockIndex* pCycleQuorumBaseBlockIndex, const PreviousQuorumQuarters& previousQuarters); + +static PreviousQuorumQuarters GetPreviousQuorumQuarterMembers(const Consensus::LLMQParams& llmqParams, + CDeterministicMNManager& dmnman, + const CBlockIndex* pBlockHMinusCIndex, + const CBlockIndex* pBlockHMinus2CIndex, + const CBlockIndex* pBlockHMinus3CIndex, int nHeight); +static std::vector> GetQuorumQuarterMembersBySnapshot( + const Consensus::LLMQParams& llmqParams, CDeterministicMNManager& dmnman, + const CBlockIndex* pCycleQuorumBaseBlockIndex, const llmq::CQuorumSnapshot& snapshot, int nHeight); +static std::pair GetMNUsageBySnapshot( + const Consensus::LLMQParams& llmqParams, CDeterministicMNManager& dmnman, + const CBlockIndex* pCycleQuorumBaseBlockIndex, const llmq::CQuorumSnapshot& snapshot, int nHeight); + +static void BuildQuorumSnapshot(const Consensus::LLMQParams& llmqParams, const CDeterministicMNList& allMns, + const CDeterministicMNList& mnUsedAtH, + std::vector& sortedCombinedMns, CQuorumSnapshot& quorumSnapshot, + int nHeight, std::vector& skipList, const CBlockIndex* pCycleQuorumBaseBlockIndex); static uint256 GetHashModifier(const Consensus::LLMQParams& llmqParams, gsl::not_null pCycleQuorumBaseBlockIndex) { @@ -97,7 +108,9 @@ static uint256 GetHashModifier(const Consensus::LLMQParams& llmqParams, gsl::not return ::SerializeHash(std::make_pair(llmqParams.type, pCycleQuorumBaseBlockIndex->GetBlockHash())); } -std::vector GetAllQuorumMembers(Consensus::LLMQType llmqType, CDeterministicMNManager& dmnman, gsl::not_null pQuorumBaseBlockIndex, bool reset_cache) +std::vector GetAllQuorumMembers(Consensus::LLMQType llmqType, CDeterministicMNManager& dmnman, + gsl::not_null pQuorumBaseBlockIndex, + bool reset_cache) { static RecursiveMutex cs_members; static std::map, StaticSaltedHasher>> mapQuorumMembers GUARDED_BY(cs_members); @@ -172,7 +185,8 @@ std::vector GetAllQuorumMembers(Consensus::LLMQType llmqTy return quorumMembers; } -std::vector ComputeQuorumMembers(Consensus::LLMQType llmqType, CDeterministicMNManager& dmnman, const CBlockIndex* pQuorumBaseBlockIndex) +std::vector ComputeQuorumMembers(Consensus::LLMQType llmqType, CDeterministicMNManager& dmnman, + const CBlockIndex* pQuorumBaseBlockIndex) { bool EvoOnly = (Params().GetConsensus().llmqTypePlatform == llmqType) && IsV19Active(pQuorumBaseBlockIndex); const auto& llmq_params_opt = Params().GetLLMQ(llmqType); @@ -190,7 +204,8 @@ std::vector ComputeQuorumMembers(Consensus::LLMQType llmqT return allMns.CalculateQuorum(llmq_params_opt->size, modifier, EvoOnly); } -std::vector> ComputeQuorumMembersByQuarterRotation(const Consensus::LLMQParams& llmqParams, CDeterministicMNManager& dmnman, const CBlockIndex* pCycleQuorumBaseBlockIndex) +std::vector> ComputeQuorumMembersByQuarterRotation( + const Consensus::LLMQParams& llmqParams, CDeterministicMNManager& dmnman, const CBlockIndex* pCycleQuorumBaseBlockIndex) { const Consensus::LLMQType llmqType = llmqParams.type; @@ -268,8 +283,7 @@ PreviousQuorumQuarters GetPreviousQuorumQuarterMembers(const Consensus::LLMQPara CDeterministicMNManager& dmnman, const CBlockIndex* pBlockHMinusCIndex, const CBlockIndex* pBlockHMinus2CIndex, - const CBlockIndex* pBlockHMinus3CIndex, - int nHeight) + const CBlockIndex* pBlockHMinus3CIndex, int nHeight) { size_t nQuorums = static_cast(llmqParams.signingActiveQuorumCount); PreviousQuorumQuarters quarters{nQuorums}; @@ -461,7 +475,8 @@ std::vector> BuildNewQuorumQuarterMembers(cons void BuildQuorumSnapshot(const Consensus::LLMQParams& llmqParams, const CDeterministicMNList& allMns, const CDeterministicMNList& mnUsedAtH, std::vector& sortedCombinedMns, - CQuorumSnapshot& quorumSnapshot, int nHeight, std::vector& skipList, const CBlockIndex* pCycleQuorumBaseBlockIndex) + CQuorumSnapshot& quorumSnapshot, int nHeight, std::vector& skipList, + const CBlockIndex* pCycleQuorumBaseBlockIndex) { if (!llmqParams.useRotation || pCycleQuorumBaseBlockIndex->nHeight % llmqParams.dkgInterval != 0) { ASSERT_IF_DEBUG(false); @@ -494,11 +509,9 @@ void BuildQuorumSnapshot(const Consensus::LLMQParams& llmqParams, const CDetermi } } -std::vector> GetQuorumQuarterMembersBySnapshot(const Consensus::LLMQParams& llmqParams, - CDeterministicMNManager& dmnman, - const CBlockIndex* pCycleQuorumBaseBlockIndex, - const llmq::CQuorumSnapshot& snapshot, - int nHeight) +std::vector> GetQuorumQuarterMembersBySnapshot( + const Consensus::LLMQParams& llmqParams, CDeterministicMNManager& dmnman, + const CBlockIndex* pCycleQuorumBaseBlockIndex, const llmq::CQuorumSnapshot& snapshot, int nHeight) { if (!llmqParams.useRotation || pCycleQuorumBaseBlockIndex->nHeight % llmqParams.dkgInterval != 0) { ASSERT_IF_DEBUG(false); @@ -756,9 +769,10 @@ std::set CalcDeterministicWatchConnections(Consensus::LLMQType llmqType, return result; } -bool EnsureQuorumConnections(const Consensus::LLMQParams& llmqParams, CConnman& connman, CDeterministicMNManager& dmnman, const CSporkManager& sporkman, - const CDeterministicMNList& tip_mn_list, gsl::not_null pQuorumBaseBlockIndex, - const uint256& myProTxHash, bool is_masternode) +bool EnsureQuorumConnections(const Consensus::LLMQParams& llmqParams, CConnman& connman, CDeterministicMNManager& dmnman, + const CSporkManager& sporkman, const CDeterministicMNList& tip_mn_list, + gsl::not_null pQuorumBaseBlockIndex, const uint256& myProTxHash, + bool is_masternode) { if (!is_masternode && !IsWatchQuorumsEnabled()) { return false; @@ -812,9 +826,10 @@ bool EnsureQuorumConnections(const Consensus::LLMQParams& llmqParams, CConnman& return true; } -void AddQuorumProbeConnections(const Consensus::LLMQParams& llmqParams, CConnman& connman, CDeterministicMNManager& dmnman, - CMasternodeMetaMan& mn_metaman, const CSporkManager& sporkman, const CDeterministicMNList& tip_mn_list, - gsl::not_null pQuorumBaseBlockIndex, const uint256 &myProTxHash) +void AddQuorumProbeConnections(const Consensus::LLMQParams& llmqParams, CConnman& connman, + CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, + const CSporkManager& sporkman, const CDeterministicMNList& tip_mn_list, + gsl::not_null pQuorumBaseBlockIndex, const uint256& myProTxHash) { assert(mn_metaman.IsValid()); @@ -868,7 +883,5 @@ template void InitQuorumsCache, StaticSaltedHasher, 0ul, 0ul>, std::less, std::allocator, StaticSaltedHasher, 0ul, 0ul>>>>>(std::map, StaticSaltedHasher, 0ul, 0ul>, std::less, std::allocator, StaticSaltedHasher, 0ul, 0ul>>>>&cache, bool limit_by_connections); template void InitQuorumsCache>>(std::map>& cache, bool limit_by_connections); template void InitQuorumsCache>>(std::map>& cache, bool limit_by_connections); - } // namespace utils - } // namespace llmq diff --git a/src/llmq/utils.h b/src/llmq/utils.h index 2795db58dc1e0..594c1874204ef 100644 --- a/src/llmq/utils.h +++ b/src/llmq/utils.h @@ -26,14 +26,12 @@ class CSporkManager; using CDeterministicMNCPtr = std::shared_ptr; -namespace llmq -{ - -namespace utils -{ - +namespace llmq { +namespace utils { // includes members which failed DKG -std::vector GetAllQuorumMembers(Consensus::LLMQType llmqType, CDeterministicMNManager& dmnman, gsl::not_null pQuorumBaseBlockIndex, bool reset_cache = false); +std::vector GetAllQuorumMembers(Consensus::LLMQType llmqType, CDeterministicMNManager& dmnman, + gsl::not_null pQuorumBaseBlockIndex, + bool reset_cache = false); uint256 DeterministicOutboundConnection(const uint256& proTxHash1, const uint256& proTxHash2); std::unordered_set GetQuorumConnections( @@ -45,18 +43,17 @@ std::unordered_set GetQuorumRelayMembers(const Cons const uint256& forMember, bool onlyOutbound); std::set CalcDeterministicWatchConnections(Consensus::LLMQType llmqType, gsl::not_null pQuorumBaseBlockIndex, size_t memberCount, size_t connectionCount); -bool EnsureQuorumConnections(const Consensus::LLMQParams& llmqParams, CConnman& connman, CDeterministicMNManager& dmnman, const CSporkManager& sporkman, - const CDeterministicMNList& tip_mn_list, gsl::not_null pQuorumBaseBlockIndex, - const uint256& myProTxHash, bool is_masternode); +bool EnsureQuorumConnections(const Consensus::LLMQParams& llmqParams, CConnman& connman, CDeterministicMNManager& dmnman, + const CSporkManager& sporkman, const CDeterministicMNList& tip_mn_list, + gsl::not_null pQuorumBaseBlockIndex, const uint256& myProTxHash, + bool is_masternode); void AddQuorumProbeConnections(const Consensus::LLMQParams& llmqParams, CConnman& connman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, const CSporkManager& sporkman, const CDeterministicMNList& tip_mn_list, gsl::not_null pQuorumBaseBlockIndex, const uint256& myProTxHash); template void InitQuorumsCache(CacheType& cache, bool limit_by_connections = true); - } // namespace utils - } // namespace llmq #endif // BITCOIN_LLMQ_UTILS_H From 7125330f1ad8b2892ae150204b44fac2b078c93c Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Wed, 1 Jan 2025 06:02:12 +0000 Subject: [PATCH 09/11] refactor: pass `llmq::CQuorumSnapshotManager` by argument --- src/evo/cbtx.cpp | 11 ++--- src/evo/cbtx.h | 10 +++-- src/evo/chainhelper.cpp | 8 ++-- src/evo/chainhelper.h | 9 ++-- src/evo/deterministicmns.cpp | 21 +++++++--- src/evo/deterministicmns.h | 17 ++++---- src/evo/specialtxman.cpp | 21 ++++++---- src/evo/specialtxman.h | 20 +++++++-- src/llmq/blockprocessor.cpp | 19 +++++---- src/llmq/blockprocessor.h | 7 +++- src/llmq/commitment.cpp | 11 +++-- src/llmq/commitment.h | 8 +++- src/llmq/context.cpp | 12 +++--- src/llmq/debug.cpp | 12 +++--- src/llmq/debug.h | 9 ++-- src/llmq/dkgsession.cpp | 11 +++-- src/llmq/dkgsession.h | 6 ++- src/llmq/dkgsessionhandler.cpp | 12 ++++-- src/llmq/dkgsessionhandler.h | 7 +++- src/llmq/dkgsessionmgr.cpp | 9 ++-- src/llmq/dkgsessionmgr.h | 7 +++- src/llmq/quorums.cpp | 9 ++-- src/llmq/quorums.h | 6 ++- src/llmq/snapshot.cpp | 13 +++--- src/llmq/snapshot.h | 3 +- src/llmq/utils.cpp | 75 +++++++++++++++++++--------------- src/llmq/utils.h | 21 ++++++---- src/net_processing.cpp | 2 +- src/node/chainstate.cpp | 3 +- src/node/miner.cpp | 4 +- src/node/miner.h | 2 + src/rpc/quorums.cpp | 15 ++++--- src/test/util/setup_common.cpp | 2 +- 33 files changed, 249 insertions(+), 153 deletions(-) diff --git a/src/evo/cbtx.cpp b/src/evo/cbtx.cpp index fc08bd5db57fd..fca6a504032b8 100644 --- a/src/evo/cbtx.cpp +++ b/src/evo/cbtx.cpp @@ -62,8 +62,8 @@ bool CheckCbTx(const CTransaction& tx, const CBlockIndex* pindexPrev, TxValidati // This can only be done after the block has been fully processed, as otherwise we won't have the finished MN list bool CheckCbTxMerkleRoots(const CBlock& block, const CBlockIndex* pindex, CDeterministicMNManager& dmnman, - const llmq::CQuorumBlockProcessor& quorum_block_processor, BlockValidationState& state, - const CCoinsViewCache& view) + llmq::CQuorumSnapshotManager& qsnapman, const llmq::CQuorumBlockProcessor& quorum_block_processor, + BlockValidationState& state, const CCoinsViewCache& view) { if (block.vtx[0]->nType != TRANSACTION_COINBASE) { return true; @@ -87,7 +87,7 @@ bool CheckCbTxMerkleRoots(const CBlock& block, const CBlockIndex* pindex, CDeter static int64_t nTimeMerkleQuorum = 0; uint256 calculatedMerkleRoot; - if (!CalcCbTxMerkleRootMNList(block, pindex->pprev, calculatedMerkleRoot, dmnman, state, view)) { + if (!CalcCbTxMerkleRootMNList(block, pindex->pprev, calculatedMerkleRoot, state, dmnman, qsnapman, view)) { // pass the state returned by the function above return false; } @@ -117,7 +117,8 @@ bool CheckCbTxMerkleRoots(const CBlock& block, const CBlockIndex* pindex, CDeter } bool CalcCbTxMerkleRootMNList(const CBlock& block, const CBlockIndex* pindexPrev, uint256& merkleRootRet, - CDeterministicMNManager& dmnman, BlockValidationState& state, const CCoinsViewCache& view) + BlockValidationState& state, CDeterministicMNManager& dmnman, + llmq::CQuorumSnapshotManager& qsnapman, const CCoinsViewCache& view) { try { static std::atomic nTimeDMN = 0; @@ -127,7 +128,7 @@ bool CalcCbTxMerkleRootMNList(const CBlock& block, const CBlockIndex* pindexPrev int64_t nTime1 = GetTimeMicros(); CDeterministicMNList tmpMNList; - if (!dmnman.BuildNewListFromBlock(block, pindexPrev, state, view, tmpMNList, false)) { + if (!dmnman.BuildNewListFromBlock(block, pindexPrev, state, view, tmpMNList, qsnapman, false)) { // pass the state returned by the function above return false; } diff --git a/src/evo/cbtx.h b/src/evo/cbtx.h index ad6b74d10fb90..ae29f2fc700de 100644 --- a/src/evo/cbtx.h +++ b/src/evo/cbtx.h @@ -19,8 +19,9 @@ class CDeterministicMNManager; class TxValidationState; namespace llmq { -class CQuorumBlockProcessor; class CChainLocksHandler; +class CQuorumBlockProcessor; +class CQuorumSnapshotManager; }// namespace llmq // Forward declaration from core_io to get rid of circular dependency @@ -87,10 +88,11 @@ template<> struct is_serializable_enum : std::true_type {}; bool CheckCbTx(const CTransaction& tx, const CBlockIndex* pindexPrev, TxValidationState& state); bool CheckCbTxMerkleRoots(const CBlock& block, const CBlockIndex* pindex, CDeterministicMNManager& dmnman, - const llmq::CQuorumBlockProcessor& quorum_block_processor, BlockValidationState& state, - const CCoinsViewCache& view); + llmq::CQuorumSnapshotManager& qsnapman, const llmq::CQuorumBlockProcessor& quorum_block_processor, + BlockValidationState& state, const CCoinsViewCache& view); bool CalcCbTxMerkleRootMNList(const CBlock& block, const CBlockIndex* pindexPrev, uint256& merkleRootRet, - CDeterministicMNManager& dmnman, BlockValidationState& state, const CCoinsViewCache& view); + BlockValidationState& state, CDeterministicMNManager& dmnman, + llmq::CQuorumSnapshotManager& qsnapman, const CCoinsViewCache& view); bool CalcCbTxMerkleRootQuorums(const CBlock& block, const CBlockIndex* pindexPrev, const llmq::CQuorumBlockProcessor& quorum_block_processor, uint256& merkleRootRet, BlockValidationState& state); diff --git a/src/evo/chainhelper.cpp b/src/evo/chainhelper.cpp index b0413dade5a40..f2a042bd984a4 100644 --- a/src/evo/chainhelper.cpp +++ b/src/evo/chainhelper.cpp @@ -11,16 +11,16 @@ #include CChainstateHelper::CChainstateHelper(CCreditPoolManager& cpoolman, CDeterministicMNManager& dmnman, - CMNHFManager& mnhfman, CGovernanceManager& govman, - llmq::CInstantSendManager& isman, llmq::CQuorumBlockProcessor& qblockman, + CMNHFManager& mnhfman, CGovernanceManager& govman, llmq::CInstantSendManager& isman, + llmq::CQuorumBlockProcessor& qblockman, llmq::CQuorumSnapshotManager& qsnapman, const ChainstateManager& chainman, const Consensus::Params& consensus_params, const CMasternodeSync& mn_sync, const CSporkManager& sporkman, const llmq::CChainLocksHandler& clhandler, const llmq::CQuorumManager& qman) : isman{isman}, clhandler{clhandler}, mn_payments{std::make_unique(dmnman, govman, chainman, consensus_params, mn_sync, sporkman)}, - special_tx{std::make_unique(cpoolman, dmnman, mnhfman, qblockman, chainman, consensus_params, - clhandler, qman)} + special_tx{std::make_unique(cpoolman, dmnman, mnhfman, qblockman, qsnapman, chainman, + consensus_params, clhandler, qman)} {} CChainstateHelper::~CChainstateHelper() = default; diff --git a/src/evo/chainhelper.h b/src/evo/chainhelper.h index 2954d24fb39cf..82b6597e3af6d 100644 --- a/src/evo/chainhelper.h +++ b/src/evo/chainhelper.h @@ -26,6 +26,7 @@ class CChainLocksHandler; class CInstantSendManager; class CQuorumBlockProcessor; class CQuorumManager; +class CQuorumSnapshotManager; } class CChainstateHelper @@ -37,10 +38,10 @@ class CChainstateHelper public: explicit CChainstateHelper(CCreditPoolManager& cpoolman, CDeterministicMNManager& dmnman, CMNHFManager& mnhfman, CGovernanceManager& govman, llmq::CInstantSendManager& isman, - llmq::CQuorumBlockProcessor& qblockman, const ChainstateManager& chainman, - const Consensus::Params& consensus_params, const CMasternodeSync& mn_sync, - const CSporkManager& sporkman, const llmq::CChainLocksHandler& clhandler, - const llmq::CQuorumManager& qman); + llmq::CQuorumBlockProcessor& qblockman, llmq::CQuorumSnapshotManager& qsnapman, + const ChainstateManager& chainman, const Consensus::Params& consensus_params, + const CMasternodeSync& mn_sync, const CSporkManager& sporkman, + const llmq::CChainLocksHandler& clhandler, const llmq::CQuorumManager& qman); ~CChainstateHelper(); CChainstateHelper() = delete; diff --git a/src/evo/deterministicmns.cpp b/src/evo/deterministicmns.cpp index 96fbe4c02cf02..f997859eddcd8 100644 --- a/src/evo/deterministicmns.cpp +++ b/src/evo/deterministicmns.cpp @@ -595,7 +595,10 @@ void CDeterministicMNList::RemoveMN(const uint256& proTxHash) mnInternalIdMap = mnInternalIdMap.erase(dmn->GetInternalId()); } -bool CDeterministicMNManager::ProcessBlock(const CBlock& block, gsl::not_null pindex, BlockValidationState& state, const CCoinsViewCache& view, bool fJustCheck, std::optional& updatesRet) +bool CDeterministicMNManager::ProcessBlock(const CBlock& block, gsl::not_null pindex, + BlockValidationState& state, const CCoinsViewCache& view, + llmq::CQuorumSnapshotManager& qsnapman, bool fJustCheck, + std::optional& updatesRet) { AssertLockHeld(cs_main); @@ -610,7 +613,7 @@ bool CDeterministicMNManager::ProcessBlock(const CBlock& block, gsl::not_nullnHeight; try { - if (!BuildNewListFromBlock(block, pindex->pprev, state, view, newList, true)) { + if (!BuildNewListFromBlock(block, pindex->pprev, state, view, newList, qsnapman, true)) { // pass the state returned by the function above return false; } @@ -700,7 +703,10 @@ void CDeterministicMNManager::UpdatedBlockTip(gsl::not_null tipIndex = pindex; } -bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, gsl::not_null pindexPrev, BlockValidationState& state, const CCoinsViewCache& view, CDeterministicMNList& mnListRet, bool debugLogs) +bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, gsl::not_null pindexPrev, + BlockValidationState& state, const CCoinsViewCache& view, + CDeterministicMNList& mnListRet, + llmq::CQuorumSnapshotManager& qsnapman, bool debugLogs) { int nHeight = pindexPrev->nHeight + 1; @@ -923,7 +929,7 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, gsl::no return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-qc-quorum-hash"); } - HandleQuorumCommitment(opt_qc->commitment, pQuorumBaseBlockIndex, newList, debugLogs); + HandleQuorumCommitment(opt_qc->commitment, pQuorumBaseBlockIndex, newList, qsnapman, debugLogs); } } } @@ -995,11 +1001,14 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, gsl::no return true; } -void CDeterministicMNManager::HandleQuorumCommitment(const llmq::CFinalCommitment& qc, gsl::not_null pQuorumBaseBlockIndex, CDeterministicMNList& mnList, bool debugLogs) +void CDeterministicMNManager::HandleQuorumCommitment(const llmq::CFinalCommitment& qc, + gsl::not_null pQuorumBaseBlockIndex, + CDeterministicMNList& mnList, + llmq::CQuorumSnapshotManager& qsnapman, bool debugLogs) { // The commitment has already been validated at this point, so it's safe to use members of it - auto members = llmq::utils::GetAllQuorumMembers(qc.llmqType, *this, pQuorumBaseBlockIndex); + auto members = llmq::utils::GetAllQuorumMembers(qc.llmqType, *this, qsnapman, pQuorumBaseBlockIndex); for (size_t i = 0; i < members.size(); i++) { if (!mnList.HasMN(members[i]->proTxHash)) { diff --git a/src/evo/deterministicmns.h b/src/evo/deterministicmns.h index 81621d8bd9863..0fde8da19b7ec 100644 --- a/src/evo/deterministicmns.h +++ b/src/evo/deterministicmns.h @@ -35,9 +35,9 @@ class TxValidationState; extern RecursiveMutex cs_main; -namespace llmq -{ - class CFinalCommitment; +namespace llmq { +class CFinalCommitment; +class CQuorumSnapshotManager; } // namespace llmq class CDeterministicMN @@ -598,15 +598,18 @@ class CDeterministicMNManager ~CDeterministicMNManager() = default; bool ProcessBlock(const CBlock& block, gsl::not_null pindex, BlockValidationState& state, - const CCoinsViewCache& view, bool fJustCheck, std::optional& updatesRet) EXCLUSIVE_LOCKS_REQUIRED(!cs, cs_main); + const CCoinsViewCache& view, llmq::CQuorumSnapshotManager& qsnapman, bool fJustCheck, + std::optional& updatesRet) EXCLUSIVE_LOCKS_REQUIRED(!cs, cs_main); bool UndoBlock(gsl::not_null pindex, std::optional& updatesRet) EXCLUSIVE_LOCKS_REQUIRED(!cs); void UpdatedBlockTip(gsl::not_null pindex) EXCLUSIVE_LOCKS_REQUIRED(!cs); // the returned list will not contain the correct block hash (we can't know it yet as the coinbase TX is not updated yet) - bool BuildNewListFromBlock(const CBlock& block, gsl::not_null pindexPrev, BlockValidationState& state, const CCoinsViewCache& view, - CDeterministicMNList& mnListRet, bool debugLogs) EXCLUSIVE_LOCKS_REQUIRED(!cs); - void HandleQuorumCommitment(const llmq::CFinalCommitment& qc, gsl::not_null pQuorumBaseBlockIndex, CDeterministicMNList& mnList, bool debugLogs); + bool BuildNewListFromBlock(const CBlock& block, gsl::not_null pindexPrev, + BlockValidationState& state, const CCoinsViewCache& view, CDeterministicMNList& mnListRet, + llmq::CQuorumSnapshotManager& qsnapman, bool debugLogs) EXCLUSIVE_LOCKS_REQUIRED(!cs); + void HandleQuorumCommitment(const llmq::CFinalCommitment& qc, gsl::not_null pQuorumBaseBlockIndex, + CDeterministicMNList& mnList, llmq::CQuorumSnapshotManager& qsnapman, bool debugLogs); CDeterministicMNList GetListForBlock(gsl::not_null pindex) EXCLUSIVE_LOCKS_REQUIRED(!cs) { LOCK(cs); diff --git a/src/evo/specialtxman.cpp b/src/evo/specialtxman.cpp index 969efa2703055..9c74d35d4801f 100644 --- a/src/evo/specialtxman.cpp +++ b/src/evo/specialtxman.cpp @@ -19,10 +19,11 @@ #include #include -static bool CheckSpecialTxInner(CDeterministicMNManager& dmnman, const ChainstateManager& chainman, - const llmq::CQuorumManager& qman, const CTransaction& tx, const CBlockIndex* pindexPrev, - const CCoinsViewCache& view, const std::optional& indexes, bool check_sigs, - TxValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) +static bool CheckSpecialTxInner(CDeterministicMNManager& dmnman, llmq::CQuorumSnapshotManager& qsnapman, + const ChainstateManager& chainman, const llmq::CQuorumManager& qman, + const CTransaction& tx, const CBlockIndex* pindexPrev, const CCoinsViewCache& view, + const std::optional& indexes, bool check_sigs, TxValidationState& state) + EXCLUSIVE_LOCKS_REQUIRED(::cs_main) { AssertLockHeld(cs_main); @@ -47,7 +48,7 @@ static bool CheckSpecialTxInner(CDeterministicMNManager& dmnman, const Chainstat case TRANSACTION_COINBASE: return CheckCbTx(tx, pindexPrev, state); case TRANSACTION_QUORUM_COMMITMENT: - return llmq::CheckLLMQCommitment(dmnman, chainman, tx, pindexPrev, state); + return llmq::CheckLLMQCommitment(dmnman, qsnapman, chainman, tx, pindexPrev, state); case TRANSACTION_MNHF_SIGNAL: return CheckMNHFTx(chainman, qman, tx, pindexPrev, state); case TRANSACTION_ASSET_LOCK: @@ -66,7 +67,8 @@ static bool CheckSpecialTxInner(CDeterministicMNManager& dmnman, const Chainstat bool CSpecialTxProcessor::CheckSpecialTx(const CTransaction& tx, const CBlockIndex* pindexPrev, const CCoinsViewCache& view, bool check_sigs, TxValidationState& state) { AssertLockHeld(cs_main); - return CheckSpecialTxInner(m_dmnman, m_chainman, m_qman, tx, pindexPrev, view, std::nullopt, check_sigs, state); + return CheckSpecialTxInner(m_dmnman, m_qsnapman, m_chainman, m_qman, tx, pindexPrev, view, std::nullopt, check_sigs, + state); } [[nodiscard]] bool CSpecialTxProcessor::ProcessSpecialTx(const CTransaction& tx, const CBlockIndex* pindex, TxValidationState& state) @@ -145,7 +147,8 @@ bool CSpecialTxProcessor::ProcessSpecialTxsInBlock(const CBlock& block, const CB TxValidationState tx_state; // At this moment CheckSpecialTx() and ProcessSpecialTx() may fail by 2 possible ways: // consensus failures and "TX_BAD_SPECIAL" - if (!CheckSpecialTxInner(m_dmnman, m_chainman, m_qman, *ptr_tx, pindex->pprev, view, creditPool.indexes, fCheckCbTxMerkleRoots, tx_state)) { + if (!CheckSpecialTxInner(m_dmnman, m_qsnapman, m_chainman, m_qman, *ptr_tx, pindex->pprev, view, + creditPool.indexes, fCheckCbTxMerkleRoots, tx_state)) { assert(tx_state.GetResult() == TxValidationResult::TX_CONSENSUS || tx_state.GetResult() == TxValidationResult::TX_BAD_SPECIAL); return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, tx_state.GetRejectReason(), strprintf("Special Transaction check failed (tx hash %s) %s", ptr_tx->GetHash().ToString(), tx_state.GetDebugMessage())); @@ -170,7 +173,7 @@ bool CSpecialTxProcessor::ProcessSpecialTxsInBlock(const CBlock& block, const CB nTimeQuorum += nTime3 - nTime2; LogPrint(BCLog::BENCHMARK, " - m_qblockman: %.2fms [%.2fs]\n", 0.001 * (nTime3 - nTime2), nTimeQuorum * 0.000001); - if (!m_dmnman.ProcessBlock(block, pindex, state, view, fJustCheck, updatesRet)) { + if (!m_dmnman.ProcessBlock(block, pindex, state, view, m_qsnapman, fJustCheck, updatesRet)) { // pass the state returned by the function above return false; } @@ -179,7 +182,7 @@ bool CSpecialTxProcessor::ProcessSpecialTxsInBlock(const CBlock& block, const CB nTimeDMN += nTime4 - nTime3; LogPrint(BCLog::BENCHMARK, " - m_dmnman: %.2fms [%.2fs]\n", 0.001 * (nTime4 - nTime3), nTimeDMN * 0.000001); - if (fCheckCbTxMerkleRoots && !CheckCbTxMerkleRoots(block, pindex, m_dmnman, m_qblockman, state, view)) { + if (fCheckCbTxMerkleRoots && !CheckCbTxMerkleRoots(block, pindex, m_dmnman, m_qsnapman, m_qblockman, state, view)) { // pass the state returned by the function above return false; } diff --git a/src/evo/specialtxman.h b/src/evo/specialtxman.h index c2148942a47d9..47dc319cb4e23 100644 --- a/src/evo/specialtxman.h +++ b/src/evo/specialtxman.h @@ -25,9 +25,10 @@ struct MNListUpdates; namespace Consensus { struct Params; } namespace llmq { +class CChainLocksHandler; class CQuorumBlockProcessor; class CQuorumManager; -class CChainLocksHandler; +class CQuorumSnapshotManager; } // namespace llmq extern RecursiveMutex cs_main; @@ -39,6 +40,7 @@ class CSpecialTxProcessor CDeterministicMNManager& m_dmnman; CMNHFManager& m_mnhfman; llmq::CQuorumBlockProcessor& m_qblockman; + llmq::CQuorumSnapshotManager& m_qsnapman; const ChainstateManager& m_chainman; const Consensus::Params& m_consensus_params; const llmq::CChainLocksHandler& m_clhandler; @@ -50,10 +52,20 @@ class CSpecialTxProcessor public: explicit CSpecialTxProcessor(CCreditPoolManager& cpoolman, CDeterministicMNManager& dmnman, CMNHFManager& mnhfman, - llmq::CQuorumBlockProcessor& qblockman, const ChainstateManager& chainman, const Consensus::Params& consensus_params, + llmq::CQuorumBlockProcessor& qblockman, llmq::CQuorumSnapshotManager& qsnapman, + const ChainstateManager& chainman, const Consensus::Params& consensus_params, const llmq::CChainLocksHandler& clhandler, const llmq::CQuorumManager& qman) : - m_cpoolman(cpoolman), m_dmnman{dmnman}, m_mnhfman{mnhfman}, m_qblockman{qblockman}, m_chainman(chainman), m_consensus_params{consensus_params}, - m_clhandler{clhandler}, m_qman{qman} {} + m_cpoolman(cpoolman), + m_dmnman{dmnman}, + m_mnhfman{mnhfman}, + m_qblockman{qblockman}, + m_qsnapman{qsnapman}, + m_chainman(chainman), + m_consensus_params{consensus_params}, + m_clhandler{clhandler}, + m_qman{qman} + { + } bool CheckSpecialTx(const CTransaction& tx, const CBlockIndex* pindexPrev, const CCoinsViewCache& view, bool check_sigs, TxValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(cs_main); diff --git a/src/llmq/blockprocessor.cpp b/src/llmq/blockprocessor.cpp index b11ab32f813ff..bc752d806dee6 100644 --- a/src/llmq/blockprocessor.cpp +++ b/src/llmq/blockprocessor.cpp @@ -26,11 +26,12 @@ #include -static void PreComputeQuorumMembers(CDeterministicMNManager& dmnman, const CBlockIndex* pindex, bool reset_cache = false) +static void PreComputeQuorumMembers(CDeterministicMNManager& dmnman, llmq::CQuorumSnapshotManager& qsnapman, + const CBlockIndex* pindex, bool reset_cache) { for (const Consensus::LLMQParams& params : llmq::GetEnabledQuorumParams(pindex->pprev)) { if (llmq::IsQuorumRotationEnabled(params, pindex) && (pindex->nHeight % params.dkgInterval == 0)) { - llmq::utils::GetAllQuorumMembers(params.type, dmnman, pindex, reset_cache); + llmq::utils::GetAllQuorumMembers(params.type, dmnman, qsnapman, pindex, reset_cache); } } } @@ -43,10 +44,12 @@ static const std::string DB_MINED_COMMITMENT_BY_INVERSED_HEIGHT_Q_INDEXED = "q_m static const std::string DB_BEST_BLOCK_UPGRADE = "q_bbu2"; -CQuorumBlockProcessor::CQuorumBlockProcessor(CChainState& chainstate, CDeterministicMNManager& dmnman, CEvoDB& evoDb) : +CQuorumBlockProcessor::CQuorumBlockProcessor(CChainState& chainstate, CDeterministicMNManager& dmnman, CEvoDB& evoDb, + CQuorumSnapshotManager& qsnapman) : m_chainstate(chainstate), m_dmnman(dmnman), - m_evoDb(evoDb) + m_evoDb(evoDb), + m_qsnapman(qsnapman) { utils::InitQuorumsCache(mapHasMinedCommitmentCache); } @@ -133,7 +136,7 @@ MessageProcessingResult CQuorumBlockProcessor::ProcessMessage(const CNode& peer, } } - if (!qc.Verify(m_dmnman, pQuorumBaseBlockIndex, true)) { + if (!qc.Verify(m_dmnman, m_qsnapman, pQuorumBaseBlockIndex, /*checkSigs=*/true)) { LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- commitment for quorum %s:%d is not valid quorumIndex[%d] nversion[%d], peer=%d\n", __func__, qc.quorumHash.ToString(), ToUnderlying(qc.llmqType), qc.quorumIndex, qc.nVersion, peer.GetId()); @@ -159,7 +162,7 @@ bool CQuorumBlockProcessor::ProcessBlock(const CBlock& block, gsl::not_null qcs; if (!GetCommitmentsFromBlock(block, pindex, qcs, state)) { @@ -270,7 +273,7 @@ bool CQuorumBlockProcessor::ProcessCommitment(int nHeight, const uint256& blockH const auto* pQuorumBaseBlockIndex = m_chainstate.m_blockman.LookupBlockIndex(qc.quorumHash); - if (!qc.Verify(m_dmnman, pQuorumBaseBlockIndex, fBLSChecks)) { + if (!qc.Verify(m_dmnman, m_qsnapman, pQuorumBaseBlockIndex, /*checkSigs=*/fBLSChecks)) { LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s height=%d, type=%d, quorumIndex=%d, quorumHash=%s, signers=%s, validMembers=%d, quorumPublicKey=%s qc verify failed.\n", __func__, nHeight, ToUnderlying(qc.llmqType), qc.quorumIndex, quorumHash.ToString(), qc.CountSigners(), qc.CountValidMembers(), qc.quorumPublicKey.ToString()); return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-qc-invalid"); @@ -314,7 +317,7 @@ bool CQuorumBlockProcessor::UndoBlock(const CBlock& block, gsl::not_null qcs; if (BlockValidationState dummy; !GetCommitmentsFromBlock(block, pindex, qcs, dummy)) { diff --git a/src/llmq/blockprocessor.h b/src/llmq/blockprocessor.h index da5dea17fb2d9..b4723674eb5a9 100644 --- a/src/llmq/blockprocessor.h +++ b/src/llmq/blockprocessor.h @@ -30,8 +30,9 @@ extern RecursiveMutex cs_main; namespace llmq { - class CFinalCommitment; +class CQuorumSnapshotManager; + using CFinalCommitmentPtr = std::unique_ptr; class CQuorumBlockProcessor @@ -40,6 +41,7 @@ class CQuorumBlockProcessor CChainState& m_chainstate; CDeterministicMNManager& m_dmnman; CEvoDB& m_evoDb; + CQuorumSnapshotManager& m_qsnapman; mutable Mutex minableCommitmentsCs; std::map, uint256> minableCommitmentsByQuorum GUARDED_BY(minableCommitmentsCs); @@ -48,7 +50,8 @@ class CQuorumBlockProcessor mutable std::map> mapHasMinedCommitmentCache GUARDED_BY(minableCommitmentsCs); public: - explicit CQuorumBlockProcessor(CChainState& chainstate, CDeterministicMNManager& dmnman, CEvoDB& evoDb); + explicit CQuorumBlockProcessor(CChainState& chainstate, CDeterministicMNManager& dmnman, CEvoDB& evoDb, + CQuorumSnapshotManager& qsnapman); MessageProcessingResult ProcessMessage(const CNode& peer, std::string_view msg_type, CDataStream& vRecv); diff --git a/src/llmq/commitment.cpp b/src/llmq/commitment.cpp index 607be69f1b63a..4727fa2533f4e 100644 --- a/src/llmq/commitment.cpp +++ b/src/llmq/commitment.cpp @@ -27,7 +27,8 @@ CFinalCommitment::CFinalCommitment(const Consensus::LLMQParams& params, const ui { } -bool CFinalCommitment::Verify(CDeterministicMNManager& dmnman, gsl::not_null pQuorumBaseBlockIndex, bool checkSigs) const +bool CFinalCommitment::Verify(CDeterministicMNManager& dmnman, CQuorumSnapshotManager& qsnapman, + gsl::not_null pQuorumBaseBlockIndex, bool checkSigs) const { const auto& llmq_params_opt = Params().GetLLMQ(llmqType); if (!llmq_params_opt.has_value()) { @@ -81,7 +82,7 @@ bool CFinalCommitment::Verify(CDeterministicMNManager& dmnman, gsl::not_null pindexPrev, TxValidationState& state) +bool CheckLLMQCommitment(CDeterministicMNManager& dmnman, CQuorumSnapshotManager& qsnapman, + const ChainstateManager& chainman, const CTransaction& tx, + gsl::not_null pindexPrev, TxValidationState& state) { const auto opt_qcTx = GetTxPayload(tx); if (!opt_qcTx) { @@ -219,7 +222,7 @@ bool CheckLLMQCommitment(CDeterministicMNManager& dmnman, const ChainstateManage return true; } - if (!qcTx.commitment.Verify(dmnman, pQuorumBaseBlockIndex, false)) { + if (!qcTx.commitment.Verify(dmnman, qsnapman, pQuorumBaseBlockIndex, false)) { LogPrint(BCLog::LLMQ, "CFinalCommitment -- h[%d] invalid qcTx.commitment[%s] Verify failed\n", pindexPrev->nHeight, qcTx.commitment.quorumHash.ToString()); return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-qc-invalid"); } diff --git a/src/llmq/commitment.h b/src/llmq/commitment.h index 3cb02b93b50df..6adbdcbb4c7fc 100644 --- a/src/llmq/commitment.h +++ b/src/llmq/commitment.h @@ -27,6 +27,7 @@ class TxValidationState; namespace llmq { +class CQuorumSnapshotManager; // This message is an aggregation of all received premature commitments and only valid if // enough (>=threshold) premature commitments were aggregated @@ -65,7 +66,8 @@ class CFinalCommitment return int(std::count(validMembers.begin(), validMembers.end(), true)); } - bool Verify(CDeterministicMNManager& dmnman, gsl::not_null pQuorumBaseBlockIndex, bool checkSigs) const; + bool Verify(CDeterministicMNManager& dmnman, CQuorumSnapshotManager& qsnapman, + gsl::not_null pQuorumBaseBlockIndex, bool checkSigs) const; bool VerifyNull() const; bool VerifySizes(const Consensus::LLMQParams& params) const; @@ -175,7 +177,9 @@ class CFinalCommitmentTxPayload } }; -bool CheckLLMQCommitment(CDeterministicMNManager& dmnman, const ChainstateManager& chainman, const CTransaction& tx, gsl::not_null pindexPrev, TxValidationState& state); +bool CheckLLMQCommitment(CDeterministicMNManager& dmnman, CQuorumSnapshotManager& qsnapman, + const ChainstateManager& chainman, const CTransaction& tx, + gsl::not_null pindexPrev, TxValidationState& state); uint256 BuildCommitmentHash(Consensus::LLMQType llmqType, const uint256& blockHash, const std::vector& validMembers, const CBLSPublicKey& pubKey, const uint256& vvecHash); diff --git a/src/llmq/context.cpp b/src/llmq/context.cpp index f1958c4457d15..7998475868cce 100644 --- a/src/llmq/context.cpp +++ b/src/llmq/context.cpp @@ -17,6 +17,7 @@ #include #include #include +#include LLMQContext::LLMQContext(ChainstateManager& chainman, CDeterministicMNManager& dmnman, CEvoDB& evo_db, CMasternodeMetaMan& mn_metaman, CMNHFManager& mnhfman, CSporkManager& sporkman, @@ -25,13 +26,14 @@ LLMQContext::LLMQContext(ChainstateManager& chainman, CDeterministicMNManager& d is_masternode{mn_activeman != nullptr}, bls_worker{std::make_shared()}, dkg_debugman{std::make_unique()}, - quorum_block_processor{std::make_unique(chainman.ActiveChainstate(), dmnman, evo_db)}, + quorum_block_processor{std::make_unique(chainman.ActiveChainstate(), dmnman, evo_db, + *llmq::quorumSnapshotManager)}, qdkgsman{std::make_unique(*bls_worker, chainman.ActiveChainstate(), dmnman, *dkg_debugman, - mn_metaman, *quorum_block_processor, mn_activeman, sporkman, - unit_tests, wipe)}, + mn_metaman, *quorum_block_processor, *llmq::quorumSnapshotManager, + mn_activeman, sporkman, unit_tests, wipe)}, qman{std::make_unique(*bls_worker, chainman.ActiveChainstate(), dmnman, *qdkgsman, evo_db, - *quorum_block_processor, mn_activeman, mn_sync, sporkman, unit_tests, - wipe)}, + *quorum_block_processor, *llmq::quorumSnapshotManager, mn_activeman, + mn_sync, sporkman, unit_tests, wipe)}, sigman{std::make_unique(mn_activeman, chainman.ActiveChainstate(), *qman, unit_tests, wipe)}, shareman{std::make_unique(*sigman, mn_activeman, *qman, sporkman)}, clhandler{std::make_unique(chainman.ActiveChainstate(), *qman, *sigman, *shareman, diff --git a/src/llmq/debug.cpp b/src/llmq/debug.cpp index c042fd0c98602..9e70b3bff319e 100644 --- a/src/llmq/debug.cpp +++ b/src/llmq/debug.cpp @@ -15,8 +15,8 @@ namespace llmq { -UniValue CDKGDebugSessionStatus::ToJson(CDeterministicMNManager& dmnman, const ChainstateManager& chainman, - int quorumIndex, int detailLevel) const +UniValue CDKGDebugSessionStatus::ToJson(CDeterministicMNManager& dmnman, CQuorumSnapshotManager& qsnapman, + const ChainstateManager& chainman, int quorumIndex, int detailLevel) const { UniValue ret(UniValue::VOBJ); @@ -28,7 +28,7 @@ UniValue CDKGDebugSessionStatus::ToJson(CDeterministicMNManager& dmnman, const C if (detailLevel == 2) { const CBlockIndex* pindex = WITH_LOCK(cs_main, return chainman.m_blockman.LookupBlockIndex(quorumHash)); if (pindex != nullptr) { - dmnMembers = utils::GetAllQuorumMembers(llmqType, dmnman, pindex); + dmnMembers = utils::GetAllQuorumMembers(llmqType, dmnman, qsnapman, pindex); } } @@ -109,8 +109,8 @@ UniValue CDKGDebugSessionStatus::ToJson(CDeterministicMNManager& dmnman, const C CDKGDebugManager::CDKGDebugManager() = default; -UniValue CDKGDebugStatus::ToJson(CDeterministicMNManager& dmnman, const ChainstateManager& chainman, - int detailLevel) const +UniValue CDKGDebugStatus::ToJson(CDeterministicMNManager& dmnman, CQuorumSnapshotManager& qsnapman, + const ChainstateManager& chainman, int detailLevel) const { UniValue ret(UniValue::VOBJ); @@ -127,7 +127,7 @@ UniValue CDKGDebugStatus::ToJson(CDeterministicMNManager& dmnman, const Chainsta UniValue s(UniValue::VOBJ); s.pushKV("llmqType", std::string(llmq_params_opt->name)); s.pushKV("quorumIndex", p.first.second); - s.pushKV("status", p.second.ToJson(dmnman, chainman, p.first.second, detailLevel)); + s.pushKV("status", p.second.ToJson(dmnman, qsnapman, chainman, p.first.second, detailLevel)); sessionsArrJson.push_back(s); } diff --git a/src/llmq/debug.h b/src/llmq/debug.h index 7498a281ab6d3..337ce82de1a90 100644 --- a/src/llmq/debug.h +++ b/src/llmq/debug.h @@ -20,6 +20,7 @@ class CScheduler; namespace llmq { +class CQuorumSnapshotManager; enum class QuorumPhase; @@ -76,8 +77,8 @@ class CDKGDebugSessionStatus public: CDKGDebugSessionStatus() : statusBitset(0) {} - UniValue ToJson(CDeterministicMNManager& dmnman, const ChainstateManager& chainman, - int quorumIndex, int detailLevel) const; + UniValue ToJson(CDeterministicMNManager& dmnman, CQuorumSnapshotManager& qsnapman, + const ChainstateManager& chainman, int quorumIndex, int detailLevel) const; }; class CDKGDebugStatus @@ -89,8 +90,8 @@ class CDKGDebugStatus //std::map sessions; public: - UniValue ToJson(CDeterministicMNManager& dmnman, const ChainstateManager& chainman, - int detailLevel) const; + UniValue ToJson(CDeterministicMNManager& dmnman, CQuorumSnapshotManager& qsnapman, + const ChainstateManager& chainman, int detailLevel) const; }; class CDKGDebugManager diff --git a/src/llmq/dkgsession.cpp b/src/llmq/dkgsession.cpp index b63ebf45a4e0f..2423b71f85de0 100644 --- a/src/llmq/dkgsession.cpp +++ b/src/llmq/dkgsession.cpp @@ -74,7 +74,8 @@ CDKGMember::CDKGMember(const CDeterministicMNCPtr& _dmn, size_t _idx) : CDKGSession::CDKGSession(const CBlockIndex* pQuorumBaseBlockIndex, const Consensus::LLMQParams& _params, CBLSWorker& _blsWorker, CDeterministicMNManager& dmnman, CDKGSessionManager& _dkgManager, CDKGDebugManager& _dkgDebugManager, CMasternodeMetaMan& mn_metaman, - const CActiveMasternodeManager* const mn_activeman, const CSporkManager& sporkman) : + CQuorumSnapshotManager& qsnapman, const CActiveMasternodeManager* const mn_activeman, + const CSporkManager& sporkman) : params(_params), blsWorker(_blsWorker), cache(_blsWorker), @@ -82,6 +83,7 @@ CDKGSession::CDKGSession(const CBlockIndex* pQuorumBaseBlockIndex, const Consens dkgManager(_dkgManager), dkgDebugManager(_dkgDebugManager), m_mn_metaman(mn_metaman), + m_qsnapman(qsnapman), m_mn_activeman(mn_activeman), m_sporkman(sporkman), m_quorum_base_block_index{pQuorumBaseBlockIndex} @@ -90,7 +92,7 @@ CDKGSession::CDKGSession(const CBlockIndex* pQuorumBaseBlockIndex, const Consens bool CDKGSession::Init(const uint256& _myProTxHash, int _quorumIndex) { - const auto mns = utils::GetAllQuorumMembers(params.type, m_dmnman, m_quorum_base_block_index); + const auto mns = utils::GetAllQuorumMembers(params.type, m_dmnman, m_qsnapman, m_quorum_base_block_index); quorumIndex = _quorumIndex; members.resize(mns.size()); memberIds.resize(members.size()); @@ -135,7 +137,8 @@ bool CDKGSession::Init(const uint256& _myProTxHash, int _quorumIndex) if (!myProTxHash.IsNull()) { dkgDebugManager.InitLocalSessionStatus(params, quorumIndex, m_quorum_base_block_index->GetBlockHash(), m_quorum_base_block_index->nHeight); - relayMembers = utils::GetQuorumRelayMembers(params, m_dmnman, m_quorum_base_block_index, myProTxHash, true); + relayMembers = utils::GetQuorumRelayMembers(params, m_dmnman, m_qsnapman, m_quorum_base_block_index, + myProTxHash, true); if (LogAcceptDebug(BCLog::LLMQ)) { std::stringstream ss; for (const auto& r : relayMembers) { @@ -1272,7 +1275,7 @@ std::vector CDKGSession::FinalizeCommitments() t2.stop(); cxxtimer::Timer t3(true); - if (!fqc.Verify(m_dmnman, m_quorum_base_block_index, true)) { + if (!fqc.Verify(m_dmnman, m_qsnapman, m_quorum_base_block_index, true)) { logger.Batch("failed to verify final commitment"); continue; } diff --git a/src/llmq/dkgsession.h b/src/llmq/dkgsession.h index b1897482fcee9..6e8a4170a7556 100644 --- a/src/llmq/dkgsession.h +++ b/src/llmq/dkgsession.h @@ -36,6 +36,7 @@ class CDKGDebugManager; class CDKGSession; class CDKGSessionManager; class CDKGPendingMessages; +class CQuorumSnapshotManager; class CDKGContribution { @@ -286,6 +287,7 @@ class CDKGSession CDKGSessionManager& dkgManager; CDKGDebugManager& dkgDebugManager; CMasternodeMetaMan& m_mn_metaman; + CQuorumSnapshotManager& m_qsnapman; const CActiveMasternodeManager* const m_mn_activeman; const CSporkManager& m_sporkman; @@ -329,8 +331,8 @@ class CDKGSession public: CDKGSession(const CBlockIndex* pQuorumBaseBlockIndex, const Consensus::LLMQParams& _params, CBLSWorker& _blsWorker, CDeterministicMNManager& dmnman, CDKGSessionManager& _dkgManager, CDKGDebugManager& _dkgDebugManager, - CMasternodeMetaMan& mn_metaman, const CActiveMasternodeManager* const mn_activeman, - const CSporkManager& sporkman); + CMasternodeMetaMan& mn_metaman, CQuorumSnapshotManager& qsnapman, + const CActiveMasternodeManager* const mn_activeman, const CSporkManager& sporkman); // TODO: remove Init completely bool Init(const uint256& _myProTxHash, int _quorumIndex); diff --git a/src/llmq/dkgsessionhandler.cpp b/src/llmq/dkgsessionhandler.cpp index 107bbf98af967..95b1c0fd3372d 100644 --- a/src/llmq/dkgsessionhandler.cpp +++ b/src/llmq/dkgsessionhandler.cpp @@ -27,6 +27,7 @@ namespace llmq CDKGSessionHandler::CDKGSessionHandler(CBLSWorker& _blsWorker, CChainState& chainstate, CDeterministicMNManager& dmnman, CDKGDebugManager& _dkgDebugManager, CDKGSessionManager& _dkgManager, CMasternodeMetaMan& mn_metaman, CQuorumBlockProcessor& _quorumBlockProcessor, + CQuorumSnapshotManager& qsnapman, const CActiveMasternodeManager* const mn_activeman, const CSporkManager& sporkman, const Consensus::LLMQParams& _params, int _quorumIndex) : blsWorker(_blsWorker), @@ -36,12 +37,13 @@ CDKGSessionHandler::CDKGSessionHandler(CBLSWorker& _blsWorker, CChainState& chai dkgManager(_dkgManager), m_mn_metaman(mn_metaman), quorumBlockProcessor(_quorumBlockProcessor), + m_qsnapman(qsnapman), m_mn_activeman(mn_activeman), m_sporkman(sporkman), params(_params), quorumIndex(_quorumIndex), curSession(std::make_unique(nullptr, _params, _blsWorker, dmnman, _dkgManager, _dkgDebugManager, - m_mn_metaman, m_mn_activeman, sporkman)), + m_mn_metaman, m_qsnapman, m_mn_activeman, sporkman)), pendingContributions( (size_t)_params.size * 2, MSG_QUORUM_CONTRIB), // we allow size*2 messages as we need to make sure we see bad behavior (double messages) @@ -189,7 +191,7 @@ bool CDKGSessionHandler::InitNewQuorum(const CBlockIndex* pQuorumBaseBlockIndex) } curSession = std::make_unique(pQuorumBaseBlockIndex, params, blsWorker, m_dmnman, dkgManager, - dkgDebugManager, m_mn_metaman, m_mn_activeman, m_sporkman); + dkgDebugManager, m_mn_metaman, m_qsnapman, m_mn_activeman, m_sporkman); if (!curSession->Init(m_mn_activeman->GetProTxHash(), quorumIndex)) { LogPrintf("CDKGSessionManager::%s -- height[%d] quorum initialization failed for %s qi[%d]\n", __func__, @@ -548,9 +550,11 @@ void CDKGSessionHandler::HandleDKGRound(CConnman& connman, PeerManager& peerman) }); const auto tip_mn_list = m_dmnman.GetListAtChainTip(); - utils::EnsureQuorumConnections(params, connman, m_dmnman, m_sporkman, tip_mn_list, pQuorumBaseBlockIndex, curSession->myProTxHash, /* is_masternode = */ m_mn_activeman != nullptr); + utils::EnsureQuorumConnections(params, connman, m_dmnman, m_sporkman, m_qsnapman, tip_mn_list, pQuorumBaseBlockIndex, + curSession->myProTxHash, /* is_masternode = */ m_mn_activeman != nullptr); if (curSession->AreWeMember()) { - utils::AddQuorumProbeConnections(params, connman, m_dmnman, m_mn_metaman, m_sporkman, tip_mn_list, pQuorumBaseBlockIndex, curSession->myProTxHash); + utils::AddQuorumProbeConnections(params, connman, m_dmnman, m_mn_metaman, m_qsnapman, m_sporkman, tip_mn_list, + pQuorumBaseBlockIndex, curSession->myProTxHash); } WaitForNextPhase(QuorumPhase::Initialized, QuorumPhase::Contribute, curQuorumHash); diff --git a/src/llmq/dkgsessionhandler.h b/src/llmq/dkgsessionhandler.h index b28ae87e44a14..6f320894a58ef 100644 --- a/src/llmq/dkgsessionhandler.h +++ b/src/llmq/dkgsessionhandler.h @@ -38,6 +38,7 @@ class CDKGDebugManager; class CDKGSession; class CDKGSessionManager; class CQuorumBlockProcessor; +class CQuorumSnapshotManager; enum class QuorumPhase { Initialized = 1, @@ -134,6 +135,7 @@ class CDKGSessionHandler CDKGSessionManager& dkgManager; CMasternodeMetaMan& m_mn_metaman; CQuorumBlockProcessor& quorumBlockProcessor; + CQuorumSnapshotManager& m_qsnapman; const CActiveMasternodeManager* const m_mn_activeman; const CSporkManager& m_sporkman; const Consensus::LLMQParams params; @@ -156,8 +158,9 @@ class CDKGSessionHandler public: CDKGSessionHandler(CBLSWorker& _blsWorker, CChainState& chainstate, CDeterministicMNManager& dmnman, - CDKGDebugManager& _dkgDebugManager, CDKGSessionManager& _dkgManager, CMasternodeMetaMan& mn_metaman, - CQuorumBlockProcessor& _quorumBlockProcessor, const CActiveMasternodeManager* const mn_activeman, + CDKGDebugManager& _dkgDebugManager, CDKGSessionManager& _dkgManager, + CMasternodeMetaMan& mn_metaman, CQuorumBlockProcessor& _quorumBlockProcessor, + CQuorumSnapshotManager& qsnapman, const CActiveMasternodeManager* const mn_activeman, const CSporkManager& sporkman, const Consensus::LLMQParams& _params, int _quorumIndex); ~CDKGSessionHandler(); diff --git a/src/llmq/dkgsessionmgr.cpp b/src/llmq/dkgsessionmgr.cpp index d6fb0715c1014..12481b0120e38 100644 --- a/src/llmq/dkgsessionmgr.cpp +++ b/src/llmq/dkgsessionmgr.cpp @@ -31,7 +31,7 @@ static const std::string DB_ENC_CONTRIB = "qdkg_E"; CDKGSessionManager::CDKGSessionManager(CBLSWorker& _blsWorker, CChainState& chainstate, CDeterministicMNManager& dmnman, CDKGDebugManager& _dkgDebugManager, CMasternodeMetaMan& mn_metaman, - CQuorumBlockProcessor& _quorumBlockProcessor, + CQuorumBlockProcessor& _quorumBlockProcessor, CQuorumSnapshotManager& qsnapman, const CActiveMasternodeManager* const mn_activeman, const CSporkManager& sporkman, bool unitTests, bool fWipe) : db(std::make_unique(unitTests ? "" : (gArgs.GetDataDirNet() / "llmq/dkgdb"), 1 << 20, unitTests, fWipe)), @@ -40,6 +40,7 @@ CDKGSessionManager::CDKGSessionManager(CBLSWorker& _blsWorker, CChainState& chai m_dmnman(dmnman), dkgDebugManager(_dkgDebugManager), quorumBlockProcessor(_quorumBlockProcessor), + m_qsnapman(qsnapman), spork_manager(sporkman) { if (mn_activeman == nullptr && !IsWatchQuorumsEnabled()) { @@ -53,7 +54,7 @@ CDKGSessionManager::CDKGSessionManager(CBLSWorker& _blsWorker, CChainState& chai for (const auto i : irange::range(session_count)) { dkgSessionHandlers.emplace(std::piecewise_construct, std::forward_as_tuple(params.type, i), std::forward_as_tuple(blsWorker, m_chainstate, dmnman, dkgDebugManager, *this, - mn_metaman, quorumBlockProcessor, mn_activeman, + mn_metaman, quorumBlockProcessor, m_qsnapman, mn_activeman, spork_manager, params, i)); } } @@ -297,7 +298,7 @@ void CDKGSessionManager::WriteEncryptedContributions(Consensus::LLMQType llmqTyp bool CDKGSessionManager::GetVerifiedContributions(Consensus::LLMQType llmqType, const CBlockIndex* pQuorumBaseBlockIndex, const std::vector& validMembers, std::vector& memberIndexesRet, std::vector& vvecsRet, std::vector& skContributionsRet) const { - auto members = utils::GetAllQuorumMembers(llmqType, m_dmnman, pQuorumBaseBlockIndex); + auto members = utils::GetAllQuorumMembers(llmqType, m_dmnman, m_qsnapman, pQuorumBaseBlockIndex); memberIndexesRet.clear(); vvecsRet.clear(); @@ -343,7 +344,7 @@ bool CDKGSessionManager::GetVerifiedContributions(Consensus::LLMQType llmqType, bool CDKGSessionManager::GetEncryptedContributions(Consensus::LLMQType llmqType, const CBlockIndex* pQuorumBaseBlockIndex, const std::vector& validMembers, const uint256& nProTxHash, std::vector>& vecRet) const { - auto members = utils::GetAllQuorumMembers(llmqType, m_dmnman, pQuorumBaseBlockIndex); + auto members = utils::GetAllQuorumMembers(llmqType, m_dmnman, m_qsnapman, pQuorumBaseBlockIndex); vecRet.clear(); vecRet.reserve(members.size()); diff --git a/src/llmq/dkgsessionmgr.h b/src/llmq/dkgsessionmgr.h index eaa5dc79deae3..2b84c35fa5b94 100644 --- a/src/llmq/dkgsessionmgr.h +++ b/src/llmq/dkgsessionmgr.h @@ -32,6 +32,7 @@ class UniValue; namespace llmq { +class CQuorumSnapshotManager; class CDKGSessionManager { @@ -45,6 +46,7 @@ class CDKGSessionManager CDeterministicMNManager& m_dmnman; CDKGDebugManager& dkgDebugManager; CQuorumBlockProcessor& quorumBlockProcessor; + CQuorumSnapshotManager& m_qsnapman; const CSporkManager& spork_manager; //TODO name struct instead of std::pair @@ -72,8 +74,9 @@ class CDKGSessionManager public: CDKGSessionManager(CBLSWorker& _blsWorker, CChainState& chainstate, CDeterministicMNManager& dmnman, CDKGDebugManager& _dkgDebugManager, CMasternodeMetaMan& mn_metaman, - CQuorumBlockProcessor& _quorumBlockProcessor, const CActiveMasternodeManager* const mn_activeman, - const CSporkManager& sporkman, bool unitTests, bool fWipe); + CQuorumBlockProcessor& _quorumBlockProcessor, CQuorumSnapshotManager& qsnapman, + const CActiveMasternodeManager* const mn_activeman, const CSporkManager& sporkman, + bool unitTests, bool fWipe); ~CDKGSessionManager(); void StartThreads(CConnman& connman, PeerManager& peerman); diff --git a/src/llmq/quorums.cpp b/src/llmq/quorums.cpp index a27fa044943c2..212aeb685735d 100644 --- a/src/llmq/quorums.cpp +++ b/src/llmq/quorums.cpp @@ -212,7 +212,7 @@ bool CQuorum::ReadContributions(const CDBWrapper& db) CQuorumManager::CQuorumManager(CBLSWorker& _blsWorker, CChainState& chainstate, CDeterministicMNManager& dmnman, CDKGSessionManager& _dkgManager, CEvoDB& _evoDb, - CQuorumBlockProcessor& _quorumBlockProcessor, + CQuorumBlockProcessor& _quorumBlockProcessor, CQuorumSnapshotManager& qsnapman, const CActiveMasternodeManager* const mn_activeman, const CMasternodeSync& mn_sync, const CSporkManager& sporkman, bool unit_tests, bool wipe) : db(std::make_unique(unit_tests ? "" : (gArgs.GetDataDirNet() / "llmq" / "quorumdb"), 1 << 20, @@ -222,6 +222,7 @@ CQuorumManager::CQuorumManager(CBLSWorker& _blsWorker, CChainState& chainstate, m_dmnman(dmnman), dkgManager(_dkgManager), quorumBlockProcessor(_quorumBlockProcessor), + m_qsnapman(qsnapman), m_mn_activeman(mn_activeman), m_mn_sync(mn_sync), m_sporkman(sporkman) @@ -365,7 +366,9 @@ void CQuorumManager::CheckQuorumConnections(CConnman& connman, const Consensus:: }); for (const auto& quorum : lastQuorums) { - if (utils::EnsureQuorumConnections(llmqParams, connman, m_dmnman, m_sporkman, m_dmnman.GetListAtChainTip(), quorum->m_quorum_base_block_index, myProTxHash, /* is_masternode = */ m_mn_activeman != nullptr)) { + if (utils::EnsureQuorumConnections(llmqParams, connman, m_dmnman, m_sporkman, m_qsnapman, + m_dmnman.GetListAtChainTip(), quorum->m_quorum_base_block_index, myProTxHash, + /* is_masternode = */ m_mn_activeman != nullptr)) { if (connmanQuorumsToDelete.erase(quorum->qc->quorumHash) > 0) { LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- llmqType[%d] h[%d] keeping mn quorum connections for quorum: [%d:%s]\n", __func__, ToUnderlying(llmqParams.type), pindexNew->nHeight, quorum->m_quorum_base_block_index->nHeight, quorum->m_quorum_base_block_index->GetBlockHash().ToString()); } @@ -407,7 +410,7 @@ CQuorumPtr CQuorumManager::BuildQuorumFromCommitment(const Consensus::LLMQType l const auto& llmq_params_opt = Params().GetLLMQ(llmqType); assert(llmq_params_opt.has_value()); auto quorum = std::make_shared(llmq_params_opt.value(), blsWorker); - auto members = utils::GetAllQuorumMembers(qc->llmqType, m_dmnman, pQuorumBaseBlockIndex); + auto members = utils::GetAllQuorumMembers(qc->llmqType, m_dmnman, m_qsnapman, pQuorumBaseBlockIndex); quorum->Init(std::move(qc), pQuorumBaseBlockIndex, minedBlockHash, members); diff --git a/src/llmq/quorums.h b/src/llmq/quorums.h index 645802efa6ce9..56924940ce3af 100644 --- a/src/llmq/quorums.h +++ b/src/llmq/quorums.h @@ -48,6 +48,7 @@ enum class VerifyRecSigStatus class CDKGSessionManager; class CQuorumBlockProcessor; +class CQuorumSnapshotManager; /** * Object used as a key to store CQuorumDataRequest @@ -241,6 +242,7 @@ class CQuorumManager CDeterministicMNManager& m_dmnman; CDKGSessionManager& dkgManager; CQuorumBlockProcessor& quorumBlockProcessor; + CQuorumSnapshotManager& m_qsnapman; const CActiveMasternodeManager* const m_mn_activeman; const CMasternodeSync& m_mn_sync; const CSporkManager& m_sporkman; @@ -262,8 +264,8 @@ class CQuorumManager public: CQuorumManager(CBLSWorker& _blsWorker, CChainState& chainstate, CDeterministicMNManager& dmnman, CDKGSessionManager& _dkgManager, CEvoDB& _evoDb, CQuorumBlockProcessor& _quorumBlockProcessor, - const CActiveMasternodeManager* const mn_activeman, const CMasternodeSync& mn_sync, - const CSporkManager& sporkman, bool unit_tests, bool wipe); + CQuorumSnapshotManager& qsnapman, const CActiveMasternodeManager* const mn_activeman, + const CMasternodeSync& mn_sync, const CSporkManager& sporkman, bool unit_tests, bool wipe); ~CQuorumManager(); void Start(); diff --git a/src/llmq/snapshot.cpp b/src/llmq/snapshot.cpp index 7b349fb31db57..e56ca051267e8 100644 --- a/src/llmq/snapshot.cpp +++ b/src/llmq/snapshot.cpp @@ -86,7 +86,8 @@ UniValue CQuorumRotationInfo::ToJson() const return obj; } -bool BuildQuorumRotationInfo(CDeterministicMNManager& dmnman, const ChainstateManager& chainman, const CQuorumManager& qman, +bool BuildQuorumRotationInfo(CDeterministicMNManager& dmnman, CQuorumSnapshotManager& qsnapman, + const ChainstateManager& chainman, const CQuorumManager& qman, const CQuorumBlockProcessor& qblockman, const CGetQuorumRotationInfo& request, CQuorumRotationInfo& response, std::string& errorRet) { @@ -207,7 +208,7 @@ bool BuildQuorumRotationInfo(CDeterministicMNManager& dmnman, const ChainstateMa return false; } - auto snapshotHMinusC = quorumSnapshotManager->GetSnapshotForBlock(llmqType, pBlockHMinusCIndex); + auto snapshotHMinusC = qsnapman.GetSnapshotForBlock(llmqType, pBlockHMinusCIndex); if (!snapshotHMinusC.has_value()) { errorRet = strprintf("Can not find quorum snapshot at H-C"); return false; @@ -219,7 +220,7 @@ bool BuildQuorumRotationInfo(CDeterministicMNManager& dmnman, const ChainstateMa return false; } - auto snapshotHMinus2C = quorumSnapshotManager->GetSnapshotForBlock(llmqType, pBlockHMinus2CIndex); + auto snapshotHMinus2C = qsnapman.GetSnapshotForBlock(llmqType, pBlockHMinus2CIndex); if (!snapshotHMinus2C.has_value()) { errorRet = strprintf("Can not find quorum snapshot at H-2C"); return false; @@ -231,7 +232,7 @@ bool BuildQuorumRotationInfo(CDeterministicMNManager& dmnman, const ChainstateMa return false; } - auto snapshotHMinus3C = quorumSnapshotManager->GetSnapshotForBlock(llmqType, pBlockHMinus3CIndex); + auto snapshotHMinus3C = qsnapman.GetSnapshotForBlock(llmqType, pBlockHMinus3CIndex); if (!snapshotHMinus3C.has_value()) { errorRet = strprintf("Can not find quorum snapshot at H-3C"); return false; @@ -247,7 +248,7 @@ bool BuildQuorumRotationInfo(CDeterministicMNManager& dmnman, const ChainstateMa return false; } - auto snapshotHMinus4C = quorumSnapshotManager->GetSnapshotForBlock(llmqType, pBlockHMinus4CIndex); + auto snapshotHMinus4C = qsnapman.GetSnapshotForBlock(llmqType, pBlockHMinus4CIndex); if (!snapshotHMinus4C.has_value()) { errorRet = strprintf("Can not find quorum snapshot at H-4C"); return false; @@ -303,7 +304,7 @@ bool BuildQuorumRotationInfo(CDeterministicMNManager& dmnman, const ChainstateMa return false; } - auto snapshotNeededH = quorumSnapshotManager->GetSnapshotForBlock(llmqType, pNeededBlockIndex); + auto snapshotNeededH = qsnapman.GetSnapshotForBlock(llmqType, pNeededBlockIndex); if (!snapshotNeededH.has_value()) { errorRet = strprintf("Can not find quorum snapshot at H(%d)", h); return false; diff --git a/src/llmq/snapshot.h b/src/llmq/snapshot.h index e1e32751c522b..caade91ad6ebb 100644 --- a/src/llmq/snapshot.h +++ b/src/llmq/snapshot.h @@ -207,7 +207,8 @@ class CQuorumRotationInfo [[nodiscard]] UniValue ToJson() const; }; -bool BuildQuorumRotationInfo(CDeterministicMNManager& dmnman, const ChainstateManager& chainman, const CQuorumManager& qman, +bool BuildQuorumRotationInfo(CDeterministicMNManager& dmnman, CQuorumSnapshotManager& qsnapman, + const ChainstateManager& chainman, const CQuorumManager& qman, const CQuorumBlockProcessor& qblockman, const CGetQuorumRotationInfo& request, CQuorumRotationInfo& response, std::string& errorRet) EXCLUSIVE_LOCKS_REQUIRED(::cs_main); uint256 GetLastBaseBlockHash(Span baseBlockIndexes, const CBlockIndex* blockIndex); diff --git a/src/llmq/utils.cpp b/src/llmq/utils.cpp index ea446fa5e464d..7efdad91db587 100644 --- a/src/llmq/utils.cpp +++ b/src/llmq/utils.cpp @@ -60,15 +60,16 @@ struct PreviousQuorumQuarters { static std::vector ComputeQuorumMembers(Consensus::LLMQType llmqType, CDeterministicMNManager& dmnman, const CBlockIndex* pQuorumBaseBlockIndex); static std::vector> ComputeQuorumMembersByQuarterRotation( - const Consensus::LLMQParams& llmqParams, CDeterministicMNManager& dmnman, + const Consensus::LLMQParams& llmqParams, CDeterministicMNManager& dmnman, CQuorumSnapshotManager& qsnapman, const CBlockIndex* pCycleQuorumBaseBlockIndex); static std::vector> BuildNewQuorumQuarterMembers( - const Consensus::LLMQParams& llmqParams, CDeterministicMNManager& dmnman, + const Consensus::LLMQParams& llmqParams, CDeterministicMNManager& dmnman, CQuorumSnapshotManager& qsnapman, const CBlockIndex* pCycleQuorumBaseBlockIndex, const PreviousQuorumQuarters& previousQuarters); static PreviousQuorumQuarters GetPreviousQuorumQuarterMembers(const Consensus::LLMQParams& llmqParams, CDeterministicMNManager& dmnman, + CQuorumSnapshotManager& qsnapman, const CBlockIndex* pBlockHMinusCIndex, const CBlockIndex* pBlockHMinus2CIndex, const CBlockIndex* pBlockHMinus3CIndex, int nHeight); @@ -109,6 +110,7 @@ static uint256 GetHashModifier(const Consensus::LLMQParams& llmqParams, gsl::not } std::vector GetAllQuorumMembers(Consensus::LLMQType llmqType, CDeterministicMNManager& dmnman, + CQuorumSnapshotManager& qsnapman, gsl::not_null pQuorumBaseBlockIndex, bool reset_cache) { @@ -169,7 +171,7 @@ std::vector GetAllQuorumMembers(Consensus::LLMQType llmqTy return quorumMembers; } - auto q = ComputeQuorumMembersByQuarterRotation(llmq_params, dmnman, pCycleQuorumBaseBlockIndex); + auto q = ComputeQuorumMembersByQuarterRotation(llmq_params, dmnman, qsnapman, pCycleQuorumBaseBlockIndex); LOCK(cs_indexed_members); for (const size_t i : irange::range(q.size())) { mapIndexedQuorumMembers[llmqType].insert(std::make_pair(pCycleQuorumBaseBlockIndex->GetBlockHash(), i), q[i]); @@ -205,7 +207,8 @@ std::vector ComputeQuorumMembers(Consensus::LLMQType llmqT } std::vector> ComputeQuorumMembersByQuarterRotation( - const Consensus::LLMQParams& llmqParams, CDeterministicMNManager& dmnman, const CBlockIndex* pCycleQuorumBaseBlockIndex) + const Consensus::LLMQParams& llmqParams, CDeterministicMNManager& dmnman, CQuorumSnapshotManager& qsnapman, + const CBlockIndex* pCycleQuorumBaseBlockIndex) { const Consensus::LLMQType llmqType = llmqParams.type; @@ -222,12 +225,16 @@ std::vector> ComputeQuorumMembersByQuarterRota auto allMns = dmnman.GetListForBlock(pWorkBlockIndex); LogPrint(BCLog::LLMQ, "ComputeQuorumMembersByQuarterRotation llmqType[%d] nHeight[%d] allMns[%d]\n", ToUnderlying(llmqType), pCycleQuorumBaseBlockIndex->nHeight, allMns.GetValidMNsCount()); - PreviousQuorumQuarters previousQuarters = GetPreviousQuorumQuarterMembers(llmqParams, dmnman, pBlockHMinusCIndex, pBlockHMinus2CIndex, pBlockHMinus3CIndex, pCycleQuorumBaseBlockIndex->nHeight); + PreviousQuorumQuarters previousQuarters = GetPreviousQuorumQuarterMembers(llmqParams, dmnman, qsnapman, + pBlockHMinusCIndex, pBlockHMinus2CIndex, + pBlockHMinus3CIndex, + pCycleQuorumBaseBlockIndex->nHeight); size_t nQuorums = static_cast(llmqParams.signingActiveQuorumCount); std::vector> quorumMembers{nQuorums}; - auto newQuarterMembers = BuildNewQuorumQuarterMembers(llmqParams, dmnman, pCycleQuorumBaseBlockIndex, previousQuarters); + auto newQuarterMembers = BuildNewQuorumQuarterMembers(llmqParams, dmnman, qsnapman, pCycleQuorumBaseBlockIndex, + previousQuarters); //TODO Check if it is triggered from outside (P2P, block validation). Throwing an exception is probably a wiser choice //assert (!newQuarterMembers.empty()); @@ -280,7 +287,7 @@ std::vector> ComputeQuorumMembersByQuarterRota } PreviousQuorumQuarters GetPreviousQuorumQuarterMembers(const Consensus::LLMQParams& llmqParams, - CDeterministicMNManager& dmnman, + CDeterministicMNManager& dmnman, CQuorumSnapshotManager& qsnapman, const CBlockIndex* pBlockHMinusCIndex, const CBlockIndex* pBlockHMinus2CIndex, const CBlockIndex* pBlockHMinus3CIndex, int nHeight) @@ -288,19 +295,22 @@ PreviousQuorumQuarters GetPreviousQuorumQuarterMembers(const Consensus::LLMQPara size_t nQuorums = static_cast(llmqParams.signingActiveQuorumCount); PreviousQuorumQuarters quarters{nQuorums}; - std::optional quSnapshotHMinusC = quorumSnapshotManager->GetSnapshotForBlock(llmqParams.type, pBlockHMinusCIndex); + std::optional quSnapshotHMinusC = qsnapman.GetSnapshotForBlock(llmqParams.type, + pBlockHMinusCIndex); if (quSnapshotHMinusC.has_value()) { quarters.quarterHMinusC = GetQuorumQuarterMembersBySnapshot(llmqParams, dmnman, pBlockHMinusCIndex, quSnapshotHMinusC.value(), nHeight); //TODO Check if it is triggered from outside (P2P, block validation). Throwing an exception is probably a wiser choice //assert (!quarterHMinusC.empty()); - std::optional quSnapshotHMinus2C = quorumSnapshotManager->GetSnapshotForBlock(llmqParams.type, pBlockHMinus2CIndex); + std::optional quSnapshotHMinus2C = qsnapman.GetSnapshotForBlock(llmqParams.type, + pBlockHMinus2CIndex); if (quSnapshotHMinus2C.has_value()) { quarters.quarterHMinus2C = GetQuorumQuarterMembersBySnapshot(llmqParams, dmnman, pBlockHMinus2CIndex, quSnapshotHMinus2C.value(), nHeight); //TODO Check if it is triggered from outside (P2P, block validation). Throwing an exception is probably a wiser choice //assert (!quarterHMinusC.empty()); - std::optional quSnapshotHMinus3C = quorumSnapshotManager->GetSnapshotForBlock(llmqParams.type, pBlockHMinus3CIndex); + std::optional quSnapshotHMinus3C = qsnapman.GetSnapshotForBlock(llmqParams.type, + pBlockHMinus3CIndex); if (quSnapshotHMinus3C.has_value()) { quarters.quarterHMinus3C = GetQuorumQuarterMembersBySnapshot(llmqParams, dmnman, pBlockHMinus3CIndex, quSnapshotHMinus3C.value(), nHeight); //TODO Check if it is triggered from outside (P2P, block validation). Throwing an exception is probably a wiser choice @@ -312,10 +322,9 @@ PreviousQuorumQuarters GetPreviousQuorumQuarterMembers(const Consensus::LLMQPara return quarters; } -std::vector> BuildNewQuorumQuarterMembers(const Consensus::LLMQParams& llmqParams, - CDeterministicMNManager& dmnman, - const CBlockIndex* pCycleQuorumBaseBlockIndex, - const PreviousQuorumQuarters& previousQuarters) +std::vector> BuildNewQuorumQuarterMembers( + const Consensus::LLMQParams& llmqParams, CDeterministicMNManager& dmnman, CQuorumSnapshotManager& qsnapman, + const CBlockIndex* pCycleQuorumBaseBlockIndex, const PreviousQuorumQuarters& previousQuarters) { if (!llmqParams.useRotation || pCycleQuorumBaseBlockIndex->nHeight % llmqParams.dkgInterval != 0) { ASSERT_IF_DEBUG(false); @@ -468,7 +477,7 @@ std::vector> BuildNewQuorumQuarterMembers(cons BuildQuorumSnapshot(llmqParams, allMns, MnsUsedAtH, sortedCombinedMnsList, quorumSnapshot, pCycleQuorumBaseBlockIndex->nHeight, skipList, pCycleQuorumBaseBlockIndex); - quorumSnapshotManager->StoreSnapshotForBlock(llmqParams.type, pCycleQuorumBaseBlockIndex, quorumSnapshot); + qsnapman.StoreSnapshotForBlock(llmqParams.type, pCycleQuorumBaseBlockIndex, quorumSnapshot); return quarterQuorumMembers; } @@ -667,11 +676,12 @@ uint256 DeterministicOutboundConnection(const uint256& proTxHash1, const uint256 } std::unordered_set GetQuorumConnections( - const Consensus::LLMQParams& llmqParams, CDeterministicMNManager& dmnman, const CSporkManager& sporkman, - gsl::not_null pQuorumBaseBlockIndex, const uint256& forMember, bool onlyOutbound) + const Consensus::LLMQParams& llmqParams, CDeterministicMNManager& dmnman, CQuorumSnapshotManager& qsnapman, + const CSporkManager& sporkman, gsl::not_null pQuorumBaseBlockIndex, const uint256& forMember, + bool onlyOutbound) { if (IsAllMembersConnectedEnabled(llmqParams.type, sporkman)) { - auto mns = GetAllQuorumMembers(llmqParams.type, dmnman, pQuorumBaseBlockIndex); + auto mns = GetAllQuorumMembers(llmqParams.type, dmnman, qsnapman, pQuorumBaseBlockIndex); std::unordered_set result; for (const auto& dmn : mns) { @@ -688,15 +698,14 @@ std::unordered_set GetQuorumConnections( } return result; } - return GetQuorumRelayMembers(llmqParams, dmnman, pQuorumBaseBlockIndex, forMember, onlyOutbound); + return GetQuorumRelayMembers(llmqParams, dmnman, qsnapman, pQuorumBaseBlockIndex, forMember, onlyOutbound); } -std::unordered_set GetQuorumRelayMembers(const Consensus::LLMQParams& llmqParams, - CDeterministicMNManager& dmnman, - gsl::not_null pQuorumBaseBlockIndex, - const uint256& forMember, bool onlyOutbound) +std::unordered_set GetQuorumRelayMembers( + const Consensus::LLMQParams& llmqParams, CDeterministicMNManager& dmnman, CQuorumSnapshotManager& qsnapman, + gsl::not_null pQuorumBaseBlockIndex, const uint256& forMember, bool onlyOutbound) { - auto mns = GetAllQuorumMembers(llmqParams.type, dmnman, pQuorumBaseBlockIndex); + auto mns = GetAllQuorumMembers(llmqParams.type, dmnman, qsnapman, pQuorumBaseBlockIndex); std::unordered_set result; auto calcOutbound = [&](size_t i, const uint256& proTxHash) { @@ -769,8 +778,9 @@ std::set CalcDeterministicWatchConnections(Consensus::LLMQType llmqType, return result; } -bool EnsureQuorumConnections(const Consensus::LLMQParams& llmqParams, CConnman& connman, CDeterministicMNManager& dmnman, - const CSporkManager& sporkman, const CDeterministicMNList& tip_mn_list, +bool EnsureQuorumConnections(const Consensus::LLMQParams& llmqParams, CConnman& connman, + CDeterministicMNManager& dmnman, const CSporkManager& sporkman, + CQuorumSnapshotManager& qsnapman, const CDeterministicMNList& tip_mn_list, gsl::not_null pQuorumBaseBlockIndex, const uint256& myProTxHash, bool is_masternode) { @@ -778,7 +788,7 @@ bool EnsureQuorumConnections(const Consensus::LLMQParams& llmqParams, CConnman& return false; } - auto members = GetAllQuorumMembers(llmqParams.type, dmnman, pQuorumBaseBlockIndex); + auto members = GetAllQuorumMembers(llmqParams.type, dmnman, qsnapman, pQuorumBaseBlockIndex); if (members.empty()) { return false; } @@ -795,8 +805,9 @@ bool EnsureQuorumConnections(const Consensus::LLMQParams& llmqParams, CConnman& std::unordered_set connections; std::unordered_set relayMembers; if (isMember) { - connections = GetQuorumConnections(llmqParams, dmnman, sporkman, pQuorumBaseBlockIndex, myProTxHash, true); - relayMembers = GetQuorumRelayMembers(llmqParams, dmnman, pQuorumBaseBlockIndex, myProTxHash, true); + connections = GetQuorumConnections(llmqParams, dmnman, qsnapman, sporkman, pQuorumBaseBlockIndex, myProTxHash, + true); + relayMembers = GetQuorumRelayMembers(llmqParams, dmnman, qsnapman, pQuorumBaseBlockIndex, myProTxHash, true); } else { auto cindexes = CalcDeterministicWatchConnections(llmqParams.type, pQuorumBaseBlockIndex, members.size(), 1); for (auto idx : cindexes) { @@ -826,8 +837,8 @@ bool EnsureQuorumConnections(const Consensus::LLMQParams& llmqParams, CConnman& return true; } -void AddQuorumProbeConnections(const Consensus::LLMQParams& llmqParams, CConnman& connman, - CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, +void AddQuorumProbeConnections(const Consensus::LLMQParams& llmqParams, CConnman& connman, CDeterministicMNManager& dmnman, + CMasternodeMetaMan& mn_metaman, CQuorumSnapshotManager& qsnapman, const CSporkManager& sporkman, const CDeterministicMNList& tip_mn_list, gsl::not_null pQuorumBaseBlockIndex, const uint256& myProTxHash) { @@ -837,7 +848,7 @@ void AddQuorumProbeConnections(const Consensus::LLMQParams& llmqParams, CConnman return; } - auto members = GetAllQuorumMembers(llmqParams.type, dmnman, pQuorumBaseBlockIndex); + auto members = GetAllQuorumMembers(llmqParams.type, dmnman, qsnapman, pQuorumBaseBlockIndex); auto curTime = GetTime().count(); std::set probeConnections; diff --git a/src/llmq/utils.h b/src/llmq/utils.h index 594c1874204ef..01ed90c77db0d 100644 --- a/src/llmq/utils.h +++ b/src/llmq/utils.h @@ -27,28 +27,33 @@ class CSporkManager; using CDeterministicMNCPtr = std::shared_ptr; namespace llmq { +class CQuorumSnapshotManager; + namespace utils { // includes members which failed DKG std::vector GetAllQuorumMembers(Consensus::LLMQType llmqType, CDeterministicMNManager& dmnman, + CQuorumSnapshotManager& qsnapman, gsl::not_null pQuorumBaseBlockIndex, bool reset_cache = false); uint256 DeterministicOutboundConnection(const uint256& proTxHash1, const uint256& proTxHash2); std::unordered_set GetQuorumConnections( - const Consensus::LLMQParams& llmqParams, CDeterministicMNManager& dmnman, const CSporkManager& sporkman, + const Consensus::LLMQParams& llmqParams, CDeterministicMNManager& dmnman, CQuorumSnapshotManager& qsnapman, + const CSporkManager& sporkman, gsl::not_null pQuorumBaseBlockIndex, const uint256& forMember, + bool onlyOutbound); +std::unordered_set GetQuorumRelayMembers( + const Consensus::LLMQParams& llmqParams, CDeterministicMNManager& dmnman, CQuorumSnapshotManager& qsnapman, gsl::not_null pQuorumBaseBlockIndex, const uint256& forMember, bool onlyOutbound); -std::unordered_set GetQuorumRelayMembers(const Consensus::LLMQParams& llmqParams, - CDeterministicMNManager& dmnman, - gsl::not_null pQuorumBaseBlockIndex, - const uint256& forMember, bool onlyOutbound); std::set CalcDeterministicWatchConnections(Consensus::LLMQType llmqType, gsl::not_null pQuorumBaseBlockIndex, size_t memberCount, size_t connectionCount); -bool EnsureQuorumConnections(const Consensus::LLMQParams& llmqParams, CConnman& connman, CDeterministicMNManager& dmnman, - const CSporkManager& sporkman, const CDeterministicMNList& tip_mn_list, +bool EnsureQuorumConnections(const Consensus::LLMQParams& llmqParams, CConnman& connman, + CDeterministicMNManager& dmnman, const CSporkManager& sporkman, + CQuorumSnapshotManager& qsnapman, const CDeterministicMNList& tip_mn_list, gsl::not_null pQuorumBaseBlockIndex, const uint256& myProTxHash, bool is_masternode); void AddQuorumProbeConnections(const Consensus::LLMQParams& llmqParams, CConnman& connman, CDeterministicMNManager& dmnman, - CMasternodeMetaMan& mn_metaman, const CSporkManager& sporkman, const CDeterministicMNList& tip_mn_list, + CMasternodeMetaMan& mn_metaman, CQuorumSnapshotManager& qsnapman, + const CSporkManager& sporkman, const CDeterministicMNList& tip_mn_list, gsl::not_null pQuorumBaseBlockIndex, const uint256& myProTxHash); template diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 10ed771d6bf53..87d1aa224b57a 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -5205,7 +5205,7 @@ void PeerManagerImpl::ProcessMessage( llmq::CQuorumRotationInfo quorumRotationInfoRet; std::string strError; - if (BuildQuorumRotationInfo(*m_dmnman, m_chainman, *m_llmq_ctx->qman, *m_llmq_ctx->quorum_block_processor, cmd, quorumRotationInfoRet, strError)) { + if (BuildQuorumRotationInfo(*m_dmnman, *llmq::quorumSnapshotManager, m_chainman, *m_llmq_ctx->qman, *m_llmq_ctx->quorum_block_processor, cmd, quorumRotationInfoRet, strError)) { m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::QUORUMROTATIONINFO, quorumRotationInfoRet)); } else { strError = strprintf("getquorumrotationinfo failed for size(baseBlockHashes)=%d, blockRequestHash=%s. error=%s", cmd.baseBlockHashes.size(), cmd.blockRequestHash.ToString(), strError); diff --git a/src/node/chainstate.cpp b/src/node/chainstate.cpp index 11ef560828177..37a3ed1986ef2 100644 --- a/src/node/chainstate.cpp +++ b/src/node/chainstate.cpp @@ -240,7 +240,8 @@ void DashChainstateSetup(ChainstateManager& chainman, chain_helper.reset(); chain_helper = std::make_unique(*cpoolman, *dmnman, *mnhf_manager, govman, *(llmq_ctx->isman), *(llmq_ctx->quorum_block_processor), - chainman, consensus_params, mn_sync, sporkman, *(llmq_ctx->clhandler), *(llmq_ctx->qman)); + *llmq::quorumSnapshotManager, chainman, consensus_params, mn_sync, sporkman, *(llmq_ctx->clhandler), + *(llmq_ctx->qman)); } void DashChainstateSetupClose(std::unique_ptr& chain_helper, diff --git a/src/node/miner.cpp b/src/node/miner.cpp index 48fff3d3e2921..697d2c0792909 100644 --- a/src/node/miner.cpp +++ b/src/node/miner.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -75,6 +76,7 @@ BlockAssembler::BlockAssembler(CChainState& chainstate, const NodeContext& node, m_mnhfman(*Assert(node.mnhf_manager)), m_clhandler(*Assert(Assert(node.llmq_ctx)->clhandler)), m_isman(*Assert(Assert(node.llmq_ctx)->isman)), + m_qsnapman(*llmq::quorumSnapshotManager), chainparams(params), m_mempool(mempool), m_quorum_block_processor(*Assert(Assert(node.llmq_ctx)->quorum_block_processor)), @@ -222,7 +224,7 @@ std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& sc cbTx.nHeight = nHeight; BlockValidationState state; - if (!CalcCbTxMerkleRootMNList(*pblock, pindexPrev, cbTx.merkleRootMNList, m_dmnman, state, m_chainstate.CoinsTip())) { + if (!CalcCbTxMerkleRootMNList(*pblock, pindexPrev, cbTx.merkleRootMNList, state, m_dmnman, m_qsnapman, m_chainstate.CoinsTip())) { throw std::runtime_error(strprintf("%s: CalcCbTxMerkleRootMNList failed: %s", __func__, state.ToString())); } if (fDIP0008Active_context) { diff --git a/src/node/miner.h b/src/node/miner.h index b7654a7d34f82..10919cadb7477 100644 --- a/src/node/miner.h +++ b/src/node/miner.h @@ -38,6 +38,7 @@ class CChainLocksHandler; class CInstantSendManager; class CQuorumBlockProcessor; class CQuorumManager; +class CQuorumSnapshotManager; } // namespace llmq static const bool DEFAULT_PRINTPRIORITY = false; @@ -174,6 +175,7 @@ class BlockAssembler CMNHFManager& m_mnhfman; llmq::CChainLocksHandler& m_clhandler; llmq::CInstantSendManager& m_isman; + llmq::CQuorumSnapshotManager& m_qsnapman; const CChainParams& chainparams; const CTxMemPool& m_mempool; const llmq::CQuorumBlockProcessor& m_quorum_block_processor; diff --git a/src/rpc/quorums.cpp b/src/rpc/quorums.cpp index e7da6e4a03ec5..ddf4d0dd93ab5 100644 --- a/src/rpc/quorums.cpp +++ b/src/rpc/quorums.cpp @@ -296,7 +296,7 @@ static RPCHelpMan quorum_dkgstatus() llmq::CDKGDebugStatus status; llmq_ctx.dkg_debugman->GetLocalDebugStatus(status); - auto ret = status.ToJson(*CHECK_NONFATAL(node.dmnman), chainman, detailLevel); + auto ret = status.ToJson(*CHECK_NONFATAL(node.dmnman), *llmq::quorumSnapshotManager, chainman, detailLevel); CBlockIndex* pindexTip = WITH_LOCK(cs_main, return chainman.ActiveChain().Tip()); int tipHeight = pindexTip->nHeight; @@ -324,8 +324,13 @@ static RPCHelpMan quorum_dkgstatus() obj.pushKV("quorumHash", pQuorumBaseBlockIndex->GetBlockHash().ToString()); obj.pushKV("pindexTip", pindexTip->nHeight); - auto allConnections = llmq::utils::GetQuorumConnections(llmq_params, *node.dmnman, *node.sporkman, pQuorumBaseBlockIndex, proTxHash, false); - auto outboundConnections = llmq::utils::GetQuorumConnections(llmq_params, *node.dmnman, *node.sporkman, pQuorumBaseBlockIndex, proTxHash, true); + auto allConnections = llmq::utils::GetQuorumConnections(llmq_params, *node.dmnman, + *llmq::quorumSnapshotManager, *node.sporkman, + pQuorumBaseBlockIndex, proTxHash, false); + auto outboundConnections = llmq::utils::GetQuorumConnections(llmq_params, *node.dmnman, + *llmq::quorumSnapshotManager, + *node.sporkman, pQuorumBaseBlockIndex, + proTxHash, true); std::map foundConnections; connman.ForEachNode([&](const CNode* pnode) { auto verifiedProRegTxHash = pnode->GetVerifiedProRegTxHash(); @@ -859,8 +864,8 @@ static RPCHelpMan quorum_rotationinfo() LOCK(cs_main); - if (!BuildQuorumRotationInfo(*CHECK_NONFATAL(node.dmnman), chainman, *llmq_ctx.qman, *llmq_ctx.quorum_block_processor, - cmd, quorumRotationInfoRet, strError)) { + if (!BuildQuorumRotationInfo(*CHECK_NONFATAL(node.dmnman), *llmq::quorumSnapshotManager, chainman, *llmq_ctx.qman, + *llmq_ctx.quorum_block_processor, cmd, quorumRotationInfoRet, strError)) { throw JSONRPCError(RPC_INVALID_REQUEST, strError); } diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 657d985a19596..046809a9f015c 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -479,7 +479,7 @@ CBlock TestChainSetup::CreateBlock( auto cbTx = GetTxPayload(*block.vtx[0]); Assert(cbTx.has_value()); BlockValidationState state; - if (!CalcCbTxMerkleRootMNList(block, chainstate.m_chain.Tip(), cbTx->merkleRootMNList, *m_node.dmnman, state, chainstate.CoinsTip())) { + if (!CalcCbTxMerkleRootMNList(block, chainstate.m_chain.Tip(), cbTx->merkleRootMNList, state, *m_node.dmnman, *llmq::quorumSnapshotManager, chainstate.CoinsTip())) { Assert(false); } if (!CalcCbTxMerkleRootQuorums(block, chainstate.m_chain.Tip(), *m_node.llmq_ctx->quorum_block_processor, cbTx->merkleRootQuorums, state)) { From b5a8240480c6b5193dd15edf1c00e45f9200bfcf Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Sat, 28 Dec 2024 07:33:44 +0000 Subject: [PATCH 10/11] refactor: remove `llmq::quorumSnapshotManager` global, move to `LLMQContext` --- src/init.cpp | 6 ++---- src/llmq/context.cpp | 13 +++++++------ src/llmq/context.h | 2 ++ src/llmq/snapshot.cpp | 2 -- src/llmq/snapshot.h | 3 --- src/net_processing.cpp | 2 +- src/node/chainstate.cpp | 12 ++---------- src/node/chainstate.h | 7 ------- src/node/miner.cpp | 2 +- src/rpc/quorums.cpp | 11 +++++------ src/test/util/setup_common.cpp | 14 +++++--------- 11 files changed, 25 insertions(+), 49 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index deaf8d237d9ca..39f5b1bcc59a3 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -104,7 +104,6 @@ #include #include #include -#include #include #include @@ -333,8 +332,8 @@ void PrepareShutdown(NodeContext& node) chainstate->ResetCoinsViews(); } } - DashChainstateSetupClose(node.chain_helper, node.cpoolman, node.dmnman, node.mnhf_manager, - llmq::quorumSnapshotManager, node.llmq_ctx, Assert(node.mempool.get())); + DashChainstateSetupClose(node.chain_helper, node.cpoolman, node.dmnman, node.mnhf_manager, node.llmq_ctx, + Assert(node.mempool.get())); node.mnhf_manager.reset(); node.evodb.reset(); } @@ -1856,7 +1855,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) node.dmnman, node.evodb, node.mnhf_manager, - llmq::quorumSnapshotManager, node.llmq_ctx, Assert(node.mempool.get()), fPruneMode, diff --git a/src/llmq/context.cpp b/src/llmq/context.cpp index 7998475868cce..876c38334f177 100644 --- a/src/llmq/context.cpp +++ b/src/llmq/context.cpp @@ -26,14 +26,15 @@ LLMQContext::LLMQContext(ChainstateManager& chainman, CDeterministicMNManager& d is_masternode{mn_activeman != nullptr}, bls_worker{std::make_shared()}, dkg_debugman{std::make_unique()}, - quorum_block_processor{std::make_unique(chainman.ActiveChainstate(), dmnman, evo_db, - *llmq::quorumSnapshotManager)}, + qsnapman{std::make_unique(evo_db)}, + quorum_block_processor{ + std::make_unique(chainman.ActiveChainstate(), dmnman, evo_db, *qsnapman)}, qdkgsman{std::make_unique(*bls_worker, chainman.ActiveChainstate(), dmnman, *dkg_debugman, - mn_metaman, *quorum_block_processor, *llmq::quorumSnapshotManager, - mn_activeman, sporkman, unit_tests, wipe)}, + mn_metaman, *quorum_block_processor, *qsnapman, mn_activeman, + sporkman, unit_tests, wipe)}, qman{std::make_unique(*bls_worker, chainman.ActiveChainstate(), dmnman, *qdkgsman, evo_db, - *quorum_block_processor, *llmq::quorumSnapshotManager, mn_activeman, - mn_sync, sporkman, unit_tests, wipe)}, + *quorum_block_processor, *qsnapman, mn_activeman, mn_sync, sporkman, + unit_tests, wipe)}, sigman{std::make_unique(mn_activeman, chainman.ActiveChainstate(), *qman, unit_tests, wipe)}, shareman{std::make_unique(*sigman, mn_activeman, *qman, sporkman)}, clhandler{std::make_unique(chainman.ActiveChainstate(), *qman, *sigman, *shareman, diff --git a/src/llmq/context.h b/src/llmq/context.h index 865d525a36fcd..deb395dce3fdc 100644 --- a/src/llmq/context.h +++ b/src/llmq/context.h @@ -28,6 +28,7 @@ class CEHFSignalsHandler; class CInstantSendManager; class CQuorumBlockProcessor; class CQuorumManager; +class CQuorumSnapshotManager; class CSigSharesManager; class CSigningManager; } @@ -61,6 +62,7 @@ struct LLMQContext { */ const std::shared_ptr bls_worker; const std::unique_ptr dkg_debugman; + const std::unique_ptr qsnapman; const std::unique_ptr quorum_block_processor; const std::unique_ptr qdkgsman; const std::unique_ptr qman; diff --git a/src/llmq/snapshot.cpp b/src/llmq/snapshot.cpp index e56ca051267e8..932139f8442b3 100644 --- a/src/llmq/snapshot.cpp +++ b/src/llmq/snapshot.cpp @@ -21,8 +21,6 @@ namespace llmq { static const std::string DB_QUORUM_SNAPSHOT = "llmq_S"; -std::unique_ptr quorumSnapshotManager; - UniValue CQuorumSnapshot::ToJson() const { UniValue obj; diff --git a/src/llmq/snapshot.h b/src/llmq/snapshot.h index caade91ad6ebb..b268c6db6e75f 100644 --- a/src/llmq/snapshot.h +++ b/src/llmq/snapshot.h @@ -229,9 +229,6 @@ class CQuorumSnapshotManager std::optional GetSnapshotForBlock(Consensus::LLMQType llmqType, const CBlockIndex* pindex); void StoreSnapshotForBlock(Consensus::LLMQType llmqType, const CBlockIndex* pindex, const CQuorumSnapshot& snapshot); }; - -extern std::unique_ptr quorumSnapshotManager; - } // namespace llmq #endif // BITCOIN_LLMQ_SNAPSHOT_H diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 87d1aa224b57a..2753f2a354ec1 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -5205,7 +5205,7 @@ void PeerManagerImpl::ProcessMessage( llmq::CQuorumRotationInfo quorumRotationInfoRet; std::string strError; - if (BuildQuorumRotationInfo(*m_dmnman, *llmq::quorumSnapshotManager, m_chainman, *m_llmq_ctx->qman, *m_llmq_ctx->quorum_block_processor, cmd, quorumRotationInfoRet, strError)) { + if (BuildQuorumRotationInfo(*m_dmnman, *m_llmq_ctx->qsnapman, m_chainman, *m_llmq_ctx->qman, *m_llmq_ctx->quorum_block_processor, cmd, quorumRotationInfoRet, strError)) { m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::QUORUMROTATIONINFO, quorumRotationInfoRet)); } else { strError = strprintf("getquorumrotationinfo failed for size(baseBlockHashes)=%d, blockRequestHash=%s. error=%s", cmd.baseBlockHashes.size(), cmd.blockRequestHash.ToString(), strError); diff --git a/src/node/chainstate.cpp b/src/node/chainstate.cpp index 37a3ed1986ef2..d379a0ee6531d 100644 --- a/src/node/chainstate.cpp +++ b/src/node/chainstate.cpp @@ -16,7 +16,6 @@ #include #include #include -#include std::optional LoadChainstate(bool fReset, ChainstateManager& chainman, @@ -30,7 +29,6 @@ std::optional LoadChainstate(bool fReset, std::unique_ptr& dmnman, std::unique_ptr& evodb, std::unique_ptr& mnhf_manager, - std::unique_ptr& qsnapman, std::unique_ptr& llmq_ctx, CTxMemPool* mempool, bool fPruneMode, @@ -74,7 +72,7 @@ std::optional LoadChainstate(bool fReset, pblocktree.reset(new CBlockTreeDB(nBlockTreeDBCache, block_tree_db_in_memory, fReset)); DashChainstateSetup(chainman, govman, mn_metaman, mn_sync, sporkman, mn_activeman, chain_helper, cpoolman, - dmnman, evodb, mnhf_manager, qsnapman, llmq_ctx, mempool, fReset, fReindexChainState, + dmnman, evodb, mnhf_manager, llmq_ctx, mempool, fReset, fReindexChainState, consensus_params); if (fReset) { @@ -210,7 +208,6 @@ void DashChainstateSetup(ChainstateManager& chainman, std::unique_ptr& dmnman, std::unique_ptr& evodb, std::unique_ptr& mnhf_manager, - std::unique_ptr& qsnapman, std::unique_ptr& llmq_ctx, CTxMemPool* mempool, bool fReset, @@ -224,9 +221,6 @@ void DashChainstateSetup(ChainstateManager& chainman, cpoolman.reset(); cpoolman = std::make_unique(*evodb); - qsnapman.reset(); - qsnapman.reset(new llmq::CQuorumSnapshotManager(*evodb)); - if (llmq_ctx) { llmq_ctx->Interrupt(); llmq_ctx->Stop(); @@ -240,7 +234,7 @@ void DashChainstateSetup(ChainstateManager& chainman, chain_helper.reset(); chain_helper = std::make_unique(*cpoolman, *dmnman, *mnhf_manager, govman, *(llmq_ctx->isman), *(llmq_ctx->quorum_block_processor), - *llmq::quorumSnapshotManager, chainman, consensus_params, mn_sync, sporkman, *(llmq_ctx->clhandler), + *(llmq_ctx->qsnapman), chainman, consensus_params, mn_sync, sporkman, *(llmq_ctx->clhandler), *(llmq_ctx->qman)); } @@ -248,7 +242,6 @@ void DashChainstateSetupClose(std::unique_ptr& chain_helper, std::unique_ptr& cpoolman, std::unique_ptr& dmnman, std::unique_ptr& mnhf_manager, - std::unique_ptr& qsnapman, std::unique_ptr& llmq_ctx, CTxMemPool* mempool) @@ -258,7 +251,6 @@ void DashChainstateSetupClose(std::unique_ptr& chain_helper, mnhf_manager->DisconnectManagers(); } llmq_ctx.reset(); - qsnapman.reset(); cpoolman.reset(); mempool->DisconnectManagers(); dmnman.reset(); diff --git a/src/node/chainstate.h b/src/node/chainstate.h index b2b3d98310811..c7b399177e412 100644 --- a/src/node/chainstate.h +++ b/src/node/chainstate.h @@ -25,10 +25,6 @@ class CSporkManager; class CTxMemPool; struct LLMQContext; -namespace llmq { -class CQuorumSnapshotManager; -} - namespace Consensus { struct Params; } @@ -91,7 +87,6 @@ std::optional LoadChainstate(bool fReset, std::unique_ptr& dmnman, std::unique_ptr& evodb, std::unique_ptr& mnhf_manager, - std::unique_ptr& qsnapman, std::unique_ptr& llmq_ctx, CTxMemPool* mempool, bool fPruneMode, @@ -123,7 +118,6 @@ void DashChainstateSetup(ChainstateManager& chainman, std::unique_ptr& dmnman, std::unique_ptr& evodb, std::unique_ptr& mnhf_manager, - std::unique_ptr& qsnapman, std::unique_ptr& llmq_ctx, CTxMemPool* mempool, bool fReset, @@ -134,7 +128,6 @@ void DashChainstateSetupClose(std::unique_ptr& chain_helper, std::unique_ptr& cpoolman, std::unique_ptr& dmnman, std::unique_ptr& mnhf_manager, - std::unique_ptr& qsnapman, std::unique_ptr& llmq_ctx, CTxMemPool* mempool); diff --git a/src/node/miner.cpp b/src/node/miner.cpp index 697d2c0792909..46518ae8ef109 100644 --- a/src/node/miner.cpp +++ b/src/node/miner.cpp @@ -76,7 +76,7 @@ BlockAssembler::BlockAssembler(CChainState& chainstate, const NodeContext& node, m_mnhfman(*Assert(node.mnhf_manager)), m_clhandler(*Assert(Assert(node.llmq_ctx)->clhandler)), m_isman(*Assert(Assert(node.llmq_ctx)->isman)), - m_qsnapman(*llmq::quorumSnapshotManager), + m_qsnapman(*Assert(Assert(node.llmq_ctx)->qsnapman)), chainparams(params), m_mempool(mempool), m_quorum_block_processor(*Assert(Assert(node.llmq_ctx)->quorum_block_processor)), diff --git a/src/rpc/quorums.cpp b/src/rpc/quorums.cpp index ddf4d0dd93ab5..bd2a4c82ab874 100644 --- a/src/rpc/quorums.cpp +++ b/src/rpc/quorums.cpp @@ -296,7 +296,7 @@ static RPCHelpMan quorum_dkgstatus() llmq::CDKGDebugStatus status; llmq_ctx.dkg_debugman->GetLocalDebugStatus(status); - auto ret = status.ToJson(*CHECK_NONFATAL(node.dmnman), *llmq::quorumSnapshotManager, chainman, detailLevel); + auto ret = status.ToJson(*CHECK_NONFATAL(node.dmnman), *llmq_ctx.qsnapman, chainman, detailLevel); CBlockIndex* pindexTip = WITH_LOCK(cs_main, return chainman.ActiveChain().Tip()); int tipHeight = pindexTip->nHeight; @@ -325,12 +325,11 @@ static RPCHelpMan quorum_dkgstatus() obj.pushKV("pindexTip", pindexTip->nHeight); auto allConnections = llmq::utils::GetQuorumConnections(llmq_params, *node.dmnman, - *llmq::quorumSnapshotManager, *node.sporkman, + *llmq_ctx.qsnapman, *node.sporkman, pQuorumBaseBlockIndex, proTxHash, false); auto outboundConnections = llmq::utils::GetQuorumConnections(llmq_params, *node.dmnman, - *llmq::quorumSnapshotManager, - *node.sporkman, pQuorumBaseBlockIndex, - proTxHash, true); + *llmq_ctx.qsnapman, *node.sporkman, + pQuorumBaseBlockIndex, proTxHash, true); std::map foundConnections; connman.ForEachNode([&](const CNode* pnode) { auto verifiedProRegTxHash = pnode->GetVerifiedProRegTxHash(); @@ -864,7 +863,7 @@ static RPCHelpMan quorum_rotationinfo() LOCK(cs_main); - if (!BuildQuorumRotationInfo(*CHECK_NONFATAL(node.dmnman), *llmq::quorumSnapshotManager, chainman, *llmq_ctx.qman, + if (!BuildQuorumRotationInfo(*CHECK_NONFATAL(node.dmnman), *llmq_ctx.qsnapman, chainman, *llmq_ctx.qman, *llmq_ctx.quorum_block_processor, cmd, quorumRotationInfoRet, strError)) { throw JSONRPCError(RPC_INVALID_REQUEST, strError); } diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 046809a9f015c..54e911f1e5186 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -112,14 +111,14 @@ void DashChainstateSetup(ChainstateManager& chainman, { DashChainstateSetup(chainman, *Assert(node.govman.get()), *Assert(node.mn_metaman.get()), *Assert(node.mn_sync.get()), *Assert(node.sporkman.get()), node.mn_activeman, node.chain_helper, node.cpoolman, node.dmnman, - node.evodb, node.mnhf_manager, llmq::quorumSnapshotManager, node.llmq_ctx, - Assert(node.mempool.get()), fReset, fReindexChainState, consensus_params); + node.evodb, node.mnhf_manager, node.llmq_ctx, Assert(node.mempool.get()), fReset, fReindexChainState, + consensus_params); } void DashChainstateSetupClose(NodeContext& node) { - DashChainstateSetupClose(node.chain_helper, node.cpoolman, node.dmnman, node.mnhf_manager, - llmq::quorumSnapshotManager, node.llmq_ctx, Assert(node.mempool.get())); + DashChainstateSetupClose(node.chain_helper, node.cpoolman, node.dmnman, node.mnhf_manager, node.llmq_ctx, + Assert(node.mempool.get())); } void DashPostChainstateSetup(NodeContext& node) @@ -203,7 +202,6 @@ BasicTestingSetup::BasicTestingSetup(const std::string& chainName, const std::ve fCheckBlockIndex = true; m_node.evodb = std::make_unique(1 << 20, true, true); m_node.mnhf_manager = std::make_unique(*m_node.evodb); - llmq::quorumSnapshotManager.reset(new llmq::CQuorumSnapshotManager(*m_node.evodb)); m_node.cpoolman = std::make_unique(*m_node.evodb); static bool noui_connected = false; if (!noui_connected) { @@ -217,7 +215,6 @@ BasicTestingSetup::~BasicTestingSetup() { SetMockTime(0s); // Reset mocktime for following tests m_node.cpoolman.reset(); - llmq::quorumSnapshotManager.reset(); m_node.mnhf_manager.reset(); m_node.evodb.reset(); m_node.connman.reset(); @@ -297,7 +294,6 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector(*block.vtx[0]); Assert(cbTx.has_value()); BlockValidationState state; - if (!CalcCbTxMerkleRootMNList(block, chainstate.m_chain.Tip(), cbTx->merkleRootMNList, state, *m_node.dmnman, *llmq::quorumSnapshotManager, chainstate.CoinsTip())) { + if (!CalcCbTxMerkleRootMNList(block, chainstate.m_chain.Tip(), cbTx->merkleRootMNList, state, *m_node.dmnman, *m_node.llmq_ctx->qsnapman, chainstate.CoinsTip())) { Assert(false); } if (!CalcCbTxMerkleRootQuorums(block, chainstate.m_chain.Tip(), *m_node.llmq_ctx->quorum_block_processor, cbTx->merkleRootQuorums, state)) { From bbb4687b54accf447532361e06af632e2c960b0c Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Sat, 28 Dec 2024 10:00:43 +0000 Subject: [PATCH 11/11] refactor: trim some unused headers, group Dash-specific headers together --- src/init.cpp | 38 ++++++++++--------------- src/test/util/setup_common.cpp | 27 ++++++++---------- src/validation.cpp | 7 +---- test/lint/lint-circular-dependencies.py | 3 -- 4 files changed, 28 insertions(+), 47 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 39f5b1bcc59a3..258be50fee660 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -71,43 +71,37 @@ #include #include #include - #include +#include -#include +#include #include #include -#ifdef ENABLE_WALLET -#include -#include -#endif // ENABLE_WALLET #include #include +#include +#include +#include #include #include +#include +#include +#include +#include #include +#include #include #include #include #include #include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include +#ifdef ENABLE_WALLET +#include +#include +#endif // ENABLE_WALLET + #include #include #include @@ -121,8 +115,6 @@ #include #include -#include - #ifndef WIN32 #include #include diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 54e911f1e5186..eb34f1d3fa7d7 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -12,18 +12,9 @@ #include #include #include -#include -#include #include #include #include -#include -#include -#include -#include -#include -#include -#include #include #include #include @@ -38,8 +29,6 @@ #include #include