From e786b4ccd55d22faac9bc8624ce69de81a945974 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Mon, 29 Sep 2025 16:17:41 +0000 Subject: [PATCH 01/11] refactor: move CDSTXManager out of CJContext We moved CCoinJoinServer to ActiveContext and 2/3 members of CJContext are conditionally initialized, let's move the unconditionally init'ed member out so we can conditionally initialize the whole object. --- src/coinjoin/context.cpp | 7 ++- src/coinjoin/context.h | 2 - src/dsnotificationinterface.cpp | 70 +++++++++++-------------- src/dsnotificationinterface.h | 3 ++ src/init.cpp | 22 ++++---- src/net_processing.cpp | 50 +++++++++--------- src/net_processing.h | 3 +- src/node/context.cpp | 1 + src/node/context.h | 2 + src/test/coinjoin_dstxmanager_tests.cpp | 4 +- src/test/denialofservice_tests.cpp | 8 +-- src/test/net_peer_connection_tests.cpp | 2 +- src/test/util/setup_common.cpp | 5 +- test/lint/lint-circular-dependencies.py | 1 - 14 files changed, 88 insertions(+), 92 deletions(-) diff --git a/src/coinjoin/context.cpp b/src/coinjoin/context.cpp index 52884e802b0e..af343d6742cc 100644 --- a/src/coinjoin/context.cpp +++ b/src/coinjoin/context.cpp @@ -7,19 +7,18 @@ #ifdef ENABLE_WALLET #include #endif // ENABLE_WALLET -#include CJContext::CJContext(ChainstateManager& chainman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, CTxMemPool& mempool, const CActiveMasternodeManager* const mn_activeman, - const CMasternodeSync& mn_sync, const llmq::CInstantSendManager& isman, bool relay_txes) : + const CMasternodeSync& mn_sync, const llmq::CInstantSendManager& isman, bool relay_txes) #ifdef ENABLE_WALLET + : 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}, + : nullptr} #endif // ENABLE_WALLET - dstxman{std::make_unique()} {} CJContext::~CJContext() {} diff --git a/src/coinjoin/context.h b/src/coinjoin/context.h index eb924f345772..8e71602928d2 100644 --- a/src/coinjoin/context.h +++ b/src/coinjoin/context.h @@ -13,7 +13,6 @@ class CActiveMasternodeManager; class CDeterministicMNManager; -class CDSTXManager; class ChainstateManager; class CMasternodeMetaMan; class CMasternodeSync; @@ -40,7 +39,6 @@ struct CJContext { const std::unique_ptr walletman; const std::unique_ptr queueman; #endif // ENABLE_WALLET - const std::unique_ptr dstxman; }; #endif // BITCOIN_COINJOIN_CONTEXT_H diff --git a/src/dsnotificationinterface.cpp b/src/dsnotificationinterface.cpp index 484a564039ab..bf71b87a3b9d 100644 --- a/src/dsnotificationinterface.cpp +++ b/src/dsnotificationinterface.cpp @@ -2,39 +2,47 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include -#ifdef ENABLE_WALLET -#include -#endif // ENABLE_WALLET -#include + #include -#include -#include + +#include #include #include +#include +#include #include #include +#include #include #include #include #include #include +#include + +#ifdef ENABLE_WALLET +#include +#endif // ENABLE_WALLET CDSNotificationInterface::CDSNotificationInterface(CConnman& connman, + CDSTXManager& dstxman, CMasternodeSync& mn_sync, CGovernanceManager& govman, const ChainstateManager& chainman, const std::unique_ptr& dmnman, const std::unique_ptr& llmq_ctx, - const std::unique_ptr& cj_ctx) - : m_connman(connman), + const std::unique_ptr& cj_ctx) : + m_connman(connman), + m_dstxman(dstxman), m_mn_sync(mn_sync), m_govman(govman), m_chainman(chainman), m_dmnman(dmnman), m_llmq_ctx(llmq_ctx), - m_cj_ctx(cj_ctx) {} + m_cj_ctx(cj_ctx) +{ +} void CDSNotificationInterface::InitializeCurrentBlockTip() { @@ -44,9 +52,7 @@ void CDSNotificationInterface::InitializeCurrentBlockTip() void CDSNotificationInterface::AcceptedBlockHeader(const CBlockIndex *pindexNew) { - assert(m_llmq_ctx); - - m_llmq_ctx->clhandler->AcceptedBlockHeader(pindexNew); + Assert(m_llmq_ctx)->clhandler->AcceptedBlockHeader(pindexNew); m_mn_sync.AcceptedBlockHeader(pindexNew); } @@ -57,18 +63,14 @@ void CDSNotificationInterface::NotifyHeaderTip(const CBlockIndex *pindexNew, boo void CDSNotificationInterface::SynchronousUpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) { - assert(m_dmnman); - if (pindexNew == pindexFork) // blocks were disconnected without any new ones return; - m_dmnman->UpdatedBlockTip(pindexNew); + Assert(m_dmnman)->UpdatedBlockTip(pindexNew); } void CDSNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) { - assert(m_cj_ctx && m_llmq_ctx); - if (pindexNew == pindexFork) // blocks were disconnected without any new ones return; @@ -77,9 +79,9 @@ void CDSNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, con if (fInitialDownload) return; - m_cj_ctx->dstxman->UpdatedBlockTip(pindexNew, *m_llmq_ctx->clhandler, m_mn_sync); + m_dstxman.UpdatedBlockTip(pindexNew, *Assert(m_llmq_ctx)->clhandler, m_mn_sync); #ifdef ENABLE_WALLET - m_cj_ctx->walletman->ForEachCJClientMan( + Assert(m_cj_ctx)->walletman->ForEachCJClientMan( [&pindexNew](std::unique_ptr& clientman) { clientman->UpdatedBlockTip(pindexNew); }); #endif // ENABLE_WALLET @@ -97,37 +99,29 @@ void CDSNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, con void CDSNotificationInterface::TransactionAddedToMempool(const CTransactionRef& ptx, int64_t nAcceptTime, uint64_t mempool_sequence) { - assert(m_cj_ctx && m_llmq_ctx); - - m_llmq_ctx->isman->TransactionAddedToMempool(ptx); + Assert(m_llmq_ctx)->isman->TransactionAddedToMempool(ptx); m_llmq_ctx->clhandler->TransactionAddedToMempool(ptx, nAcceptTime); - m_cj_ctx->dstxman->TransactionAddedToMempool(ptx); + m_dstxman.TransactionAddedToMempool(ptx); } void CDSNotificationInterface::TransactionRemovedFromMempool(const CTransactionRef& ptx, MemPoolRemovalReason reason, uint64_t mempool_sequence) { - assert(m_llmq_ctx); - - m_llmq_ctx->isman->TransactionRemovedFromMempool(ptx); + Assert(m_llmq_ctx)->isman->TransactionRemovedFromMempool(ptx); } void CDSNotificationInterface::BlockConnected(const std::shared_ptr& pblock, const CBlockIndex* pindex) { - assert(m_cj_ctx && m_llmq_ctx); - - m_llmq_ctx->isman->BlockConnected(pblock, pindex); + Assert(m_llmq_ctx)->isman->BlockConnected(pblock, pindex); m_llmq_ctx->clhandler->BlockConnected(pblock, pindex); - m_cj_ctx->dstxman->BlockConnected(pblock, pindex); + m_dstxman.BlockConnected(pblock, pindex); } void CDSNotificationInterface::BlockDisconnected(const std::shared_ptr& pblock, const CBlockIndex* pindexDisconnected) { - assert(m_cj_ctx && m_llmq_ctx); - - m_llmq_ctx->isman->BlockDisconnected(pblock, pindexDisconnected); + Assert(m_llmq_ctx)->isman->BlockDisconnected(pblock, pindexDisconnected); m_llmq_ctx->clhandler->BlockDisconnected(pblock, pindexDisconnected); - m_cj_ctx->dstxman->BlockDisconnected(pblock, pindexDisconnected); + m_dstxman.BlockDisconnected(pblock, pindexDisconnected); } void CDSNotificationInterface::NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff) @@ -141,10 +135,8 @@ void CDSNotificationInterface::NotifyMasternodeListChanged(bool undo, const CDet void CDSNotificationInterface::NotifyChainLock(const CBlockIndex* pindex, const std::shared_ptr& clsig) { - assert(m_cj_ctx && m_llmq_ctx); - - m_llmq_ctx->isman->NotifyChainLock(pindex); - m_cj_ctx->dstxman->NotifyChainLock(pindex, *m_llmq_ctx->clhandler, m_mn_sync); + Assert(m_llmq_ctx)->isman->NotifyChainLock(pindex); + m_dstxman.NotifyChainLock(pindex, *m_llmq_ctx->clhandler, m_mn_sync); } std::unique_ptr g_ds_notification_interface; diff --git a/src/dsnotificationinterface.h b/src/dsnotificationinterface.h index bcb614006b6f..90cea2a37557 100644 --- a/src/dsnotificationinterface.h +++ b/src/dsnotificationinterface.h @@ -8,6 +8,7 @@ #include class CConnman; +class CDSTXManager; class CDeterministicMNManager; class CGovernanceManager; class ChainstateManager; @@ -19,6 +20,7 @@ class CDSNotificationInterface : public CValidationInterface { public: explicit CDSNotificationInterface(CConnman& connman, + CDSTXManager& dstxman, CMasternodeSync& mn_sync, CGovernanceManager& govman, const ChainstateManager& chainman, @@ -46,6 +48,7 @@ class CDSNotificationInterface : public CValidationInterface private: CConnman& m_connman; + CDSTXManager& m_dstxman; CMasternodeSync& m_mn_sync; CGovernanceManager& m_govman; const ChainstateManager& m_chainman; diff --git a/src/init.cpp b/src/init.cpp index 0753588739f1..bf72cd08e739 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -388,6 +388,7 @@ void PrepareShutdown(NodeContext& node) // After all wallets are removed, destroy all CoinJoin objects // and reset them to nullptr node.cj_ctx.reset(); + node.dstxman.reset(); UnregisterAllValidationInterfaces(); GetMainSignals().UnregisterBackgroundSignalScheduler(); @@ -2131,36 +2132,35 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) ChainstateManager& chainman = *Assert(node.chainman); + node.dstxman = std::make_unique(); + node.cj_ctx = std::make_unique(chainman, *node.dmnman, *node.mn_metaman, *node.mempool, + node.mn_activeman.get(), *node.mn_sync, *node.llmq_ctx->isman, + !ignores_incoming_txs); + assert(!node.peerman); - node.peerman = PeerManager::make(chainparams, *node.connman, *node.addrman, node.banman.get(), + node.peerman = PeerManager::make(chainparams, *node.connman, *node.addrman, node.banman.get(), *node.dstxman, chainman, *node.mempool, *node.mn_metaman, *node.mn_sync, *node.govman, *node.sporkman, node.mn_activeman.get(), node.dmnman, node.active_ctx, node.cj_ctx, node.llmq_ctx, ignores_incoming_txs); RegisterValidationInterface(node.peerman.get()); g_ds_notification_interface = std::make_unique( - *node.connman, *node.mn_sync, *node.govman, chainman, node.dmnman, node.llmq_ctx, node.cj_ctx + *node.connman, *node.dstxman, *node.mn_sync, *node.govman, chainman, node.dmnman, node.llmq_ctx, node.cj_ctx ); RegisterValidationInterface(g_ds_notification_interface.get()); - // ********************************************************* Step 7c: Setup CoinJoin - - node.cj_ctx = std::make_unique(chainman, *node.dmnman, *node.mn_metaman, *node.mempool, - node.mn_activeman.get(), *node.mn_sync, *node.llmq_ctx->isman, - !ignores_incoming_txs); - - // ********************************************************* Step 7d: Setup masternode mode + // ********************************************************* Step 7c: Setup masternode mode assert(!node.active_ctx); assert(!g_active_notification_interface); if (node.mn_activeman) { - node.active_ctx = std::make_unique(chainman, *node.connman, *node.dmnman, *node.cj_ctx->dstxman, *node.govman, *node.mn_metaman, + node.active_ctx = std::make_unique(chainman, *node.connman, *node.dmnman, *node.dstxman, *node.govman, *node.mn_metaman, *node.mnhf_manager, *node.sporkman, *node.mempool, *node.llmq_ctx, *node.peerman, *node.mn_activeman, *node.mn_sync); g_active_notification_interface = std::make_unique(*node.active_ctx, *node.mn_activeman); RegisterValidationInterface(g_active_notification_interface.get()); } - // ********************************************************* Step 7e: Setup other Dash services + // ********************************************************* Step 7d: Setup other Dash services bool fLoadCacheFiles = !(fReindex || fReindexChainState) && (chainman.ActiveChain().Tip() != nullptr); diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 63d5aac9657b..01d7b0e33e8e 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -592,15 +592,12 @@ class PeerManagerImpl final : public PeerManager { public: PeerManagerImpl(const CChainParams& chainparams, CConnman& connman, AddrMan& addrman, BanMan* banman, - ChainstateManager& chainman, CTxMemPool& pool, - CMasternodeMetaMan& mn_metaman, CMasternodeSync& mn_sync, - CGovernanceManager& govman, CSporkManager& sporkman, - const CActiveMasternodeManager* const mn_activeman, + CDSTXManager& dstxman, ChainstateManager& chainman, CTxMemPool& pool, + CMasternodeMetaMan& mn_metaman, CMasternodeSync& mn_sync, CGovernanceManager& govman, + CSporkManager& sporkman, const CActiveMasternodeManager* const mn_activeman, const std::unique_ptr& dmnman, - const std::unique_ptr& active_ctx, - const std::unique_ptr& cj_ctx, - const std::unique_ptr& llmq_ctx, - bool ignore_incoming_txs); + const std::unique_ptr& active_ctx, const std::unique_ptr& cj_ctx, + const std::unique_ptr& llmq_ctx, bool ignore_incoming_txs); /** Overridden from CValidationInterface. */ void BlockConnected(const std::shared_ptr& pblock, const CBlockIndex* pindexConnected) override @@ -789,6 +786,7 @@ class PeerManagerImpl final : public PeerManager AddrMan& m_addrman; /** Pointer to this node's banman. May be nullptr - check existence before dereferencing. */ BanMan* const m_banman; + CDSTXManager& m_dstxman; ChainstateManager& m_chainman; CTxMemPool& m_mempool; std::unique_ptr m_txreconciliation; @@ -1960,33 +1958,33 @@ std::optional PeerManagerImpl::FetchBlock(NodeId peer_id, const CBl return std::nullopt; } -std::unique_ptr PeerManager::make(const CChainParams& chainparams, CConnman& connman, AddrMan& addrman, BanMan* banman, - ChainstateManager& chainman, CTxMemPool& pool, - CMasternodeMetaMan& mn_metaman, CMasternodeSync& mn_sync, - CGovernanceManager& govman, CSporkManager& sporkman, +std::unique_ptr PeerManager::make(const CChainParams& chainparams, CConnman& connman, AddrMan& addrman, + BanMan* banman, CDSTXManager& dstxman, ChainstateManager& chainman, + CTxMemPool& pool, CMasternodeMetaMan& mn_metaman, + CMasternodeSync& mn_sync, CGovernanceManager& govman, + CSporkManager& sporkman, const CActiveMasternodeManager* const mn_activeman, const std::unique_ptr& dmnman, const std::unique_ptr& active_ctx, const std::unique_ptr& cj_ctx, const std::unique_ptr& llmq_ctx, bool ignore_incoming_txs) { - return std::make_unique(chainparams, connman, addrman, banman, chainman, pool, mn_metaman, mn_sync, govman, sporkman, mn_activeman, dmnman, active_ctx, cj_ctx, llmq_ctx, ignore_incoming_txs); + return std::make_unique(chainparams, connman, addrman, banman, dstxman, chainman, pool, mn_metaman, mn_sync, govman, sporkman, mn_activeman, dmnman, active_ctx, cj_ctx, llmq_ctx, ignore_incoming_txs); } PeerManagerImpl::PeerManagerImpl(const CChainParams& chainparams, CConnman& connman, AddrMan& addrman, BanMan* banman, - ChainstateManager& chainman, CTxMemPool& pool, - CMasternodeMetaMan& mn_metaman, CMasternodeSync& mn_sync, - CGovernanceManager& govman, CSporkManager& sporkman, - const CActiveMasternodeManager* const mn_activeman, + CDSTXManager& dstxman, ChainstateManager& chainman, CTxMemPool& pool, + CMasternodeMetaMan& mn_metaman, CMasternodeSync& mn_sync, CGovernanceManager& govman, + CSporkManager& sporkman, const CActiveMasternodeManager* const mn_activeman, const std::unique_ptr& dmnman, const std::unique_ptr& active_ctx, const std::unique_ptr& cj_ctx, - const std::unique_ptr& llmq_ctx, - bool ignore_incoming_txs) + const std::unique_ptr& llmq_ctx, bool ignore_incoming_txs) : m_chainparams(chainparams), m_connman(connman), m_addrman(addrman), m_banman(banman), + m_dstxman(dstxman), m_chainman(chainman), m_mempool(pool), m_dmnman(dmnman), @@ -2242,7 +2240,7 @@ bool PeerManagerImpl::AlreadyHave(const CInv& inv) m_llmq_ctx->isman->IsLocked(inv.hash); return (!fIgnoreRecentRejects && m_recent_rejects.contains(inv.hash)) || - (inv.IsMsgDstx() && static_cast(m_cj_ctx->dstxman->GetDSTX(inv.hash))) || + (inv.IsMsgDstx() && static_cast(m_dstxman.GetDSTX(inv.hash))) || m_mempool.exists(inv.hash) || (g_txindex != nullptr && g_txindex->HasTx(inv.hash)); } @@ -2459,7 +2457,7 @@ void PeerManagerImpl::RelayTransaction(const uint256& txid) void PeerManagerImpl::_RelayTransaction(const uint256& txid) { - const CInv inv{m_cj_ctx->dstxman->GetDSTX(txid) ? MSG_DSTX : MSG_TX, txid}; + const CInv inv{m_dstxman.GetDSTX(txid) ? MSG_DSTX : MSG_TX, txid}; LOCK(m_peer_mutex); for(auto& it : m_peer_map) { Peer& peer = *it.second; @@ -2751,7 +2749,7 @@ void PeerManagerImpl::ProcessGetData(CNode& pfrom, Peer& peer, const std::atomic if (tx) { CCoinJoinBroadcastTx dstx; if (inv.IsMsgDstx()) { - dstx = m_cj_ctx->dstxman->GetDSTX(inv.hash); + dstx = m_dstxman.GetDSTX(inv.hash); } if (dstx) { m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::DSTX, dstx)); @@ -4565,7 +4563,7 @@ void PeerManagerImpl::ProcessMessage( if (nInvType == MSG_DSTX) { // Validate DSTX and return bRet if we need to return from here uint256 hashTx = tx.GetHash(); - const auto& [bRet, bDoReturn] = ValidateDSTX(*m_dmnman, *(m_cj_ctx->dstxman), m_chainman, m_mn_metaman, m_mempool, dstx, hashTx); + const auto& [bRet, bDoReturn] = ValidateDSTX(*m_dmnman, m_dstxman, m_chainman, m_mn_metaman, m_mempool, dstx, hashTx); if (bDoReturn) { return; } @@ -4597,7 +4595,7 @@ void PeerManagerImpl::ProcessMessage( if (nInvType == MSG_DSTX) { LogPrint(BCLog::COINJOIN, "DSTX -- Masternode transaction accepted, txid=%s, peer=%d\n", tx.GetHash().ToString(), pfrom.GetId()); - m_cj_ctx->dstxman->AddDSTX(dstx); + m_dstxman.AddDSTX(dstx); } _RelayTransaction(tx.GetHash()); @@ -6205,7 +6203,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto) tx_relay->m_tx_inventory_to_send.erase(hash); if (tx_relay->m_bloom_filter && !tx_relay->m_bloom_filter->IsRelevantAndUpdate(*txinfo.tx)) continue; - int nInvType = m_cj_ctx->dstxman->GetDSTX(hash) ? MSG_DSTX : MSG_TX; + int nInvType = m_dstxman.GetDSTX(hash) ? MSG_DSTX : MSG_TX; tx_relay->m_tx_inventory_known_filter.insert(hash); queueAndMaybePushInv(CInv(nInvType, hash)); @@ -6280,7 +6278,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto) g_relay_expiration.emplace_back(current_time + RELAY_TX_CACHE_TIME, ret.first); } } - int nInvType = m_cj_ctx->dstxman->GetDSTX(hash) ? MSG_DSTX : MSG_TX; + int nInvType = m_dstxman.GetDSTX(hash) ? MSG_DSTX : MSG_TX; tx_relay->m_tx_inventory_known_filter.insert(hash); queueAndMaybePushInv(CInv(nInvType, hash)); } diff --git a/src/net_processing.h b/src/net_processing.h index 56efc63adce8..27f9091845ff 100644 --- a/src/net_processing.h +++ b/src/net_processing.h @@ -17,6 +17,7 @@ class AddrMan; class CTxMemPool; class CCoinJoinQueue; class CDeterministicMNManager; +class CDSTXManager; class CMasternodeMetaMan; class CMasternodeSync; class ChainstateManager; @@ -56,7 +57,7 @@ class PeerManager : public CValidationInterface, public NetEventsInterface { public: static std::unique_ptr make(const CChainParams& chainparams, CConnman& connman, AddrMan& addrman, - BanMan* banman, ChainstateManager& chainman, + BanMan* banman, CDSTXManager& dstxman, ChainstateManager& chainman, CTxMemPool& pool, CMasternodeMetaMan& mn_metaman, CMasternodeSync& mn_sync, CGovernanceManager& govman, CSporkManager& sporkman, const CActiveMasternodeManager* const mn_activeman, diff --git a/src/node/context.cpp b/src/node/context.cpp index e8407d8548f6..f63b1f4fca0a 100644 --- a/src/node/context.cpp +++ b/src/node/context.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include diff --git a/src/node/context.h b/src/node/context.h index fc04830e72d6..439fd3a8aab8 100644 --- a/src/node/context.h +++ b/src/node/context.h @@ -18,6 +18,7 @@ class CBlockPolicyEstimator; class CConnman; class CCreditPoolManager; class CDeterministicMNManager; +class CDSTXManager; class CChainstateHelper; class ChainstateManager; class CEvoDB; @@ -80,6 +81,7 @@ struct NodeContext { //! Dash managers std::unique_ptr mn_activeman; std::unique_ptr cpoolman; + std::unique_ptr dstxman; std::unique_ptr evodb; std::unique_ptr chain_helper; std::unique_ptr dmnman; diff --git a/src/test/coinjoin_dstxmanager_tests.cpp b/src/test/coinjoin_dstxmanager_tests.cpp index bbe5c94c74ee..04e9ce5f93e7 100644 --- a/src/test/coinjoin_dstxmanager_tests.cpp +++ b/src/test/coinjoin_dstxmanager_tests.cpp @@ -39,7 +39,7 @@ static CCoinJoinBroadcastTx MakeDSTX(int vin_vout_count = 3) BOOST_AUTO_TEST_CASE(add_get_dstx) { CCoinJoinBroadcastTx dstx = MakeDSTX(); - auto& man = *Assert(Assert(m_node.cj_ctx)->dstxman); + auto& man = *Assert(m_node.dstxman); // Not present initially BOOST_CHECK(!man.GetDSTX(dstx.tx->GetHash())); // Add @@ -53,7 +53,7 @@ BOOST_AUTO_TEST_CASE(add_get_dstx) BOOST_AUTO_TEST_CASE(update_heights_block_connect_disconnect) { CCoinJoinBroadcastTx dstx = MakeDSTX(); - auto& man = *Assert(Assert(m_node.cj_ctx)->dstxman); + auto& man = *Assert(m_node.dstxman); man.AddDSTX(dstx); // Create a fake block containing the tx diff --git a/src/test/denialofservice_tests.cpp b/src/test/denialofservice_tests.cpp index 06c92a1434c5..d8e573c61c63 100644 --- a/src/test/denialofservice_tests.cpp +++ b/src/test/denialofservice_tests.cpp @@ -148,7 +148,7 @@ BOOST_AUTO_TEST_CASE(stale_tip_peer_management) NodeId id{0}; const CChainParams& chainparams = Params(); auto connman = std::make_unique(0x1337, 0x1337, *m_node.addrman, *m_node.netgroupman); - auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, /*banman=*/nullptr, + auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, /*banman=*/nullptr, *m_node.dstxman, *m_node.chainman, *m_node.mempool, *m_node.mn_metaman, *m_node.mn_sync, *m_node.govman, *m_node.sporkman, /*mn_activeman=*/ nullptr, m_node.dmnman, /*active_ctx=*/nullptr, m_node.cj_ctx, m_node.llmq_ctx, /*ignore_incoming_txs=*/false); @@ -252,7 +252,7 @@ BOOST_AUTO_TEST_CASE(block_relay_only_eviction) NodeId id{0}; const CChainParams& chainparams = Params(); auto connman = std::make_unique(0x1337, 0x1337, *m_node.addrman, *m_node.netgroupman); - auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, /*banman=*/nullptr, + auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, /*banman=*/nullptr, *m_node.dstxman, *m_node.chainman, *m_node.mempool, *m_node.mn_metaman, *m_node.mn_sync, *m_node.govman, *m_node.sporkman, /*mn_activeman=*/ nullptr, m_node.dmnman, /*active_ctx=*/nullptr, m_node.cj_ctx, m_node.llmq_ctx, /*ignore_incoming_txs=*/false); @@ -319,7 +319,7 @@ BOOST_AUTO_TEST_CASE(peer_discouragement) const CChainParams& chainparams = Params(); auto banman = std::make_unique(m_args.GetDataDirBase() / "banlist", nullptr, DEFAULT_MISBEHAVING_BANTIME); auto connman = std::make_unique(0x1337, 0x1337, *m_node.addrman, *m_node.netgroupman); - auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, banman.get(), + auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, banman.get(), *m_node.dstxman, *m_node.chainman, *m_node.mempool, *m_node.mn_metaman, *m_node.mn_sync, *m_node.govman, *m_node.sporkman, /*mn_activeman=*/nullptr, m_node.dmnman, /*active_ctx=*/nullptr, m_node.cj_ctx, m_node.llmq_ctx, /*ignore_incoming_txs=*/false); @@ -424,7 +424,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime) const CChainParams& chainparams = Params(); auto banman = std::make_unique(m_args.GetDataDirBase() / "banlist", nullptr, DEFAULT_MISBEHAVING_BANTIME); auto connman = std::make_unique(0x1337, 0x1337, *m_node.addrman, *m_node.netgroupman); - auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, banman.get(), + auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, banman.get(), *m_node.dstxman, *m_node.chainman, *m_node.mempool, *m_node.mn_metaman, *m_node.mn_sync, *m_node.govman, *m_node.sporkman, /*mn_activeman=*/nullptr, m_node.dmnman, /*active_ctx=*/nullptr, m_node.cj_ctx, m_node.llmq_ctx, /*ignore_incoming_txs=*/false); diff --git a/src/test/net_peer_connection_tests.cpp b/src/test/net_peer_connection_tests.cpp index ac8e307f463c..a883f9c6ba1e 100644 --- a/src/test/net_peer_connection_tests.cpp +++ b/src/test/net_peer_connection_tests.cpp @@ -85,7 +85,7 @@ BOOST_AUTO_TEST_CASE(test_addnode_getaddednodeinfo_and_connection_detection) { const auto& chainparams = Params(); auto connman = std::make_unique(0x1337, 0x1337, *m_node.addrman, *m_node.netgroupman); - auto peerman = PeerManager::make(chainparams, *connman, *m_node.addrman, nullptr, + auto peerman = PeerManager::make(chainparams, *connman, *m_node.addrman, /*banman=*/nullptr, *m_node.dstxman, *m_node.chainman, *m_node.mempool, *m_node.mn_metaman, *m_node.mn_sync, *m_node.govman, *m_node.sporkman, /*mn_activeman=*/nullptr, m_node.dmnman, /*active_ctx=*/nullptr, m_node.cj_ctx, m_node.llmq_ctx, /*ignore_incoming_txs=*/false); diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 7942e3c2a57f..6881691e9e6e 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -48,6 +48,7 @@ #include #include +#include #include #include #include @@ -340,8 +341,9 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector(); m_node.banman = std::make_unique(m_args.GetDataDirBase() / "banlist", nullptr, DEFAULT_MISBEHAVING_BANTIME); - m_node.peerman = PeerManager::make(chainparams, *m_node.connman, *m_node.addrman, m_node.banman.get(), + m_node.peerman = PeerManager::make(chainparams, *m_node.connman, *m_node.addrman, m_node.banman.get(), *m_node.dstxman, *m_node.chainman, *m_node.mempool, *m_node.mn_metaman, *m_node.mn_sync, *m_node.govman, *m_node.sporkman, /*mn_activeman=*/nullptr, m_node.dmnman, /*active_ctx=*/nullptr, m_node.cj_ctx, m_node.llmq_ctx, /*ignore_incoming_txs=*/false); @@ -400,6 +402,7 @@ TestingSetup::~TestingSetup() m_node.peerman.reset(); m_node.banman.reset(); + m_node.dstxman.reset(); } TestChain100Setup::TestChain100Setup(const std::string& chain_name, const std::vector& extra_args) diff --git a/test/lint/lint-circular-dependencies.py b/test/lint/lint-circular-dependencies.py index 32718063789b..bcd5aa0ecc5b 100755 --- a/test/lint/lint-circular-dependencies.py +++ b/test/lint/lint-circular-dependencies.py @@ -32,7 +32,6 @@ "chainlock/signing -> instantsend/instantsend -> net_processing -> masternode/active/context -> chainlock/signing", "coinjoin/client -> net_processing -> coinjoin/client", "coinjoin/client -> net_processing -> coinjoin/context -> coinjoin/client", - "coinjoin/coinjoin -> instantsend/instantsend -> net_processing -> coinjoin/context -> coinjoin/coinjoin", "coinjoin/server -> net_processing -> coinjoin/server", "coinjoin/server -> net_processing -> masternode/active/context -> coinjoin/server", "common/bloom -> evo/assetlocktx -> llmq/commitment -> evo/deterministicmns -> evo/simplifiedmns -> merkleblock -> common/bloom", From 2606d8c9cb9dfd5df66fdb16f3283adbcf832494 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Mon, 8 Sep 2025 13:59:36 +0000 Subject: [PATCH 02/11] refactor: obscure scheduled CoinJoin tasks by moving into context --- src/coinjoin/context.cpp | 22 ++++++++++++++++++---- src/coinjoin/context.h | 9 +++++++++ src/init.cpp | 9 ++++----- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/coinjoin/context.cpp b/src/coinjoin/context.cpp index af343d6742cc..c501f3d80e45 100644 --- a/src/coinjoin/context.cpp +++ b/src/coinjoin/context.cpp @@ -4,6 +4,8 @@ #include +#include + #ifdef ENABLE_WALLET #include #endif // ENABLE_WALLET @@ -13,12 +15,24 @@ CJContext::CJContext(ChainstateManager& chainman, CDeterministicMNManager& dmnma const CMasternodeSync& mn_sync, const llmq::CInstantSendManager& isman, bool relay_txes) #ifdef ENABLE_WALLET : + m_relay_txes{relay_txes}, 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} + queueman{m_relay_txes ? std::make_unique(*walletman, dmnman, mn_metaman, mn_sync, + /*is_masternode=*/mn_activeman != nullptr) + : nullptr} #endif // ENABLE_WALLET {} -CJContext::~CJContext() {} +CJContext::~CJContext() = default; + +void CJContext::Schedule(CConnman& connman, CScheduler& scheduler) +{ +#ifdef ENABLE_WALLET + if (!m_relay_txes) return; + scheduler.scheduleEvery(std::bind(&CCoinJoinClientQueueManager::DoMaintenance, std::ref(*queueman)), + std::chrono::seconds{1}); + scheduler.scheduleEvery(std::bind(&CoinJoinWalletManager::DoMaintenance, std::ref(*walletman), std::ref(connman)), + std::chrono::seconds{1}); +#endif // ENABLE_WALLET +} diff --git a/src/coinjoin/context.h b/src/coinjoin/context.h index 8e71602928d2..be77e4f14546 100644 --- a/src/coinjoin/context.h +++ b/src/coinjoin/context.h @@ -12,10 +12,12 @@ #include class CActiveMasternodeManager; +class CConnman; class CDeterministicMNManager; class ChainstateManager; class CMasternodeMetaMan; class CMasternodeSync; +class CScheduler; class CTxMemPool; namespace llmq { class CInstantSendManager; @@ -27,6 +29,7 @@ class CoinJoinWalletManager; #endif // ENABLE_WALLET struct CJContext { +public: CJContext() = delete; CJContext(const CJContext&) = delete; CJContext(ChainstateManager& chainman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, @@ -34,7 +37,13 @@ struct CJContext { const llmq::CInstantSendManager& isman, bool relay_txes); ~CJContext(); + void Schedule(CConnman& connman, CScheduler& scheduler); + #ifdef ENABLE_WALLET +private: + const bool m_relay_txes; + +public: // The main object for accessing mixing const std::unique_ptr walletman; const std::unique_ptr queueman; diff --git a/src/init.cpp b/src/init.cpp index bf72cd08e739..acc253159d4e 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -2267,11 +2267,10 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) if (node.mn_activeman) { node.scheduler->scheduleEvery(std::bind(&CCoinJoinServer::DoMaintenance, std::ref(*node.active_ctx->cj_server)), std::chrono::seconds{1}); node.scheduler->scheduleEvery(std::bind(&llmq::CDKGSessionManager::CleanupOldContributions, std::ref(*node.llmq_ctx->qdkgsman)), std::chrono::hours{1}); -#ifdef ENABLE_WALLET - } else if (!ignores_incoming_txs) { - node.scheduler->scheduleEvery(std::bind(&CCoinJoinClientQueueManager::DoMaintenance, std::ref(*node.cj_ctx->queueman)), std::chrono::seconds{1}); - node.scheduler->scheduleEvery(std::bind(&CoinJoinWalletManager::DoMaintenance, std::ref(*node.cj_ctx->walletman), std::ref(*node.connman)), std::chrono::seconds{1}); -#endif // ENABLE_WALLET + } + + if (node.cj_ctx) { + node.cj_ctx->Schedule(*node.connman, *node.scheduler); } if (::g_stats_client->active()) { From cebe18bbd44cf98adae6b7e580134033fdffdb97 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Mon, 8 Sep 2025 13:59:46 +0000 Subject: [PATCH 03/11] refactor: remove `ENABLE_WALLET` from `dsnotificationinterface.cpp` Currently a lot of non-wallet code is peppered with `ENABLE_WALLET` due to wallet-only CoinJoin managers, we need to contain them. --- src/coinjoin/context.cpp | 11 +++++++++++ src/coinjoin/context.h | 11 +++++++++-- src/dsnotificationinterface.cpp | 18 +++--------------- src/dsnotificationinterface.h | 5 +---- src/init.cpp | 17 +++++++++++------ 5 files changed, 35 insertions(+), 27 deletions(-) diff --git a/src/coinjoin/context.cpp b/src/coinjoin/context.cpp index c501f3d80e45..c1c84d3fe52b 100644 --- a/src/coinjoin/context.cpp +++ b/src/coinjoin/context.cpp @@ -36,3 +36,14 @@ void CJContext::Schedule(CConnman& connman, CScheduler& scheduler) std::chrono::seconds{1}); #endif // ENABLE_WALLET } + +void CJContext::UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, bool fInitialDownload) +{ +#ifdef ENABLE_WALLET + if (fInitialDownload || pindexNew == pindexFork) // In IBD or blocks were disconnected without any new ones + return; + + walletman->ForEachCJClientMan( + [&pindexNew](std::unique_ptr& clientman) { clientman->UpdatedBlockTip(pindexNew); }); +#endif // ENABLE_WALLET +} diff --git a/src/coinjoin/context.h b/src/coinjoin/context.h index be77e4f14546..a26d00e4fbe1 100644 --- a/src/coinjoin/context.h +++ b/src/coinjoin/context.h @@ -9,9 +9,12 @@ #include #endif +#include + #include class CActiveMasternodeManager; +class CBlockIndex; class CConnman; class CDeterministicMNManager; class ChainstateManager; @@ -28,17 +31,21 @@ class CCoinJoinClientQueueManager; class CoinJoinWalletManager; #endif // ENABLE_WALLET -struct CJContext { +struct CJContext final : public CValidationInterface { public: CJContext() = delete; CJContext(const CJContext&) = delete; CJContext(ChainstateManager& chainman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, CTxMemPool& mempool, const CActiveMasternodeManager* const mn_activeman, const CMasternodeSync& mn_sync, const llmq::CInstantSendManager& isman, bool relay_txes); - ~CJContext(); + virtual ~CJContext(); void Schedule(CConnman& connman, CScheduler& scheduler); +protected: + // CValidationInterface + void UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, bool fInitialDownload) override; + #ifdef ENABLE_WALLET private: const bool m_relay_txes; diff --git a/src/dsnotificationinterface.cpp b/src/dsnotificationinterface.cpp index bf71b87a3b9d..1a1faa969563 100644 --- a/src/dsnotificationinterface.cpp +++ b/src/dsnotificationinterface.cpp @@ -10,7 +10,6 @@ #include #include -#include #include #include #include @@ -21,26 +20,20 @@ #include #include -#ifdef ENABLE_WALLET -#include -#endif // ENABLE_WALLET - CDSNotificationInterface::CDSNotificationInterface(CConnman& connman, CDSTXManager& dstxman, CMasternodeSync& mn_sync, CGovernanceManager& govman, const ChainstateManager& chainman, const std::unique_ptr& dmnman, - const std::unique_ptr& llmq_ctx, - const std::unique_ptr& cj_ctx) : + const std::unique_ptr& llmq_ctx) : m_connman(connman), m_dstxman(dstxman), m_mn_sync(mn_sync), m_govman(govman), m_chainman(chainman), m_dmnman(dmnman), - m_llmq_ctx(llmq_ctx), - m_cj_ctx(cj_ctx) + m_llmq_ctx(llmq_ctx) { } @@ -80,16 +73,11 @@ void CDSNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, con return; m_dstxman.UpdatedBlockTip(pindexNew, *Assert(m_llmq_ctx)->clhandler, m_mn_sync); -#ifdef ENABLE_WALLET - Assert(m_cj_ctx)->walletman->ForEachCJClientMan( - [&pindexNew](std::unique_ptr& clientman) { clientman->UpdatedBlockTip(pindexNew); }); -#endif // ENABLE_WALLET m_llmq_ctx->isman->UpdatedBlockTip(pindexNew); 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); + m_llmq_ctx->qman->UpdatedBlockTip(pindexNew, m_connman, fInitialDownload); if (m_govman.IsValid()) { m_govman.UpdatedBlockTip(pindexNew); diff --git a/src/dsnotificationinterface.h b/src/dsnotificationinterface.h index 90cea2a37557..52cf0b2f62af 100644 --- a/src/dsnotificationinterface.h +++ b/src/dsnotificationinterface.h @@ -13,7 +13,6 @@ class CDeterministicMNManager; class CGovernanceManager; class ChainstateManager; class CMasternodeSync; -struct CJContext; struct LLMQContext; class CDSNotificationInterface : public CValidationInterface @@ -25,8 +24,7 @@ class CDSNotificationInterface : public CValidationInterface CGovernanceManager& govman, const ChainstateManager& chainman, const std::unique_ptr& dmnman, - const std::unique_ptr& llmq_ctx, - const std::unique_ptr& cj_ctx); + const std::unique_ptr& llmq_ctx); virtual ~CDSNotificationInterface() = default; // a small helper to initialize current block height in sub-modules on startup @@ -54,7 +52,6 @@ class CDSNotificationInterface : public CValidationInterface const ChainstateManager& m_chainman; const std::unique_ptr& m_dmnman; const std::unique_ptr& m_llmq_ctx; - const std::unique_ptr& m_cj_ctx; }; extern std::unique_ptr g_ds_notification_interface; diff --git a/src/init.cpp b/src/init.cpp index acc253159d4e..5ca253518c6e 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -325,6 +325,15 @@ void PrepareShutdown(NodeContext& node) g_active_notification_interface.reset(); } + if (node.cj_ctx) { + UnregisterValidationInterface(node.cj_ctx.get()); + } + + if (g_ds_notification_interface) { + UnregisterValidationInterface(g_ds_notification_interface.get()); + g_ds_notification_interface.reset(); + } + // After all scheduled tasks have been flushed, destroy pointers // and reset all to nullptr. node.active_ctx.reset(); @@ -376,11 +385,6 @@ void PrepareShutdown(NodeContext& node) } #endif - if (g_ds_notification_interface) { - UnregisterValidationInterface(g_ds_notification_interface.get()); - g_ds_notification_interface.reset(); - } - node.mn_activeman.reset(); node.chain_clients.clear(); @@ -2136,6 +2140,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) node.cj_ctx = std::make_unique(chainman, *node.dmnman, *node.mn_metaman, *node.mempool, node.mn_activeman.get(), *node.mn_sync, *node.llmq_ctx->isman, !ignores_incoming_txs); + RegisterValidationInterface(node.cj_ctx.get()); assert(!node.peerman); node.peerman = PeerManager::make(chainparams, *node.connman, *node.addrman, node.banman.get(), *node.dstxman, @@ -2145,7 +2150,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) RegisterValidationInterface(node.peerman.get()); g_ds_notification_interface = std::make_unique( - *node.connman, *node.dstxman, *node.mn_sync, *node.govman, chainman, node.dmnman, node.llmq_ctx, node.cj_ctx + *node.connman, *node.dstxman, *node.mn_sync, *node.govman, chainman, node.dmnman, node.llmq_ctx ); RegisterValidationInterface(g_ds_notification_interface.get()); From 9d06491fac1461bf9ab2d394b924bfd01b001a59 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Tue, 21 Oct 2025 17:22:37 +0530 Subject: [PATCH 04/11] refactor: allow `MessageProcessingResult` to submit DSQ messages --- src/coinjoin/client.cpp | 5 ++--- src/coinjoin/client.h | 5 ++--- src/coinjoin/server.cpp | 2 +- src/net_processing.cpp | 5 ++++- src/protocol.h | 7 +++++++ test/lint/lint-circular-dependencies.py | 2 -- 6 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/coinjoin/client.cpp b/src/coinjoin/client.cpp index c08a647cac7e..81771d1d95ac 100644 --- a/src/coinjoin/client.cpp +++ b/src/coinjoin/client.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -39,7 +38,7 @@ using wallet::CoinType; using wallet::CWallet; using wallet::ReserveDestination; -MessageProcessingResult CCoinJoinClientQueueManager::ProcessMessage(NodeId from, CConnman& connman, PeerManager& peerman, +MessageProcessingResult CCoinJoinClientQueueManager::ProcessMessage(NodeId from, CConnman& connman, std::string_view msg_type, CDataStream& vRecv) { if (msg_type != NetMsgType::DSQUEUE) { @@ -138,7 +137,7 @@ MessageProcessingResult CCoinJoinClientQueueManager::ProcessMessage(NodeId from, WITH_LOCK(cs_vecqueue, vecCoinJoinQueue.push_back(dsq)); } } // cs_ProcessDSQueue - peerman.RelayDSQ(dsq); + ret.m_dsq.push_back(dsq); return ret; } diff --git a/src/coinjoin/client.h b/src/coinjoin/client.h index cba6903030b3..b49bb7f87fbc 100644 --- a/src/coinjoin/client.h +++ b/src/coinjoin/client.h @@ -29,7 +29,6 @@ class CMasternodeSync; class CNode; class CoinJoinWalletManager; class CTxMemPool; -class PeerManager; class UniValue; @@ -251,8 +250,8 @@ class CCoinJoinClientQueueManager : public CCoinJoinBaseManager m_mn_sync(mn_sync), m_is_masternode{is_masternode} {}; - [[nodiscard]] MessageProcessingResult ProcessMessage(NodeId from, CConnman& connman, PeerManager& peerman, - std::string_view msg_type, CDataStream& vRecv) + [[nodiscard]] MessageProcessingResult ProcessMessage(NodeId from, CConnman& connman, std::string_view msg_type, + CDataStream& vRecv) EXCLUSIVE_LOCKS_REQUIRED(!cs_vecqueue, !cs_ProcessDSQueue); void DoMaintenance(); }; diff --git a/src/coinjoin/server.cpp b/src/coinjoin/server.cpp index 86c8e67bc5cb..6f7169af7486 100644 --- a/src/coinjoin/server.cpp +++ b/src/coinjoin/server.cpp @@ -188,7 +188,7 @@ MessageProcessingResult CCoinJoinServer::ProcessDSQUEUE(NodeId from, CDataStream TRY_LOCK(cs_vecqueue, lockRecv); if (!lockRecv) return ret; vecCoinJoinQueue.push_back(dsq); - m_peerman.RelayDSQ(dsq); + ret.m_dsq.push_back(dsq); } return ret; } diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 01d7b0e33e8e..cbd2a5f0067f 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -3520,6 +3520,9 @@ void PeerManagerImpl::PostProcessMessage(MessageProcessingResult&& result, NodeI for (const auto& inv : result.m_inventory) { RelayInv(inv); } + for (const auto& dsq : result.m_dsq) { + RelayDSQ(dsq); + } if (result.m_inv_filter) { const auto& [inv, filter] = result.m_inv_filter.value(); if (std::holds_alternative(filter)) { @@ -5367,7 +5370,7 @@ void PeerManagerImpl::ProcessMessage( //probably one the extensions #ifdef ENABLE_WALLET if (m_cj_ctx->queueman) { - PostProcessMessage(m_cj_ctx->queueman->ProcessMessage(pfrom.GetId(), m_connman, *this, msg_type, vRecv), pfrom.GetId()); + PostProcessMessage(m_cj_ctx->queueman->ProcessMessage(pfrom.GetId(), m_connman, msg_type, vRecv), pfrom.GetId()); } m_cj_ctx->walletman->ForEachCJClientMan([this, &pfrom, &msg_type, &vRecv](std::unique_ptr& clientman) { clientman->ProcessMessage(pfrom, m_chainman.ActiveChainstate(), m_connman, m_mempool, msg_type, vRecv); diff --git a/src/protocol.h b/src/protocol.h index 75456d161fb7..535a63e50432 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -13,11 +13,15 @@ #include #include +#include + #include #include #include #include +class CCoinJoinQueue; + /** Message header. * (4) message start. * (12) command. @@ -602,6 +606,9 @@ struct MessageProcessingResult //! @m_inventory will relay these inventories to connected peers std::vector m_inventory; + //! @m_dsq will relay DSQs to connected peers + std::vector m_dsq; + //! @m_inv_filter will relay this inventory if filter matches to connected peers if not nullopt std::optional>> m_inv_filter; diff --git a/test/lint/lint-circular-dependencies.py b/test/lint/lint-circular-dependencies.py index bcd5aa0ecc5b..59aab9053be9 100755 --- a/test/lint/lint-circular-dependencies.py +++ b/test/lint/lint-circular-dependencies.py @@ -30,8 +30,6 @@ "chainlock/chainlock -> validation -> chainlock/chainlock", "chainlock/chainlock -> validation -> evo/chainhelper -> chainlock/chainlock", "chainlock/signing -> instantsend/instantsend -> net_processing -> masternode/active/context -> chainlock/signing", - "coinjoin/client -> net_processing -> coinjoin/client", - "coinjoin/client -> net_processing -> coinjoin/context -> coinjoin/client", "coinjoin/server -> net_processing -> coinjoin/server", "coinjoin/server -> net_processing -> masternode/active/context -> coinjoin/server", "common/bloom -> evo/assetlocktx -> llmq/commitment -> evo/deterministicmns -> evo/simplifiedmns -> merkleblock -> common/bloom", From cd77127b626420bbee63dd73203865ea1d00d3b7 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Sun, 5 Oct 2025 14:57:24 +0000 Subject: [PATCH 05/11] refactor: separate `MisbehavingError` and `MessageProcessingResult` Placing them in `protocol.h` limits what headers we can include as circular dependencies can balloon unexpectedly, a separate header will reduce how often this happens. --- src/Makefile.am | 1 + src/coinjoin/client.h | 1 + src/coinjoin/server.h | 1 + src/evo/mnauth.h | 2 + src/governance/governance.h | 1 + src/llmq/blockprocessor.h | 7 ++- src/llmq/dkgsessionhandler.h | 2 + src/llmq/dkgsessionmgr.h | 1 + src/llmq/ehf_signals.h | 1 + src/llmq/quorums.h | 2 +- src/llmq/signing.h | 2 +- src/llmq/signing_shares.h | 4 +- src/msg_result.h | 79 +++++++++++++++++++++++++ src/net_processing.cpp | 56 +++++++++--------- src/net_processing.h | 2 + src/protocol.h | 64 -------------------- src/spork.h | 2 + test/lint/lint-circular-dependencies.py | 4 ++ 18 files changed, 133 insertions(+), 99 deletions(-) create mode 100644 src/msg_result.h diff --git a/src/Makefile.am b/src/Makefile.am index 639a7d9eff83..77445e48cc8b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -292,6 +292,7 @@ BITCOIN_CORE_H = \ memusage.h \ merkleblock.h \ messagesigner.h \ + msg_result.h \ net.h \ net_permissions.h \ net_processing.h \ diff --git a/src/coinjoin/client.h b/src/coinjoin/client.h index b49bb7f87fbc..0d4aab3986ce 100644 --- a/src/coinjoin/client.h +++ b/src/coinjoin/client.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include diff --git a/src/coinjoin/server.h b/src/coinjoin/server.h index 31099a6ac384..86e486ab3156 100644 --- a/src/coinjoin/server.h +++ b/src/coinjoin/server.h @@ -6,6 +6,7 @@ #define BITCOIN_COINJOIN_SERVER_H #include +#include #include #include diff --git a/src/evo/mnauth.h b/src/evo/mnauth.h index 9508cca595c8..0ab8acf4dc95 100644 --- a/src/evo/mnauth.h +++ b/src/evo/mnauth.h @@ -6,6 +6,8 @@ #define BITCOIN_EVO_MNAUTH_H #include +#include + #include #include #include diff --git a/src/governance/governance.h b/src/governance/governance.h index 43d3979bdcd4..8035985fdad6 100644 --- a/src/governance/governance.h +++ b/src/governance/governance.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include diff --git a/src/llmq/blockprocessor.h b/src/llmq/blockprocessor.h index de026946d7ab..fb58be574250 100644 --- a/src/llmq/blockprocessor.h +++ b/src/llmq/blockprocessor.h @@ -5,12 +5,13 @@ #ifndef BITCOIN_LLMQ_BLOCKPROCESSOR_H #define BITCOIN_LLMQ_BLOCKPROCESSOR_H -#include - #include -#include #include #include +#include +#include + +#include #include #include #include diff --git a/src/llmq/dkgsessionhandler.h b/src/llmq/dkgsessionhandler.h index ad241a5efc13..e40611a0238a 100644 --- a/src/llmq/dkgsessionhandler.h +++ b/src/llmq/dkgsessionhandler.h @@ -5,6 +5,8 @@ #ifndef BITCOIN_LLMQ_DKGSESSIONHANDLER_H #define BITCOIN_LLMQ_DKGSESSIONHANDLER_H +#include + #include // for NodeId #include diff --git a/src/llmq/dkgsessionmgr.h b/src/llmq/dkgsessionmgr.h index dba7948ec2f7..b7d0b5211f2e 100644 --- a/src/llmq/dkgsessionmgr.h +++ b/src/llmq/dkgsessionmgr.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include diff --git a/src/llmq/ehf_signals.h b/src/llmq/ehf_signals.h index 33283f6dbca8..cc9893061dca 100644 --- a/src/llmq/ehf_signals.h +++ b/src/llmq/ehf_signals.h @@ -6,6 +6,7 @@ #define BITCOIN_LLMQ_EHF_SIGNALS_H #include +#include #include diff --git a/src/llmq/quorums.h b/src/llmq/quorums.h index 1ba398103739..01a1e75dad75 100644 --- a/src/llmq/quorums.h +++ b/src/llmq/quorums.h @@ -11,9 +11,9 @@ #include #include #include +#include #include -#include #include #include #include diff --git a/src/llmq/signing.h b/src/llmq/signing.h index e49e76a14329..5438de2aaa1a 100644 --- a/src/llmq/signing.h +++ b/src/llmq/signing.h @@ -9,10 +9,10 @@ #include #include #include +#include #include #include -#include #include #include #include diff --git a/src/llmq/signing_shares.h b/src/llmq/signing_shares.h index 258a6f2417a6..0b0d2cacb3d8 100644 --- a/src/llmq/signing_shares.h +++ b/src/llmq/signing_shares.h @@ -5,10 +5,10 @@ #ifndef BITCOIN_LLMQ_SIGNING_SHARES_H #define BITCOIN_LLMQ_SIGNING_SHARES_H -#include - #include #include +#include +#include #include #include diff --git a/src/msg_result.h b/src/msg_result.h new file mode 100644 index 000000000000..01b14288ee27 --- /dev/null +++ b/src/msg_result.h @@ -0,0 +1,79 @@ +// Copyright (c) 2024-2025 The Dash Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_MSG_RESULT_H +#define BITCOIN_MSG_RESULT_H + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +struct MisbehavingError +{ + int score; + std::string message; + + MisbehavingError(int s) : score{s} {} + + // Constructor does a perfect forwarding reference + template + MisbehavingError(int s, T&& msg) : + score{s}, + message{std::forward(msg)} + {} +}; + +/** + * This struct is a helper to return values from handlers that are processing + * network messages but implemented outside of net_processing.cpp, + * for example llmq's messages. + * + * These handlers do not supposed to know anything about PeerManager to avoid + * circular dependencies. + * + * See `PeerManagerImpl::PostProcessMessage` to see how each type of return code + * is processed. + */ +struct MessageProcessingResult +{ + //! @m_error triggers Misbehaving error with score and optional message if not nullopt + std::optional m_error; + + //! @m_inventory will relay these inventories to connected peers + std::vector m_inventory; + + //! @m_dsq will relay DSQs to connected peers + std::vector m_dsq; + + //! @m_inv_filter will relay this inventory if filter matches to connected peers if not nullopt + std::optional>> m_inv_filter; + + //! @m_request_tx will ask connected peers to relay transaction if not nullopt + std::optional m_request_tx; + + //! @m_transactions will relay transactions to peers which is ready to accept it (some peers does not accept transactions) + std::vector m_transactions; + + //! @m_to_erase triggers EraseObjectRequest from PeerManager for this inventory if not nullopt + std::optional m_to_erase; + + MessageProcessingResult() = default; + MessageProcessingResult(CInv inv) : + m_inventory({inv}) + { + } + MessageProcessingResult(MisbehavingError error) : + m_error(error) + {} +}; + +#endif // BITCOIN_MSG_RESULT_H diff --git a/src/net_processing.cpp b/src/net_processing.cpp index cbd2a5f0067f..1a0352fc93df 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -14,11 +14,11 @@ #include #include #include -#include +#include #include -#include -#include #include +#include +#include #include #include #include @@ -31,42 +31,24 @@ #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 -#endif // ENABLE_WALLET +#include #include #include - -#include #include #include #include -#include +#include #include +#include #include #include #include @@ -77,9 +59,27 @@ #include #include #include - +#include +#include +#include +#include +#include #include +#ifdef ENABLE_WALLET +#include +#endif // ENABLE_WALLET + +#include +#include +#include +#include +#include +#include +#include +#include +#include + using node::ReadBlockFromDisk; using node::fImporting; using node::fPruneMode; diff --git a/src/net_processing.h b/src/net_processing.h index 27f9091845ff..de81c5f846f6 100644 --- a/src/net_processing.h +++ b/src/net_processing.h @@ -10,6 +10,8 @@ #include #include +#include + #include class CActiveMasternodeManager; diff --git a/src/protocol.h b/src/protocol.h index 535a63e50432..ed1b71705b80 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -7,21 +7,16 @@ #define BITCOIN_PROTOCOL_H #include -#include #include #include #include #include -#include - #include #include #include #include -class CCoinJoinQueue; - /** Message header. * (4) message start. * (12) command. @@ -572,63 +567,4 @@ class CInv uint256 hash; }; -struct MisbehavingError -{ - int score; - std::string message; - - MisbehavingError(int s) : score{s} {} - - // Constructor does a perfect forwarding reference - template - MisbehavingError(int s, T&& msg) : - score{s}, - message{std::forward(msg)} - {} -}; - -/** - * This struct is a helper to return values from handlers that are processing - * network messages but implemented outside of net_processing.cpp, - * for example llmq's messages. - * - * These handlers do not supposed to know anything about PeerManager to avoid - * circular dependencies. - * - * See `PeerManagerImpl::PostProcessMessage` to see how each type of return code - * is processed. - */ -struct MessageProcessingResult -{ - //! @m_error triggers Misbehaving error with score and optional message if not nullopt - std::optional m_error; - - //! @m_inventory will relay these inventories to connected peers - std::vector m_inventory; - - //! @m_dsq will relay DSQs to connected peers - std::vector m_dsq; - - //! @m_inv_filter will relay this inventory if filter matches to connected peers if not nullopt - std::optional>> m_inv_filter; - - //! @m_request_tx will ask connected peers to relay transaction if not nullopt - std::optional m_request_tx; - - //! @m_transactions will relay transactions to peers which is ready to accept it (some peers does not accept transactions) - std::vector m_transactions; - - //! @m_to_erase triggers EraseObjectRequest from PeerManager for this inventory if not nullopt - std::optional m_to_erase; - - MessageProcessingResult() = default; - MessageProcessingResult(MisbehavingError error) : - m_error(error) - {} - MessageProcessingResult(CInv inv) : - m_inventory({inv}) - { - } -}; - #endif // BITCOIN_PROTOCOL_H diff --git a/src/spork.h b/src/spork.h index 56ddd098d7ce..4ea43b435354 100644 --- a/src/spork.h +++ b/src/spork.h @@ -5,6 +5,8 @@ #ifndef BITCOIN_SPORK_H #define BITCOIN_SPORK_H +#include + #include #include #include diff --git a/test/lint/lint-circular-dependencies.py b/test/lint/lint-circular-dependencies.py index 59aab9053be9..3208860b5da5 100755 --- a/test/lint/lint-circular-dependencies.py +++ b/test/lint/lint-circular-dependencies.py @@ -27,9 +27,13 @@ "chainlock/chainlock -> instantsend/instantsend -> instantsend/signing -> chainlock/chainlock", "chainlock/chainlock -> instantsend/instantsend -> net_processing -> chainlock/chainlock", "chainlock/chainlock -> instantsend/instantsend -> net_processing -> masternode/active/context -> chainlock/chainlock", + "chainlock/chainlock -> llmq/quorums -> msg_result -> coinjoin/coinjoin -> chainlock/chainlock", "chainlock/chainlock -> validation -> chainlock/chainlock", "chainlock/chainlock -> validation -> evo/chainhelper -> chainlock/chainlock", "chainlock/signing -> instantsend/instantsend -> net_processing -> masternode/active/context -> chainlock/signing", + "coinjoin/client -> coinjoin/coinjoin -> instantsend/instantsend -> net_processing -> coinjoin/client", + "coinjoin/client -> coinjoin/coinjoin -> instantsend/instantsend -> net_processing -> coinjoin/context -> coinjoin/client", + "coinjoin/coinjoin -> instantsend/instantsend -> llmq/quorums -> msg_result -> coinjoin/coinjoin", "coinjoin/server -> net_processing -> coinjoin/server", "coinjoin/server -> net_processing -> masternode/active/context -> coinjoin/server", "common/bloom -> evo/assetlocktx -> llmq/commitment -> evo/deterministicmns -> evo/simplifiedmns -> merkleblock -> common/bloom", From d56879fe037fb29984aff433bf412da8bd8e3b8e Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Sun, 5 Oct 2025 14:47:05 +0000 Subject: [PATCH 06/11] refactor: restrict access to CoinJoin wallet managers --- src/coinjoin/context.cpp | 87 ++++++++++++++++++++++++++++++ src/coinjoin/context.h | 26 ++++++++- src/coinjoin/interfaces.cpp | 12 ++--- src/init.cpp | 2 +- src/masternode/utils.cpp | 28 ++++------ src/masternode/utils.h | 4 +- src/net_processing.cpp | 19 ++----- src/rpc/coinjoin.cpp | 6 ++- src/wallet/test/coinjoin_tests.cpp | 16 +++--- 9 files changed, 147 insertions(+), 53 deletions(-) diff --git a/src/coinjoin/context.cpp b/src/coinjoin/context.cpp index c1c84d3fe52b..3584d25bebda 100644 --- a/src/coinjoin/context.cpp +++ b/src/coinjoin/context.cpp @@ -4,8 +4,11 @@ #include +#include #include +#include + #ifdef ENABLE_WALLET #include #endif // ENABLE_WALLET @@ -47,3 +50,87 @@ void CJContext::UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* [&pindexNew](std::unique_ptr& clientman) { clientman->UpdatedBlockTip(pindexNew); }); #endif // ENABLE_WALLET } + +bool CJContext::hasQueue(const uint256& hash) const +{ +#ifdef ENABLE_WALLET + if (queueman) { + return queueman->HasQueue(hash); + } +#endif // ENABLE_WALLET + return false; +} + +CCoinJoinClientManager* CJContext::getClient(const std::string& name) +{ +#ifdef ENABLE_WALLET + return walletman->Get(name); +#else + return nullptr; +#endif // ENABLE_WALLET +} + +MessageProcessingResult CJContext::processMessage(CNode& pfrom, CChainState& chainstate, CConnman& connman, + CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv) +{ +#ifdef ENABLE_WALLET + walletman->ForEachCJClientMan([&](std::unique_ptr& clientman) { + clientman->ProcessMessage(pfrom, chainstate, connman, mempool, msg_type, vRecv); + }); + if (queueman) { + return queueman->ProcessMessage(pfrom.GetId(), connman, msg_type, vRecv); + } +#endif // ENABLE_WALLET + return {}; +} + +std::optional CJContext::getQueueFromHash(const uint256& hash) const +{ +#ifdef ENABLE_WALLET + if (queueman) { + return queueman->GetQueueFromHash(hash); + } +#endif // ENABLE_WALLET + return std::nullopt; +} + +std::optional CJContext::getQueueSize() const +{ +#ifdef ENABLE_WALLET + if (queueman) { + return queueman->GetQueueSize(); + } +#endif // ENABLE_WALLET + return std::nullopt; +} + +std::vector CJContext::getMixingMasternodes() const +{ + std::vector ret{}; +#ifdef ENABLE_WALLET + walletman->ForEachCJClientMan( + [&](const std::unique_ptr& clientman) { clientman->GetMixingMasternodesInfo(ret); }); +#endif // ENABLE_WALLET + return ret; +} + +void CJContext::addWallet(const std::shared_ptr& wallet) +{ +#ifdef ENABLE_WALLET + walletman->Add(wallet); +#endif // ENABLE_WALLET +} + +void CJContext::flushWallet(const std::string& name) +{ +#ifdef ENABLE_WALLET + walletman->Flush(name); +#endif // ENABLE_WALLET +} + +void CJContext::removeWallet(const std::string& name) +{ +#ifdef ENABLE_WALLET + walletman->Remove(name); +#endif // ENABLE_WALLET +} diff --git a/src/coinjoin/context.h b/src/coinjoin/context.h index a26d00e4fbe1..96edc00d505c 100644 --- a/src/coinjoin/context.h +++ b/src/coinjoin/context.h @@ -9,22 +9,34 @@ #include #endif +#include +#include + #include #include +#include +#include class CActiveMasternodeManager; class CBlockIndex; +class CChainState; +class CCoinJoinClientManager; +class CCoinJoinQueue; class CConnman; class CDeterministicMNManager; class ChainstateManager; class CMasternodeMetaMan; class CMasternodeSync; +class CNode; class CScheduler; class CTxMemPool; namespace llmq { class CInstantSendManager; -}; +} // namespace llmq +namespace wallet { +class CWallet; +} // namespace wallet #ifdef ENABLE_WALLET class CCoinJoinClientQueueManager; @@ -42,6 +54,17 @@ struct CJContext final : public CValidationInterface { void Schedule(CConnman& connman, CScheduler& scheduler); + bool hasQueue(const uint256& hash) const; + CCoinJoinClientManager* getClient(const std::string& name); + MessageProcessingResult processMessage(CNode& peer, CChainState& chainstate, CConnman& connman, CTxMemPool& mempool, + std::string_view msg_type, CDataStream& vRecv); + std::optional getQueueFromHash(const uint256& hash) const; + std::optional getQueueSize() const; + std::vector getMixingMasternodes() const; + void addWallet(const std::shared_ptr& wallet); + void removeWallet(const std::string& name); + void flushWallet(const std::string& name); + protected: // CValidationInterface void UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, bool fInitialDownload) override; @@ -50,7 +73,6 @@ struct CJContext final : public CValidationInterface { private: const bool m_relay_txes; -public: // The main object for accessing mixing const std::unique_ptr walletman; const std::unique_ptr queueman; diff --git a/src/coinjoin/interfaces.cpp b/src/coinjoin/interfaces.cpp index 98091b694c12..561df7a9083b 100644 --- a/src/coinjoin/interfaces.cpp +++ b/src/coinjoin/interfaces.cpp @@ -77,9 +77,9 @@ class CoinJoinClientImpl : public interfaces::CoinJoin::Client class CoinJoinLoaderImpl : public interfaces::CoinJoin::Loader { private: - CoinJoinWalletManager& walletman() + CJContext& manager() { - return *Assert(Assert(m_node.cj_ctx)->walletman); + return *Assert(m_node.cj_ctx); } interfaces::WalletLoader& wallet_loader() @@ -97,21 +97,21 @@ class CoinJoinLoaderImpl : public interfaces::CoinJoin::Loader void AddWallet(const std::shared_ptr& wallet) override { - walletman().Add(wallet); + manager().addWallet(wallet); g_wallet_init_interface.InitCoinJoinSettings(*this, wallet_loader()); } void RemoveWallet(const std::string& name) override { - walletman().Remove(name); + manager().removeWallet(name); g_wallet_init_interface.InitCoinJoinSettings(*this, wallet_loader()); } void FlushWallet(const std::string& name) override { - walletman().Flush(name); + manager().flushWallet(name); } std::unique_ptr GetClient(const std::string& name) override { - auto clientman = walletman().Get(name); + auto clientman = manager().getClient(name); return clientman ? std::make_unique(*clientman) : nullptr; } diff --git a/src/init.cpp b/src/init.cpp index 5ca253518c6e..ab1b92040c93 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -2262,7 +2262,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) node.scheduler->scheduleEvery(std::bind(&CNetFulfilledRequestManager::DoMaintenance, std::ref(*node.netfulfilledman)), std::chrono::minutes{1}); node.scheduler->scheduleEvery(std::bind(&CMasternodeSync::DoMaintenance, std::ref(*node.mn_sync), std::cref(*node.peerman), std::cref(*node.govman)), std::chrono::seconds{1}); - node.scheduler->scheduleEvery(std::bind(&CMasternodeUtils::DoMaintenance, std::ref(*node.connman), std::ref(*node.dmnman), std::ref(*node.mn_sync), std::ref(*node.cj_ctx)), std::chrono::minutes{1}); + node.scheduler->scheduleEvery(std::bind(&CMasternodeUtils::DoMaintenance, std::ref(*node.connman), std::ref(*node.dmnman), std::ref(*node.mn_sync), node.cj_ctx.get()), std::chrono::minutes{1}); node.scheduler->scheduleEvery(std::bind(&CDeterministicMNManager::DoMaintenance, std::ref(*node.dmnman)), std::chrono::seconds{10}); if (node.govman->IsValid()) { diff --git a/src/masternode/utils.cpp b/src/masternode/utils.cpp index 2988b3ffe801..d5961446a4d3 100644 --- a/src/masternode/utils.cpp +++ b/src/masternode/utils.cpp @@ -3,30 +3,25 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include -#include -#ifdef ENABLE_WALLET -#include -#endif -#include #include #include #include + #include +#include +#include -void CMasternodeUtils::DoMaintenance(CConnman& connman, CDeterministicMNManager& dmnman, - const CMasternodeSync& mn_sync, const CJContext& cj_ctx) +#ifdef ENABLE_WALLET +#include +#endif + +void CMasternodeUtils::DoMaintenance(CConnman& connman, CDeterministicMNManager& dmnman, const CMasternodeSync& mn_sync, + const CJContext* const cj_ctx) { if (!mn_sync.IsBlockchainSynced()) return; if (ShutdownRequested()) return; - std::vector vecDmns; // will be empty when no wallet -#ifdef ENABLE_WALLET - cj_ctx.walletman->ForEachCJClientMan([&vecDmns](const std::unique_ptr& clientman) { - clientman->GetMixingMasternodesInfo(vecDmns); - }); -#endif // ENABLE_WALLET - // Don't disconnect masternode connections when we have less then the desired amount of outbound nodes int nonMasternodeCount = 0; connman.ForEachNode(CConnman::AllNodes, [&](const CNode* pnode) { @@ -45,6 +40,7 @@ void CMasternodeUtils::DoMaintenance(CConnman& connman, CDeterministicMNManager& return; } + auto mixing_masternodes = cj_ctx ? cj_ctx->getMixingMasternodes() : std::vector{}; connman.ForEachNode(CConnman::AllNodes, [&](CNode* pnode) { if (pnode->m_masternode_probe_connection) { // we're not disconnecting masternode probes for at least PROBE_WAIT_INTERVAL seconds @@ -75,12 +71,10 @@ void CMasternodeUtils::DoMaintenance(CConnman& connman, CDeterministicMNManager& } } -#ifdef ENABLE_WALLET - bool fFound = ranges::any_of(vecDmns, [&pnode](const auto& dmn) { + bool fFound = ranges::any_of(mixing_masternodes, [&pnode](const auto& dmn) { return pnode->addr == dmn->pdmnState->netInfo->GetPrimary(); }); if (fFound) return; // do NOT disconnect mixing masternodes -#endif // ENABLE_WALLET if (fLogIPs) { LogPrint(BCLog::NET_NETCONN, "Closing Masternode connection: peer=%d, addr=%s\n", pnode->GetId(), pnode->addr.ToStringAddrPort()); diff --git a/src/masternode/utils.h b/src/masternode/utils.h index eb50990985c1..2350dc0160de 100644 --- a/src/masternode/utils.h +++ b/src/masternode/utils.h @@ -13,8 +13,8 @@ struct CJContext; class CMasternodeUtils { public: - static void DoMaintenance(CConnman &connman, CDeterministicMNManager& dmnman, - const CMasternodeSync& mn_sync, const CJContext& cj_ctx); + static void DoMaintenance(CConnman& connman, CDeterministicMNManager& dmnman, const CMasternodeSync& mn_sync, + const CJContext* const cj_ctx); }; #endif // BITCOIN_MASTERNODE_UTILS_H diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 1a0352fc93df..9999afe898ab 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -2278,11 +2278,7 @@ bool PeerManagerImpl::AlreadyHave(const CInv& inv) case MSG_ISDLOCK: return m_llmq_ctx->isman->AlreadyHave(inv); case MSG_DSQ: - return -#ifdef ENABLE_WALLET - (m_cj_ctx->queueman && m_cj_ctx->queueman->HasQueue(inv.hash)) || -#endif // ENABLE_WALLET - (m_active_ctx && m_active_ctx->cj_server->HasQueue(inv.hash)); + return (m_cj_ctx && m_cj_ctx->hasQueue(inv.hash)) || (m_active_ctx && m_active_ctx->cj_server->HasQueue(inv.hash)); case MSG_PLATFORM_BAN: return m_mn_metaman.AlreadyHavePlatformBan(inv.hash); } @@ -2888,11 +2884,9 @@ void PeerManagerImpl::ProcessGetData(CNode& pfrom, Peer& peer, const std::atomic } if (!push && inv.type == MSG_DSQ) { auto opt_dsq = m_active_ctx ? m_active_ctx->cj_server->GetQueueFromHash(inv.hash) : std::nullopt; -#ifdef ENABLE_WALLET - if (m_cj_ctx->queueman && !opt_dsq.has_value()) { - opt_dsq = m_cj_ctx->queueman->GetQueueFromHash(inv.hash); + if (m_cj_ctx && !opt_dsq.has_value()) { + opt_dsq = m_cj_ctx->getQueueFromHash(inv.hash); } -#endif if (opt_dsq.has_value()) { m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::DSQUEUE, *opt_dsq)); push = true; @@ -5369,12 +5363,9 @@ void PeerManagerImpl::ProcessMessage( { //probably one the extensions #ifdef ENABLE_WALLET - if (m_cj_ctx->queueman) { - PostProcessMessage(m_cj_ctx->queueman->ProcessMessage(pfrom.GetId(), m_connman, msg_type, vRecv), pfrom.GetId()); + if (m_cj_ctx) { + PostProcessMessage(m_cj_ctx->processMessage(pfrom, m_chainman.ActiveChainstate(), m_connman, m_mempool, msg_type, vRecv), pfrom.GetId()); } - m_cj_ctx->walletman->ForEachCJClientMan([this, &pfrom, &msg_type, &vRecv](std::unique_ptr& clientman) { - clientman->ProcessMessage(pfrom, m_chainman.ActiveChainstate(), m_connman, m_mempool, msg_type, vRecv); - }); #endif // ENABLE_WALLET if (m_active_ctx) { PostProcessMessage(m_active_ctx->cj_server->ProcessMessage(pfrom, msg_type, vRecv), pfrom.GetId()); diff --git a/src/rpc/coinjoin.cpp b/src/rpc/coinjoin.cpp index ef578d726101..225936dae6db 100644 --- a/src/rpc/coinjoin.cpp +++ b/src/rpc/coinjoin.cpp @@ -473,8 +473,10 @@ static RPCHelpMan getcoinjoininfo() #ifdef ENABLE_WALLET CCoinJoinClientOptions::GetJsonInfo(obj); - if (node.cj_ctx->queueman) { - obj.pushKV("queue_size", node.cj_ctx->queueman->GetQueueSize()); + if (node.cj_ctx) { + if (auto queue_size = node.cj_ctx->getQueueSize()) { + obj.pushKV("queue_size", queue_size.value()); + } } const std::shared_ptr wallet = GetWalletForJSONRPCRequest(request); diff --git a/src/wallet/test/coinjoin_tests.cpp b/src/wallet/test/coinjoin_tests.cpp index 7c3cc037de43..688f72efceb0 100644 --- a/src/wallet/test/coinjoin_tests.cpp +++ b/src/wallet/test/coinjoin_tests.cpp @@ -221,17 +221,15 @@ class CTransactionBuilderTestSetup : public TestChain100Setup BOOST_FIXTURE_TEST_CASE(coinjoin_manager_start_stop_tests, CTransactionBuilderTestSetup) { - CCoinJoinClientManager* cj_man = m_node.cj_ctx->walletman->Get(""); - BOOST_REQUIRE(cj_man != nullptr); - BOOST_CHECK_EQUAL(cj_man->IsMixing(), false); - BOOST_CHECK_EQUAL(cj_man->StartMixing(), true); - BOOST_CHECK_EQUAL(cj_man->IsMixing(), true); - BOOST_CHECK_EQUAL(cj_man->StartMixing(), false); - cj_man->StopMixing(); - BOOST_CHECK_EQUAL(cj_man->IsMixing(), false); + auto& cj_man = *Assert(m_node.cj_ctx->getClient("")); + BOOST_CHECK_EQUAL(cj_man.IsMixing(), false); + BOOST_CHECK_EQUAL(cj_man.StartMixing(), true); + BOOST_CHECK_EQUAL(cj_man.IsMixing(), true); + BOOST_CHECK_EQUAL(cj_man.StartMixing(), false); + cj_man.StopMixing(); + BOOST_CHECK_EQUAL(cj_man.IsMixing(), false); } - BOOST_FIXTURE_TEST_CASE(CTransactionBuilderTest, CTransactionBuilderTestSetup) { // NOTE: Mock wallet version is FEATURE_BASE which means that it uses uncompressed pubkeys From 80c201b58e4ed0785cca4c6c82cc528d43bdfa6a Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Tue, 30 Sep 2025 10:54:40 +0000 Subject: [PATCH 07/11] refactor: make `CJContext` an interface, move implementation to source This should prevent ENABLE_WALLET from spilling out to files that include the header. --- src/coinjoin/context.cpp | 115 +++++++++++++++--------- src/coinjoin/context.h | 62 +++++-------- src/init.cpp | 12 ++- src/masternode/utils.h | 2 +- src/net_processing.cpp | 6 -- src/net_processing.h | 14 +-- src/node/context.h | 2 +- src/test/util/setup_common.cpp | 6 +- test/lint/lint-circular-dependencies.py | 1 - 9 files changed, 116 insertions(+), 104 deletions(-) diff --git a/src/coinjoin/context.cpp b/src/coinjoin/context.cpp index 3584d25bebda..09417ba561c5 100644 --- a/src/coinjoin/context.cpp +++ b/src/coinjoin/context.cpp @@ -2,10 +2,15 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#if defined(HAVE_CONFIG_H) +#include +#endif + #include #include #include +#include #include @@ -13,124 +18,148 @@ #include #endif // ENABLE_WALLET -CJContext::CJContext(ChainstateManager& chainman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, - CTxMemPool& mempool, const CActiveMasternodeManager* const mn_activeman, - const CMasternodeSync& mn_sync, const llmq::CInstantSendManager& isman, bool relay_txes) +#include + #ifdef ENABLE_WALLET - : +class CJContextImpl final : public CJContext +{ +public: + CJContextImpl(ChainstateManager& chainman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, + CTxMemPool& mempool, const CActiveMasternodeManager* const mn_activeman, + const CMasternodeSync& mn_sync, const llmq::CInstantSendManager& isman, bool relay_txes); + virtual ~CJContextImpl() = default; + +public: + void Schedule(CConnman& connman, CScheduler& scheduler) override; + +public: + bool hasQueue(const uint256& hash) const override; + CCoinJoinClientManager* getClient(const std::string& name) override; + MessageProcessingResult processMessage(CNode& peer, CChainState& chainstate, CConnman& connman, CTxMemPool& mempool, + std::string_view msg_type, CDataStream& vRecv) override; + std::optional getQueueFromHash(const uint256& hash) const override; + std::optional getQueueSize() const override; + std::vector getMixingMasternodes() const override; + void addWallet(const std::shared_ptr& wallet) override; + void removeWallet(const std::string& name) override; + void flushWallet(const std::string& name) override; + +protected: + // CValidationInterface + void UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, bool fInitialDownload) override; + +private: + const bool m_relay_txes; + + const std::unique_ptr walletman; + const std::unique_ptr queueman; +}; + +CJContextImpl::CJContextImpl(ChainstateManager& chainman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, + CTxMemPool& mempool, const CActiveMasternodeManager* const mn_activeman, + const CMasternodeSync& mn_sync, const llmq::CInstantSendManager& isman, bool relay_txes) : m_relay_txes{relay_txes}, walletman{std::make_unique(chainman, dmnman, mn_metaman, mempool, mn_sync, isman, queueman, /*is_masternode=*/mn_activeman != nullptr)}, queueman{m_relay_txes ? std::make_unique(*walletman, dmnman, mn_metaman, mn_sync, /*is_masternode=*/mn_activeman != nullptr) : nullptr} -#endif // ENABLE_WALLET -{} - -CJContext::~CJContext() = default; +{ +} -void CJContext::Schedule(CConnman& connman, CScheduler& scheduler) +void CJContextImpl::Schedule(CConnman& connman, CScheduler& scheduler) { -#ifdef ENABLE_WALLET if (!m_relay_txes) return; scheduler.scheduleEvery(std::bind(&CCoinJoinClientQueueManager::DoMaintenance, std::ref(*queueman)), std::chrono::seconds{1}); scheduler.scheduleEvery(std::bind(&CoinJoinWalletManager::DoMaintenance, std::ref(*walletman), std::ref(connman)), std::chrono::seconds{1}); -#endif // ENABLE_WALLET } -void CJContext::UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, bool fInitialDownload) +void CJContextImpl::UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, bool fInitialDownload) { -#ifdef ENABLE_WALLET if (fInitialDownload || pindexNew == pindexFork) // In IBD or blocks were disconnected without any new ones return; walletman->ForEachCJClientMan( [&pindexNew](std::unique_ptr& clientman) { clientman->UpdatedBlockTip(pindexNew); }); -#endif // ENABLE_WALLET } -bool CJContext::hasQueue(const uint256& hash) const +bool CJContextImpl::hasQueue(const uint256& hash) const { -#ifdef ENABLE_WALLET if (queueman) { return queueman->HasQueue(hash); } -#endif // ENABLE_WALLET return false; } -CCoinJoinClientManager* CJContext::getClient(const std::string& name) +CCoinJoinClientManager* CJContextImpl::getClient(const std::string& name) { -#ifdef ENABLE_WALLET return walletman->Get(name); -#else - return nullptr; -#endif // ENABLE_WALLET } -MessageProcessingResult CJContext::processMessage(CNode& pfrom, CChainState& chainstate, CConnman& connman, - CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv) +MessageProcessingResult CJContextImpl::processMessage(CNode& pfrom, CChainState& chainstate, CConnman& connman, + CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv) { -#ifdef ENABLE_WALLET walletman->ForEachCJClientMan([&](std::unique_ptr& clientman) { clientman->ProcessMessage(pfrom, chainstate, connman, mempool, msg_type, vRecv); }); if (queueman) { return queueman->ProcessMessage(pfrom.GetId(), connman, msg_type, vRecv); } -#endif // ENABLE_WALLET return {}; } -std::optional CJContext::getQueueFromHash(const uint256& hash) const +std::optional CJContextImpl::getQueueFromHash(const uint256& hash) const { -#ifdef ENABLE_WALLET if (queueman) { return queueman->GetQueueFromHash(hash); } -#endif // ENABLE_WALLET return std::nullopt; } -std::optional CJContext::getQueueSize() const +std::optional CJContextImpl::getQueueSize() const { -#ifdef ENABLE_WALLET if (queueman) { return queueman->GetQueueSize(); } -#endif // ENABLE_WALLET return std::nullopt; } -std::vector CJContext::getMixingMasternodes() const +std::vector CJContextImpl::getMixingMasternodes() const { std::vector ret{}; -#ifdef ENABLE_WALLET walletman->ForEachCJClientMan( [&](const std::unique_ptr& clientman) { clientman->GetMixingMasternodesInfo(ret); }); -#endif // ENABLE_WALLET return ret; } -void CJContext::addWallet(const std::shared_ptr& wallet) +void CJContextImpl::addWallet(const std::shared_ptr& wallet) { -#ifdef ENABLE_WALLET walletman->Add(wallet); -#endif // ENABLE_WALLET } -void CJContext::flushWallet(const std::string& name) +void CJContextImpl::flushWallet(const std::string& name) { -#ifdef ENABLE_WALLET walletman->Flush(name); -#endif // ENABLE_WALLET } -void CJContext::removeWallet(const std::string& name) +void CJContextImpl::removeWallet(const std::string& name) { -#ifdef ENABLE_WALLET walletman->Remove(name); +} +#endif // ENABLE_WALLET + +std::unique_ptr CJContext::make(ChainstateManager& chainman, CDeterministicMNManager& dmnman, + CMasternodeMetaMan& mn_metaman, CTxMemPool& mempool, + const CActiveMasternodeManager* const mn_activeman, + const CMasternodeSync& mn_sync, const llmq::CInstantSendManager& isman, + bool relay_txes) +{ +#ifdef ENABLE_WALLET + return std::make_unique(chainman, dmnman, mn_metaman, mempool, mn_activeman, mn_sync, isman, relay_txes); +#else + // Cannot be constructed if wallet support isn't built + return nullptr; #endif // ENABLE_WALLET } diff --git a/src/coinjoin/context.h b/src/coinjoin/context.h index 96edc00d505c..be843d6ab9bb 100644 --- a/src/coinjoin/context.h +++ b/src/coinjoin/context.h @@ -5,16 +5,11 @@ #ifndef BITCOIN_COINJOIN_CONTEXT_H #define BITCOIN_COINJOIN_CONTEXT_H -#if defined(HAVE_CONFIG_H) -#include -#endif - #include #include #include -#include #include #include @@ -24,6 +19,7 @@ class CChainState; class CCoinJoinClientManager; class CCoinJoinQueue; class CConnman; +class CDataStream; class CDeterministicMNManager; class ChainstateManager; class CMasternodeMetaMan; @@ -38,45 +34,35 @@ namespace wallet { class CWallet; } // namespace wallet -#ifdef ENABLE_WALLET -class CCoinJoinClientQueueManager; -class CoinJoinWalletManager; -#endif // ENABLE_WALLET - -struct CJContext final : public CValidationInterface { +class CJContext : public CValidationInterface +{ public: - CJContext() = delete; - CJContext(const CJContext&) = delete; - CJContext(ChainstateManager& chainman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, - CTxMemPool& mempool, const CActiveMasternodeManager* const mn_activeman, const CMasternodeSync& mn_sync, - const llmq::CInstantSendManager& isman, bool relay_txes); - virtual ~CJContext(); + static std::unique_ptr make(ChainstateManager& chainman, CDeterministicMNManager& dmnman, + CMasternodeMetaMan& mn_metaman, CTxMemPool& mempool, + const CActiveMasternodeManager* const mn_activeman, + const CMasternodeSync& mn_sync, const llmq::CInstantSendManager& isman, + bool relay_txes); + virtual ~CJContext() = default; - void Schedule(CConnman& connman, CScheduler& scheduler); +public: + virtual void Schedule(CConnman& connman, CScheduler& scheduler) = 0; - bool hasQueue(const uint256& hash) const; - CCoinJoinClientManager* getClient(const std::string& name); - MessageProcessingResult processMessage(CNode& peer, CChainState& chainstate, CConnman& connman, CTxMemPool& mempool, - std::string_view msg_type, CDataStream& vRecv); - std::optional getQueueFromHash(const uint256& hash) const; - std::optional getQueueSize() const; - std::vector getMixingMasternodes() const; - void addWallet(const std::shared_ptr& wallet); - void removeWallet(const std::string& name); - void flushWallet(const std::string& name); +public: + virtual bool hasQueue(const uint256& hash) const = 0; + virtual CCoinJoinClientManager* getClient(const std::string& name) = 0; + virtual MessageProcessingResult processMessage(CNode& peer, CChainState& chainstate, CConnman& connman, + CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv) = 0; + virtual std::optional getQueueFromHash(const uint256& hash) const = 0; + virtual std::optional getQueueSize() const = 0; + virtual std::vector getMixingMasternodes() const = 0; + virtual void addWallet(const std::shared_ptr& wallet) = 0; + virtual void removeWallet(const std::string& name) = 0; + virtual void flushWallet(const std::string& name) = 0; protected: // CValidationInterface - void UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, bool fInitialDownload) override; - -#ifdef ENABLE_WALLET -private: - const bool m_relay_txes; - - // The main object for accessing mixing - const std::unique_ptr walletman; - const std::unique_ptr queueman; -#endif // ENABLE_WALLET + virtual void UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, + bool fInitialDownload) override = 0; }; #endif // BITCOIN_COINJOIN_CONTEXT_H diff --git a/src/init.cpp b/src/init.cpp index ab1b92040c93..621b3d07432e 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -2136,11 +2136,15 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) ChainstateManager& chainman = *Assert(node.chainman); + assert(!node.dstxman); node.dstxman = std::make_unique(); - node.cj_ctx = std::make_unique(chainman, *node.dmnman, *node.mn_metaman, *node.mempool, - node.mn_activeman.get(), *node.mn_sync, *node.llmq_ctx->isman, - !ignores_incoming_txs); - RegisterValidationInterface(node.cj_ctx.get()); + + assert(!node.cj_ctx); + node.cj_ctx = CJContext::make(chainman, *node.dmnman, *node.mn_metaman, *node.mempool, node.mn_activeman.get(), + *node.mn_sync, *node.llmq_ctx->isman, !ignores_incoming_txs); + if (node.cj_ctx) { + RegisterValidationInterface(node.cj_ctx.get()); + } assert(!node.peerman); node.peerman = PeerManager::make(chainparams, *node.connman, *node.addrman, node.banman.get(), *node.dstxman, diff --git a/src/masternode/utils.h b/src/masternode/utils.h index 2350dc0160de..0c9b2adfec18 100644 --- a/src/masternode/utils.h +++ b/src/masternode/utils.h @@ -8,7 +8,7 @@ class CConnman; class CDeterministicMNManager; class CMasternodeSync; -struct CJContext; +class CJContext; class CMasternodeUtils { diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 9999afe898ab..5bab7573f9bd 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -66,10 +66,6 @@ #include #include -#ifdef ENABLE_WALLET -#include -#endif // ENABLE_WALLET - #include #include #include @@ -5362,11 +5358,9 @@ void PeerManagerImpl::ProcessMessage( if (found) { //probably one the extensions -#ifdef ENABLE_WALLET if (m_cj_ctx) { PostProcessMessage(m_cj_ctx->processMessage(pfrom, m_chainman.ActiveChainstate(), m_connman, m_mempool, msg_type, vRecv), pfrom.GetId()); } -#endif // ENABLE_WALLET if (m_active_ctx) { PostProcessMessage(m_active_ctx->cj_server->ProcessMessage(pfrom, msg_type, vRecv), pfrom.GetId()); } diff --git a/src/net_processing.h b/src/net_processing.h index de81c5f846f6..0a1e3b2b37d4 100644 --- a/src/net_processing.h +++ b/src/net_processing.h @@ -14,22 +14,22 @@ #include -class CActiveMasternodeManager; class AddrMan; -class CTxMemPool; +class CActiveMasternodeManager; class CCoinJoinQueue; +class CCoinJoinServer; class CDeterministicMNManager; class CDSTXManager; -class CMasternodeMetaMan; -class CMasternodeSync; -class ChainstateManager; -class CCoinJoinServer; class CGovernanceManager; +class ChainstateManager; class CInv; +class CJContext; +class CMasternodeMetaMan; +class CMasternodeSync; class CSporkManager; class CTransaction; +class CTxMemPool; struct ActiveContext; -struct CJContext; struct LLMQContext; /** Default for -maxorphantxsize, maximum size in megabytes the orphan map can grow before entries are removed */ diff --git a/src/node/context.h b/src/node/context.h index 439fd3a8aab8..8429e10daf57 100644 --- a/src/node/context.h +++ b/src/node/context.h @@ -23,6 +23,7 @@ class CChainstateHelper; class ChainstateManager; class CEvoDB; class CGovernanceManager; +class CJContext; class CMasternodeMetaMan; class CMasternodeSync; class CNetFulfilledRequestManager; @@ -33,7 +34,6 @@ class CMNHFManager; class NetGroupManager; class PeerManager; struct ActiveContext; -struct CJContext; struct LLMQContext; namespace interfaces { diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 6881691e9e6e..db7298e92fa9 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -354,9 +354,9 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vectorInit(options); } - m_node.cj_ctx = std::make_unique(*m_node.chainman, *m_node.dmnman, *m_node.mn_metaman, *m_node.mempool, - /*mn_activeman=*/nullptr, *m_node.mn_sync, *m_node.llmq_ctx->isman, - /*relay_txes=*/true); + m_node.cj_ctx = CJContext::make(*m_node.chainman, *m_node.dmnman, *m_node.mn_metaman, *m_node.mempool, + /*mn_activeman=*/nullptr, *m_node.mn_sync, *m_node.llmq_ctx->isman, + /*relay_txes=*/true); #ifdef ENABLE_WALLET // WalletInit::Construct()-like logic needed for wallet tests that run on diff --git a/test/lint/lint-circular-dependencies.py b/test/lint/lint-circular-dependencies.py index 3208860b5da5..e05e64a50d7d 100755 --- a/test/lint/lint-circular-dependencies.py +++ b/test/lint/lint-circular-dependencies.py @@ -31,7 +31,6 @@ "chainlock/chainlock -> validation -> chainlock/chainlock", "chainlock/chainlock -> validation -> evo/chainhelper -> chainlock/chainlock", "chainlock/signing -> instantsend/instantsend -> net_processing -> masternode/active/context -> chainlock/signing", - "coinjoin/client -> coinjoin/coinjoin -> instantsend/instantsend -> net_processing -> coinjoin/client", "coinjoin/client -> coinjoin/coinjoin -> instantsend/instantsend -> net_processing -> coinjoin/context -> coinjoin/client", "coinjoin/coinjoin -> instantsend/instantsend -> llmq/quorums -> msg_result -> coinjoin/coinjoin", "coinjoin/server -> net_processing -> coinjoin/server", From 1a35a65cf58b5e24e60185f3fdb603ef2b227793 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Tue, 30 Sep 2025 11:11:34 +0000 Subject: [PATCH 08/11] refactor: drop `mn_activeman` from `CJContext` Now that we no longer assume that cj_ctx is always initialized, we can skip the whole process if we are in masternode mode. --- src/coinjoin/context.cpp | 17 +++++------ src/coinjoin/context.h | 2 -- src/init.cpp | 8 +++-- src/net_processing.cpp | 9 +++--- src/net_processing.h | 4 +-- src/test/denialofservice_tests.cpp | 10 +++---- src/test/net_peer_connection_tests.cpp | 2 +- src/test/util/setup_common.cpp | 41 +++++++++++++------------- 8 files changed, 46 insertions(+), 47 deletions(-) diff --git a/src/coinjoin/context.cpp b/src/coinjoin/context.cpp index 09417ba561c5..8405fd8a2eb5 100644 --- a/src/coinjoin/context.cpp +++ b/src/coinjoin/context.cpp @@ -25,8 +25,8 @@ class CJContextImpl final : public CJContext { public: CJContextImpl(ChainstateManager& chainman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, - CTxMemPool& mempool, const CActiveMasternodeManager* const mn_activeman, - const CMasternodeSync& mn_sync, const llmq::CInstantSendManager& isman, bool relay_txes); + CTxMemPool& mempool, const CMasternodeSync& mn_sync, const llmq::CInstantSendManager& isman, + bool relay_txes); virtual ~CJContextImpl() = default; public: @@ -55,14 +55,14 @@ class CJContextImpl final : public CJContext const std::unique_ptr queueman; }; -CJContextImpl::CJContextImpl(ChainstateManager& chainman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, - CTxMemPool& mempool, const CActiveMasternodeManager* const mn_activeman, - const CMasternodeSync& mn_sync, const llmq::CInstantSendManager& isman, bool relay_txes) : +CJContextImpl::CJContextImpl(ChainstateManager& chainman, CDeterministicMNManager& dmnman, + CMasternodeMetaMan& mn_metaman, CTxMemPool& mempool, const CMasternodeSync& mn_sync, + const llmq::CInstantSendManager& isman, bool relay_txes) : m_relay_txes{relay_txes}, walletman{std::make_unique(chainman, dmnman, mn_metaman, mempool, mn_sync, isman, queueman, - /*is_masternode=*/mn_activeman != nullptr)}, + /*is_masternode=*/false)}, queueman{m_relay_txes ? std::make_unique(*walletman, dmnman, mn_metaman, mn_sync, - /*is_masternode=*/mn_activeman != nullptr) + /*is_masternode=*/false) : nullptr} { } @@ -152,12 +152,11 @@ void CJContextImpl::removeWallet(const std::string& name) std::unique_ptr CJContext::make(ChainstateManager& chainman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, CTxMemPool& mempool, - const CActiveMasternodeManager* const mn_activeman, const CMasternodeSync& mn_sync, const llmq::CInstantSendManager& isman, bool relay_txes) { #ifdef ENABLE_WALLET - return std::make_unique(chainman, dmnman, mn_metaman, mempool, mn_activeman, mn_sync, isman, relay_txes); + return std::make_unique(chainman, dmnman, mn_metaman, mempool, mn_sync, isman, relay_txes); #else // Cannot be constructed if wallet support isn't built return nullptr; diff --git a/src/coinjoin/context.h b/src/coinjoin/context.h index be843d6ab9bb..9e9b5de11846 100644 --- a/src/coinjoin/context.h +++ b/src/coinjoin/context.h @@ -13,7 +13,6 @@ #include #include -class CActiveMasternodeManager; class CBlockIndex; class CChainState; class CCoinJoinClientManager; @@ -39,7 +38,6 @@ class CJContext : public CValidationInterface public: static std::unique_ptr make(ChainstateManager& chainman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, CTxMemPool& mempool, - const CActiveMasternodeManager* const mn_activeman, const CMasternodeSync& mn_sync, const llmq::CInstantSendManager& isman, bool relay_txes); virtual ~CJContext() = default; diff --git a/src/init.cpp b/src/init.cpp index 621b3d07432e..27eaf71fae31 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -2140,8 +2140,10 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) node.dstxman = std::make_unique(); assert(!node.cj_ctx); - node.cj_ctx = CJContext::make(chainman, *node.dmnman, *node.mn_metaman, *node.mempool, node.mn_activeman.get(), - *node.mn_sync, *node.llmq_ctx->isman, !ignores_incoming_txs); + if (!node.mn_activeman) { + node.cj_ctx = CJContext::make(chainman, *node.dmnman, *node.mn_metaman, *node.mempool, *node.mn_sync, + *node.llmq_ctx->isman, !ignores_incoming_txs); + } if (node.cj_ctx) { RegisterValidationInterface(node.cj_ctx.get()); } @@ -2150,7 +2152,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) node.peerman = PeerManager::make(chainparams, *node.connman, *node.addrman, node.banman.get(), *node.dstxman, chainman, *node.mempool, *node.mn_metaman, *node.mn_sync, *node.govman, *node.sporkman, node.mn_activeman.get(), node.dmnman, - node.active_ctx, node.cj_ctx, node.llmq_ctx, ignores_incoming_txs); + node.active_ctx, node.cj_ctx.get(), node.llmq_ctx, ignores_incoming_txs); RegisterValidationInterface(node.peerman.get()); g_ds_notification_interface = std::make_unique( diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 5bab7573f9bd..962b64db38ff 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -592,7 +592,7 @@ class PeerManagerImpl final : public PeerManager CMasternodeMetaMan& mn_metaman, CMasternodeSync& mn_sync, CGovernanceManager& govman, CSporkManager& sporkman, const CActiveMasternodeManager* const mn_activeman, const std::unique_ptr& dmnman, - const std::unique_ptr& active_ctx, const std::unique_ptr& cj_ctx, + const std::unique_ptr& active_ctx, CJContext* const cj_ctx, const std::unique_ptr& llmq_ctx, bool ignore_incoming_txs); /** Overridden from CValidationInterface. */ @@ -788,7 +788,8 @@ class PeerManagerImpl final : public PeerManager std::unique_ptr m_txreconciliation; const std::unique_ptr& m_dmnman; const std::unique_ptr& m_active_ctx; - const std::unique_ptr& m_cj_ctx; + /** Pointer to this node's CJContext. May be nullptr - check existence before dereferencing. */ + CJContext* const m_cj_ctx; const std::unique_ptr& m_llmq_ctx; CMasternodeMetaMan& m_mn_metaman; CMasternodeSync& m_mn_sync; @@ -1962,7 +1963,7 @@ std::unique_ptr PeerManager::make(const CChainParams& chainparams, const CActiveMasternodeManager* const mn_activeman, const std::unique_ptr& dmnman, const std::unique_ptr& active_ctx, - const std::unique_ptr& cj_ctx, + CJContext* const cj_ctx, const std::unique_ptr& llmq_ctx, bool ignore_incoming_txs) { return std::make_unique(chainparams, connman, addrman, banman, dstxman, chainman, pool, mn_metaman, mn_sync, govman, sporkman, mn_activeman, dmnman, active_ctx, cj_ctx, llmq_ctx, ignore_incoming_txs); @@ -1974,7 +1975,7 @@ PeerManagerImpl::PeerManagerImpl(const CChainParams& chainparams, CConnman& conn CSporkManager& sporkman, const CActiveMasternodeManager* const mn_activeman, const std::unique_ptr& dmnman, const std::unique_ptr& active_ctx, - const std::unique_ptr& cj_ctx, + CJContext* const cj_ctx, const std::unique_ptr& llmq_ctx, bool ignore_incoming_txs) : m_chainparams(chainparams), m_connman(connman), diff --git a/src/net_processing.h b/src/net_processing.h index 0a1e3b2b37d4..f957a14011cb 100644 --- a/src/net_processing.h +++ b/src/net_processing.h @@ -65,8 +65,8 @@ class PeerManager : public CValidationInterface, public NetEventsInterface const CActiveMasternodeManager* const mn_activeman, const std::unique_ptr& dmnman, const std::unique_ptr& active_ctx, - const std::unique_ptr& cj_ctx, - const std::unique_ptr& llmq_ctx, bool ignore_incoming_txs); + CJContext* const cj_ctx, const std::unique_ptr& llmq_ctx, + bool ignore_incoming_txs); virtual ~PeerManager() { } /** diff --git a/src/test/denialofservice_tests.cpp b/src/test/denialofservice_tests.cpp index d8e573c61c63..6a3c993e644f 100644 --- a/src/test/denialofservice_tests.cpp +++ b/src/test/denialofservice_tests.cpp @@ -151,7 +151,7 @@ BOOST_AUTO_TEST_CASE(stale_tip_peer_management) auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, /*banman=*/nullptr, *m_node.dstxman, *m_node.chainman, *m_node.mempool, *m_node.mn_metaman, *m_node.mn_sync, *m_node.govman, *m_node.sporkman, /*mn_activeman=*/ nullptr, m_node.dmnman, - /*active_ctx=*/nullptr, m_node.cj_ctx, m_node.llmq_ctx, /*ignore_incoming_txs=*/false); + /*active_ctx=*/nullptr, /*cj_ctx=*/nullptr, m_node.llmq_ctx, /*ignore_incoming_txs=*/false); constexpr int max_outbound_full_relay = MAX_OUTBOUND_FULL_RELAY_CONNECTIONS; CConnman::Options options; @@ -254,8 +254,8 @@ BOOST_AUTO_TEST_CASE(block_relay_only_eviction) auto connman = std::make_unique(0x1337, 0x1337, *m_node.addrman, *m_node.netgroupman); auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, /*banman=*/nullptr, *m_node.dstxman, *m_node.chainman, *m_node.mempool, *m_node.mn_metaman, *m_node.mn_sync, - *m_node.govman, *m_node.sporkman, /*mn_activeman=*/ nullptr, m_node.dmnman, - /*active_ctx=*/nullptr, m_node.cj_ctx, m_node.llmq_ctx, /*ignore_incoming_txs=*/false); + *m_node.govman, *m_node.sporkman, /*mn_activeman=*/nullptr, m_node.dmnman, + /*active_ctx=*/nullptr, /*cj_ctx=*/nullptr, m_node.llmq_ctx, /*ignore_incoming_txs=*/false); constexpr int max_outbound_block_relay{MAX_BLOCK_RELAY_ONLY_CONNECTIONS}; constexpr int64_t MINIMUM_CONNECT_TIME{30}; @@ -322,7 +322,7 @@ BOOST_AUTO_TEST_CASE(peer_discouragement) auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, banman.get(), *m_node.dstxman, *m_node.chainman, *m_node.mempool, *m_node.mn_metaman, *m_node.mn_sync, *m_node.govman, *m_node.sporkman, /*mn_activeman=*/nullptr, m_node.dmnman, - /*active_ctx=*/nullptr, m_node.cj_ctx, m_node.llmq_ctx, /*ignore_incoming_txs=*/false); + /*active_ctx=*/nullptr, /*cj_ctx=*/nullptr, m_node.llmq_ctx, /*ignore_incoming_txs=*/false); CNetAddr tor_netaddr; BOOST_REQUIRE( @@ -427,7 +427,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime) auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, banman.get(), *m_node.dstxman, *m_node.chainman, *m_node.mempool, *m_node.mn_metaman, *m_node.mn_sync, *m_node.govman, *m_node.sporkman, /*mn_activeman=*/nullptr, m_node.dmnman, - /*active_ctx=*/nullptr, m_node.cj_ctx, m_node.llmq_ctx, /*ignore_incoming_txs=*/false); + /*active_ctx=*/nullptr, /*cj_ctx=*/nullptr, m_node.llmq_ctx, /*ignore_incoming_txs=*/false); banman->ClearBanned(); int64_t nStartTime = GetTime(); diff --git a/src/test/net_peer_connection_tests.cpp b/src/test/net_peer_connection_tests.cpp index a883f9c6ba1e..966aec6dddce 100644 --- a/src/test/net_peer_connection_tests.cpp +++ b/src/test/net_peer_connection_tests.cpp @@ -88,7 +88,7 @@ BOOST_AUTO_TEST_CASE(test_addnode_getaddednodeinfo_and_connection_detection) auto peerman = PeerManager::make(chainparams, *connman, *m_node.addrman, /*banman=*/nullptr, *m_node.dstxman, *m_node.chainman, *m_node.mempool, *m_node.mn_metaman, *m_node.mn_sync, *m_node.govman, *m_node.sporkman, /*mn_activeman=*/nullptr, m_node.dmnman, - /*active_ctx=*/nullptr, m_node.cj_ctx, m_node.llmq_ctx, /*ignore_incoming_txs=*/false); + /*active_ctx=*/nullptr, /*cj_ctx=*/nullptr, m_node.llmq_ctx, /*ignore_incoming_txs=*/false); NodeId id{0}; std::vector nodes; diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index db7298e92fa9..727550fe44b6 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -342,23 +342,12 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector(); - m_node.banman = std::make_unique(m_args.GetDataDirBase() / "banlist", nullptr, DEFAULT_MISBEHAVING_BANTIME); - m_node.peerman = PeerManager::make(chainparams, *m_node.connman, *m_node.addrman, m_node.banman.get(), *m_node.dstxman, - *m_node.chainman, *m_node.mempool, *m_node.mn_metaman, *m_node.mn_sync, - *m_node.govman, *m_node.sporkman, /*mn_activeman=*/nullptr, m_node.dmnman, - /*active_ctx=*/nullptr, m_node.cj_ctx, m_node.llmq_ctx, /*ignore_incoming_txs=*/false); - { - CConnman::Options options; - options.m_msgproc = m_node.peerman.get(); - options.socketEventsMode = ::g_socket_events_mode; - m_node.connman->Init(options); - } - +#ifdef ENABLE_WALLET + // The test suite doesn't use masternode mode, so we may initialize it m_node.cj_ctx = CJContext::make(*m_node.chainman, *m_node.dmnman, *m_node.mn_metaman, *m_node.mempool, - /*mn_activeman=*/nullptr, *m_node.mn_sync, *m_node.llmq_ctx->isman, - /*relay_txes=*/true); + *m_node.mn_sync, *m_node.llmq_ctx->isman, /*relay_txes=*/true); + assert(m_node.cj_ctx); -#ifdef ENABLE_WALLET // WalletInit::Construct()-like logic needed for wallet tests that run on // TestingSetup and its children (e.g. TestChain100Setup) instead of // WalletTestingSetup @@ -369,6 +358,18 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector(m_args.GetDataDirBase() / "banlist", nullptr, DEFAULT_MISBEHAVING_BANTIME); + m_node.peerman = PeerManager::make(chainparams, *m_node.connman, *m_node.addrman, m_node.banman.get(), *m_node.dstxman, + *m_node.chainman, *m_node.mempool, *m_node.mn_metaman, *m_node.mn_sync, + *m_node.govman, *m_node.sporkman, /*mn_activeman=*/nullptr, m_node.dmnman, + /*active_ctx=*/nullptr, m_node.cj_ctx.get(), m_node.llmq_ctx, /*ignore_incoming_txs=*/false); + { + CConnman::Options options; + options.m_msgproc = m_node.peerman.get(); + options.socketEventsMode = ::g_socket_events_mode; + m_node.connman->Init(options); + } + BlockValidationState state; if (!m_node.chainman->ActiveChainstate().ActivateBestChain(state)) { throw std::runtime_error(strprintf("ActivateBestChain failed. (%s)", state.ToString())); @@ -377,15 +378,17 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector& extra_args) From 5bd1a6b56dbb2c144d26eeb48dc4c74e126bb1b6 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Mon, 8 Sep 2025 22:15:11 +0000 Subject: [PATCH 09/11] refactor: drop `m_is_masternode` from `CCoinJoinClientQueueManager` As it's now a fixed value, we can drop it, yay! --- src/coinjoin/client.cpp | 4 ---- src/coinjoin/client.h | 9 ++++----- src/coinjoin/context.cpp | 4 +--- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/coinjoin/client.cpp b/src/coinjoin/client.cpp index 81771d1d95ac..a26a071d60e4 100644 --- a/src/coinjoin/client.cpp +++ b/src/coinjoin/client.cpp @@ -44,8 +44,6 @@ MessageProcessingResult CCoinJoinClientQueueManager::ProcessMessage(NodeId from, if (msg_type != NetMsgType::DSQUEUE) { return {}; } - - if (m_is_masternode) return {}; if (!m_mn_sync.IsBlockchainSynced()) return {}; assert(m_mn_metaman.IsValid()); @@ -1839,8 +1837,6 @@ void CCoinJoinClientManager::UpdatedBlockTip(const CBlockIndex* pindex) void CCoinJoinClientQueueManager::DoMaintenance() { - if (m_is_masternode) return; // no client-side mixing on masternodes - if (!m_mn_sync.IsBlockchainSynced() || ShutdownRequested()) return; CheckQueue(); diff --git a/src/coinjoin/client.h b/src/coinjoin/client.h index 0d4aab3986ce..b364dc937280 100644 --- a/src/coinjoin/client.h +++ b/src/coinjoin/client.h @@ -239,17 +239,16 @@ class CCoinJoinClientQueueManager : public CCoinJoinBaseManager const CMasternodeSync& m_mn_sync; mutable Mutex cs_ProcessDSQueue; - const bool m_is_masternode; public: explicit CCoinJoinClientQueueManager(CoinJoinWalletManager& walletman, CDeterministicMNManager& dmnman, - CMasternodeMetaMan& mn_metaman, const CMasternodeSync& mn_sync, - bool is_masternode) : + CMasternodeMetaMan& mn_metaman, const CMasternodeSync& mn_sync) : m_walletman(walletman), m_dmnman(dmnman), m_mn_metaman(mn_metaman), - m_mn_sync(mn_sync), - m_is_masternode{is_masternode} {}; + m_mn_sync(mn_sync) + { + } [[nodiscard]] MessageProcessingResult ProcessMessage(NodeId from, CConnman& connman, std::string_view msg_type, CDataStream& vRecv) diff --git a/src/coinjoin/context.cpp b/src/coinjoin/context.cpp index 8405fd8a2eb5..90422cf471d3 100644 --- a/src/coinjoin/context.cpp +++ b/src/coinjoin/context.cpp @@ -61,9 +61,7 @@ CJContextImpl::CJContextImpl(ChainstateManager& chainman, CDeterministicMNManage m_relay_txes{relay_txes}, walletman{std::make_unique(chainman, dmnman, mn_metaman, mempool, mn_sync, isman, queueman, /*is_masternode=*/false)}, - queueman{m_relay_txes ? std::make_unique(*walletman, dmnman, mn_metaman, mn_sync, - /*is_masternode=*/false) - : nullptr} + queueman{m_relay_txes ? std::make_unique(*walletman, dmnman, mn_metaman, mn_sync) : nullptr} { } From 4f3da688bba5a88363f0a0221e6f76f1a5c71357 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Tue, 30 Sep 2025 11:59:38 +0000 Subject: [PATCH 10/11] refactor: drop `m_is_masternode` from `CoinJoinWalletManager` --- src/coinjoin/client.cpp | 29 ++++------------------------- src/coinjoin/client.h | 20 +++++--------------- src/coinjoin/context.cpp | 27 +++++++++++++-------------- src/coinjoin/context.h | 2 +- src/masternode/utils.cpp | 2 +- src/masternode/utils.h | 2 +- 6 files changed, 25 insertions(+), 57 deletions(-) diff --git a/src/coinjoin/client.cpp b/src/coinjoin/client.cpp index a26a071d60e4..88d5ee4f8187 100644 --- a/src/coinjoin/client.cpp +++ b/src/coinjoin/client.cpp @@ -141,7 +141,6 @@ MessageProcessingResult CCoinJoinClientQueueManager::ProcessMessage(NodeId from, void CCoinJoinClientManager::ProcessMessage(CNode& peer, CChainState& active_chainstate, CConnman& connman, const CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv) { - if (m_is_masternode) return; if (!CCoinJoinClientOptions::IsEnabled()) return; if (!m_mn_sync.IsBlockchainSynced()) return; @@ -166,21 +165,18 @@ void CCoinJoinClientManager::ProcessMessage(CNode& peer, CChainState& active_cha CCoinJoinClientSession::CCoinJoinClientSession(const std::shared_ptr& wallet, CCoinJoinClientManager& clientman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, const CMasternodeSync& mn_sync, const llmq::CInstantSendManager& isman, - const std::unique_ptr& queueman, - bool is_masternode) : + const std::unique_ptr& queueman) : m_wallet(wallet), m_clientman(clientman), m_dmnman(dmnman), m_mn_metaman(mn_metaman), m_mn_sync(mn_sync), m_isman{isman}, - m_queueman(queueman), - m_is_masternode{is_masternode} + m_queueman(queueman) {} void CCoinJoinClientSession::ProcessMessage(CNode& peer, CChainState& active_chainstate, CConnman& connman, const CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv) { - if (m_is_masternode) return; if (!CCoinJoinClientOptions::IsEnabled()) return; if (!m_mn_sync.IsBlockchainSynced()) return; @@ -383,8 +379,6 @@ bool CCoinJoinClientManager::GetMixingMasternodesInfo(std::vector >& vecPSInOutPairsIn, CConnman& connman) { - if (m_is_masternode) { - WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::SendDenominate -- CoinJoin from a Masternode is not supported currently.\n"); - return false; - } - if (CTransaction(txMyCollateral).IsNull()) { WalletCJLogPrint(m_wallet, "CCoinJoinClient:SendDenominate -- CoinJoin collateral not set\n"); return false; @@ -495,8 +483,6 @@ bool CCoinJoinClientSession::SendDenominate(const std::vectorcs_wallet); @@ -679,8 +664,6 @@ bool CCoinJoinClientSession::SignFinalTransaction(CNode& peer, CChainState& acti // mixing transaction was completed (failed or successful) void CCoinJoinClientSession::CompletedTransaction(PoolMessage nMessageID) { - if (m_is_masternode) return; - if (nMessageID == MSG_SUCCESS) { m_clientman.UpdatedSuccessBlock(); keyHolderStorage.KeepAll(); @@ -696,7 +679,6 @@ void CCoinJoinClientSession::CompletedTransaction(PoolMessage nMessageID) void CCoinJoinClientManager::UpdatedSuccessBlock() { - if (m_is_masternode) return; nCachedLastSuccessBlock = nCachedBlockHeight; } @@ -788,7 +770,6 @@ bool CCoinJoinClientManager::CheckAutomaticBackup() bool CCoinJoinClientSession::DoAutomaticDenominating(ChainstateManager& chainman, CConnman& connman, const CTxMemPool& mempool, bool fDryRun) { - if (m_is_masternode) return false; // no client-side mixing on masternodes if (nState != POOL_STATE_IDLE) return false; if (!m_mn_sync.IsBlockchainSynced()) { @@ -969,7 +950,6 @@ bool CCoinJoinClientSession::DoAutomaticDenominating(ChainstateManager& chainman bool CCoinJoinClientManager::DoAutomaticDenominating(ChainstateManager& chainman, CConnman& connman, const CTxMemPool& mempool, bool fDryRun) { - if (m_is_masternode) return false; // no client-side mixing on masternodes if (!CCoinJoinClientOptions::IsEnabled() || !IsMixing()) return false; if (!m_mn_sync.IsBlockchainSynced()) { @@ -998,7 +978,7 @@ bool CCoinJoinClientManager::DoAutomaticDenominating(ChainstateManager& chainman AssertLockNotHeld(cs_deqsessions); LOCK(cs_deqsessions); if (int(deqSessions.size()) < CCoinJoinClientOptions::GetSessions()) { - deqSessions.emplace_back(m_wallet, *this, m_dmnman, m_mn_metaman, m_mn_sync, m_isman, m_queueman, m_is_masternode); + deqSessions.emplace_back(m_wallet, *this, m_dmnman, m_mn_metaman, m_mn_sync, m_isman, m_queueman); } for (auto& session : deqSessions) { if (!CheckAutomaticBackup()) return false; @@ -1845,7 +1825,6 @@ void CCoinJoinClientQueueManager::DoMaintenance() void CCoinJoinClientManager::DoMaintenance(ChainstateManager& chainman, CConnman& connman, const CTxMemPool& mempool) { if (!CCoinJoinClientOptions::IsEnabled()) return; - if (m_is_masternode) return; // no client-side mixing on masternodes if (!m_mn_sync.IsBlockchainSynced() || ShutdownRequested()) return; @@ -1899,7 +1878,7 @@ 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, m_dmnman, m_mn_metaman, m_mn_sync, - m_isman, m_queueman, m_is_masternode)); + m_isman, m_queueman)); } void CoinJoinWalletManager::DoMaintenance(CConnman& connman) diff --git a/src/coinjoin/client.h b/src/coinjoin/client.h index b364dc937280..222122b0329e 100644 --- a/src/coinjoin/client.h +++ b/src/coinjoin/client.h @@ -77,15 +77,14 @@ class CoinJoinWalletManager { public: CoinJoinWalletManager(ChainstateManager& chainman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, const CTxMemPool& mempool, const CMasternodeSync& mn_sync, const llmq::CInstantSendManager& isman, - const std::unique_ptr& queueman, bool is_masternode) : + const std::unique_ptr& queueman) : 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} + m_queueman(queueman) {} ~CoinJoinWalletManager() { @@ -128,8 +127,6 @@ class CoinJoinWalletManager { const llmq::CInstantSendManager& m_isman; const std::unique_ptr& m_queueman; - const bool m_is_masternode; - mutable Mutex cs_wallet_manager_map; wallet_name_cjman_map m_wallet_manager_map GUARDED_BY(cs_wallet_manager_map); }; @@ -145,9 +142,6 @@ class CCoinJoinClientSession : public CCoinJoinBaseSession const llmq::CInstantSendManager& m_isman; const std::unique_ptr& m_queueman; - // Track node type - const bool m_is_masternode; - std::vector vecOutPointLocked; bilingual_str strLastMessage; @@ -202,7 +196,7 @@ class CCoinJoinClientSession : public CCoinJoinBaseSession explicit CCoinJoinClientSession(const std::shared_ptr& wallet, CCoinJoinClientManager& clientman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, const CMasternodeSync& mn_sync, const llmq::CInstantSendManager& isman, - const std::unique_ptr& queueman, bool is_masternode); + const std::unique_ptr& queueman); void ProcessMessage(CNode& peer, CChainState& active_chainstate, CConnman& connman, const CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv); @@ -268,9 +262,6 @@ class CCoinJoinClientManager const llmq::CInstantSendManager& m_isman; const std::unique_ptr& m_queueman; - // Track node type - const bool m_is_masternode; - // Keep track of the used Masternodes std::vector vecMasternodesUsed; @@ -303,14 +294,13 @@ class CCoinJoinClientManager explicit CCoinJoinClientManager(const std::shared_ptr& wallet, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, const CMasternodeSync& mn_sync, const llmq::CInstantSendManager& isman, - const std::unique_ptr& queueman, bool is_masternode) : + const std::unique_ptr& queueman) : m_wallet(wallet), m_dmnman(dmnman), m_mn_metaman(mn_metaman), m_mn_sync(mn_sync), m_isman{isman}, - m_queueman(queueman), - m_is_masternode{is_masternode} + m_queueman(queueman) { } diff --git a/src/coinjoin/context.cpp b/src/coinjoin/context.cpp index 90422cf471d3..cb85be55c35b 100644 --- a/src/coinjoin/context.cpp +++ b/src/coinjoin/context.cpp @@ -39,7 +39,7 @@ class CJContextImpl final : public CJContext std::string_view msg_type, CDataStream& vRecv) override; std::optional getQueueFromHash(const uint256& hash) const override; std::optional getQueueSize() const override; - std::vector getMixingMasternodes() const override; + std::vector getMixingMasternodes() override; void addWallet(const std::shared_ptr& wallet) override; void removeWallet(const std::string& name) override; void flushWallet(const std::string& name) override; @@ -51,7 +51,7 @@ class CJContextImpl final : public CJContext private: const bool m_relay_txes; - const std::unique_ptr walletman; + CoinJoinWalletManager walletman; const std::unique_ptr queueman; }; @@ -59,9 +59,8 @@ CJContextImpl::CJContextImpl(ChainstateManager& chainman, CDeterministicMNManage CMasternodeMetaMan& mn_metaman, CTxMemPool& mempool, const CMasternodeSync& mn_sync, const llmq::CInstantSendManager& isman, bool relay_txes) : m_relay_txes{relay_txes}, - walletman{std::make_unique(chainman, dmnman, mn_metaman, mempool, mn_sync, isman, queueman, - /*is_masternode=*/false)}, - queueman{m_relay_txes ? std::make_unique(*walletman, dmnman, mn_metaman, mn_sync) : nullptr} + walletman{chainman, dmnman, mn_metaman, mempool, mn_sync, isman, queueman}, + queueman{m_relay_txes ? std::make_unique(walletman, dmnman, mn_metaman, mn_sync) : nullptr} { } @@ -70,7 +69,7 @@ void CJContextImpl::Schedule(CConnman& connman, CScheduler& scheduler) if (!m_relay_txes) return; scheduler.scheduleEvery(std::bind(&CCoinJoinClientQueueManager::DoMaintenance, std::ref(*queueman)), std::chrono::seconds{1}); - scheduler.scheduleEvery(std::bind(&CoinJoinWalletManager::DoMaintenance, std::ref(*walletman), std::ref(connman)), + scheduler.scheduleEvery(std::bind(&CoinJoinWalletManager::DoMaintenance, std::ref(walletman), std::ref(connman)), std::chrono::seconds{1}); } @@ -79,7 +78,7 @@ void CJContextImpl::UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIn if (fInitialDownload || pindexNew == pindexFork) // In IBD or blocks were disconnected without any new ones return; - walletman->ForEachCJClientMan( + walletman.ForEachCJClientMan( [&pindexNew](std::unique_ptr& clientman) { clientman->UpdatedBlockTip(pindexNew); }); } @@ -93,13 +92,13 @@ bool CJContextImpl::hasQueue(const uint256& hash) const CCoinJoinClientManager* CJContextImpl::getClient(const std::string& name) { - return walletman->Get(name); + return walletman.Get(name); } MessageProcessingResult CJContextImpl::processMessage(CNode& pfrom, CChainState& chainstate, CConnman& connman, CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv) { - walletman->ForEachCJClientMan([&](std::unique_ptr& clientman) { + walletman.ForEachCJClientMan([&](std::unique_ptr& clientman) { clientman->ProcessMessage(pfrom, chainstate, connman, mempool, msg_type, vRecv); }); if (queueman) { @@ -124,27 +123,27 @@ std::optional CJContextImpl::getQueueSize() const return std::nullopt; } -std::vector CJContextImpl::getMixingMasternodes() const +std::vector CJContextImpl::getMixingMasternodes() { std::vector ret{}; - walletman->ForEachCJClientMan( + walletman.ForEachCJClientMan( [&](const std::unique_ptr& clientman) { clientman->GetMixingMasternodesInfo(ret); }); return ret; } void CJContextImpl::addWallet(const std::shared_ptr& wallet) { - walletman->Add(wallet); + walletman.Add(wallet); } void CJContextImpl::flushWallet(const std::string& name) { - walletman->Flush(name); + walletman.Flush(name); } void CJContextImpl::removeWallet(const std::string& name) { - walletman->Remove(name); + walletman.Remove(name); } #endif // ENABLE_WALLET diff --git a/src/coinjoin/context.h b/src/coinjoin/context.h index 9e9b5de11846..18f64f7db4a6 100644 --- a/src/coinjoin/context.h +++ b/src/coinjoin/context.h @@ -52,7 +52,7 @@ class CJContext : public CValidationInterface CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv) = 0; virtual std::optional getQueueFromHash(const uint256& hash) const = 0; virtual std::optional getQueueSize() const = 0; - virtual std::vector getMixingMasternodes() const = 0; + virtual std::vector getMixingMasternodes() = 0; virtual void addWallet(const std::shared_ptr& wallet) = 0; virtual void removeWallet(const std::string& name) = 0; virtual void flushWallet(const std::string& name) = 0; diff --git a/src/masternode/utils.cpp b/src/masternode/utils.cpp index d5961446a4d3..c392411108fb 100644 --- a/src/masternode/utils.cpp +++ b/src/masternode/utils.cpp @@ -17,7 +17,7 @@ #endif void CMasternodeUtils::DoMaintenance(CConnman& connman, CDeterministicMNManager& dmnman, const CMasternodeSync& mn_sync, - const CJContext* const cj_ctx) + CJContext* const cj_ctx) { if (!mn_sync.IsBlockchainSynced()) return; if (ShutdownRequested()) return; diff --git a/src/masternode/utils.h b/src/masternode/utils.h index 0c9b2adfec18..227027435476 100644 --- a/src/masternode/utils.h +++ b/src/masternode/utils.h @@ -14,7 +14,7 @@ class CMasternodeUtils { public: static void DoMaintenance(CConnman& connman, CDeterministicMNManager& dmnman, const CMasternodeSync& mn_sync, - const CJContext* const cj_ctx); + CJContext* const cj_ctx); }; #endif // BITCOIN_MASTERNODE_UTILS_H From 6a20464584f16b611b1a4c079863b29d868096f7 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Sun, 5 Oct 2025 14:46:27 +0000 Subject: [PATCH 11/11] refactor: `s/CJContext/CJWalletManager/g` CJContext is no longer just a context class, it's a lot more involved now and serves triple duty as also a notification interface and a layer of abstraction. Name reflects that it's the wallet-specific components of CoinJoin. --- src/Makefile.am | 4 +- src/coinjoin/interfaces.cpp | 6 +-- src/coinjoin/{context.cpp => walletman.cpp} | 54 +++++++++++---------- src/coinjoin/{context.h => walletman.h} | 18 +++---- src/init.cpp | 26 +++++----- src/masternode/utils.cpp | 10 ++-- src/masternode/utils.h | 4 +- src/net_processing.cpp | 26 +++++----- src/net_processing.h | 6 +-- src/node/context.cpp | 2 +- src/node/context.h | 4 +- src/rpc/coinjoin.cpp | 7 ++- src/test/coinjoin_dstxmanager_tests.cpp | 1 - src/test/denialofservice_tests.cpp | 14 ++++-- src/test/net_peer_connection_tests.cpp | 3 +- src/test/util/setup_common.cpp | 13 ++--- src/wallet/test/coinjoin_tests.cpp | 4 +- src/wallet/test/wallet_tests.cpp | 1 - test/lint/lint-circular-dependencies.py | 2 +- 19 files changed, 103 insertions(+), 102 deletions(-) rename src/coinjoin/{context.cpp => walletman.cpp} (60%) rename src/coinjoin/{context.h => walletman.h} (74%) diff --git a/src/Makefile.am b/src/Makefile.am index 77445e48cc8b..fd94d2bca363 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -179,10 +179,10 @@ BITCOIN_CORE_H = \ coinjoin/coinjoin.h \ coinjoin/client.h \ coinjoin/common.h \ - coinjoin/context.h \ coinjoin/options.h \ coinjoin/server.h \ coinjoin/util.h \ + coinjoin/walletman.h \ coins.h \ common/bloom.h \ compat/assumptions.h \ @@ -486,8 +486,8 @@ libbitcoin_node_a_SOURCES = \ chainlock/clsig.cpp \ chainlock/signing.cpp \ coinjoin/coinjoin.cpp \ - coinjoin/context.cpp \ coinjoin/server.cpp \ + coinjoin/walletman.cpp \ consensus/tx_verify.cpp \ dbwrapper.cpp \ deploymentstatus.cpp \ diff --git a/src/coinjoin/interfaces.cpp b/src/coinjoin/interfaces.cpp index 561df7a9083b..07f7d889701d 100644 --- a/src/coinjoin/interfaces.cpp +++ b/src/coinjoin/interfaces.cpp @@ -5,8 +5,8 @@ #include #include -#include #include +#include #include #include #include @@ -77,9 +77,9 @@ class CoinJoinClientImpl : public interfaces::CoinJoin::Client class CoinJoinLoaderImpl : public interfaces::CoinJoin::Loader { private: - CJContext& manager() + CJWalletManager& manager() { - return *Assert(m_node.cj_ctx); + return *Assert(m_node.cj_walletman); } interfaces::WalletLoader& wallet_loader() diff --git a/src/coinjoin/context.cpp b/src/coinjoin/walletman.cpp similarity index 60% rename from src/coinjoin/context.cpp rename to src/coinjoin/walletman.cpp index cb85be55c35b..50b552d766fb 100644 --- a/src/coinjoin/context.cpp +++ b/src/coinjoin/walletman.cpp @@ -6,7 +6,7 @@ #include #endif -#include +#include #include #include @@ -21,13 +21,13 @@ #include #ifdef ENABLE_WALLET -class CJContextImpl final : public CJContext +class CJWalletManagerImpl final : public CJWalletManager { public: - CJContextImpl(ChainstateManager& chainman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, - CTxMemPool& mempool, const CMasternodeSync& mn_sync, const llmq::CInstantSendManager& isman, - bool relay_txes); - virtual ~CJContextImpl() = default; + CJWalletManagerImpl(ChainstateManager& chainman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, + CTxMemPool& mempool, const CMasternodeSync& mn_sync, const llmq::CInstantSendManager& isman, + bool relay_txes); + virtual ~CJWalletManagerImpl() = default; public: void Schedule(CConnman& connman, CScheduler& scheduler) override; @@ -55,16 +55,17 @@ class CJContextImpl final : public CJContext const std::unique_ptr queueman; }; -CJContextImpl::CJContextImpl(ChainstateManager& chainman, CDeterministicMNManager& dmnman, - CMasternodeMetaMan& mn_metaman, CTxMemPool& mempool, const CMasternodeSync& mn_sync, - const llmq::CInstantSendManager& isman, bool relay_txes) : +CJWalletManagerImpl::CJWalletManagerImpl(ChainstateManager& chainman, CDeterministicMNManager& dmnman, + CMasternodeMetaMan& mn_metaman, CTxMemPool& mempool, + const CMasternodeSync& mn_sync, const llmq::CInstantSendManager& isman, + bool relay_txes) : m_relay_txes{relay_txes}, walletman{chainman, dmnman, mn_metaman, mempool, mn_sync, isman, queueman}, queueman{m_relay_txes ? std::make_unique(walletman, dmnman, mn_metaman, mn_sync) : nullptr} { } -void CJContextImpl::Schedule(CConnman& connman, CScheduler& scheduler) +void CJWalletManagerImpl::Schedule(CConnman& connman, CScheduler& scheduler) { if (!m_relay_txes) return; scheduler.scheduleEvery(std::bind(&CCoinJoinClientQueueManager::DoMaintenance, std::ref(*queueman)), @@ -73,7 +74,7 @@ void CJContextImpl::Schedule(CConnman& connman, CScheduler& scheduler) std::chrono::seconds{1}); } -void CJContextImpl::UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, bool fInitialDownload) +void CJWalletManagerImpl::UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, bool fInitialDownload) { if (fInitialDownload || pindexNew == pindexFork) // In IBD or blocks were disconnected without any new ones return; @@ -82,7 +83,7 @@ void CJContextImpl::UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIn [&pindexNew](std::unique_ptr& clientman) { clientman->UpdatedBlockTip(pindexNew); }); } -bool CJContextImpl::hasQueue(const uint256& hash) const +bool CJWalletManagerImpl::hasQueue(const uint256& hash) const { if (queueman) { return queueman->HasQueue(hash); @@ -90,13 +91,14 @@ bool CJContextImpl::hasQueue(const uint256& hash) const return false; } -CCoinJoinClientManager* CJContextImpl::getClient(const std::string& name) +CCoinJoinClientManager* CJWalletManagerImpl::getClient(const std::string& name) { return walletman.Get(name); } -MessageProcessingResult CJContextImpl::processMessage(CNode& pfrom, CChainState& chainstate, CConnman& connman, - CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv) +MessageProcessingResult CJWalletManagerImpl::processMessage(CNode& pfrom, CChainState& chainstate, CConnman& connman, + CTxMemPool& mempool, std::string_view msg_type, + CDataStream& vRecv) { walletman.ForEachCJClientMan([&](std::unique_ptr& clientman) { clientman->ProcessMessage(pfrom, chainstate, connman, mempool, msg_type, vRecv); @@ -107,7 +109,7 @@ MessageProcessingResult CJContextImpl::processMessage(CNode& pfrom, CChainState& return {}; } -std::optional CJContextImpl::getQueueFromHash(const uint256& hash) const +std::optional CJWalletManagerImpl::getQueueFromHash(const uint256& hash) const { if (queueman) { return queueman->GetQueueFromHash(hash); @@ -115,7 +117,7 @@ std::optional CJContextImpl::getQueueFromHash(const uint256& has return std::nullopt; } -std::optional CJContextImpl::getQueueSize() const +std::optional CJWalletManagerImpl::getQueueSize() const { if (queueman) { return queueman->GetQueueSize(); @@ -123,7 +125,7 @@ std::optional CJContextImpl::getQueueSize() const return std::nullopt; } -std::vector CJContextImpl::getMixingMasternodes() +std::vector CJWalletManagerImpl::getMixingMasternodes() { std::vector ret{}; walletman.ForEachCJClientMan( @@ -131,29 +133,29 @@ std::vector CJContextImpl::getMixingMasternodes() return ret; } -void CJContextImpl::addWallet(const std::shared_ptr& wallet) +void CJWalletManagerImpl::addWallet(const std::shared_ptr& wallet) { walletman.Add(wallet); } -void CJContextImpl::flushWallet(const std::string& name) +void CJWalletManagerImpl::flushWallet(const std::string& name) { walletman.Flush(name); } -void CJContextImpl::removeWallet(const std::string& name) +void CJWalletManagerImpl::removeWallet(const std::string& name) { walletman.Remove(name); } #endif // ENABLE_WALLET -std::unique_ptr CJContext::make(ChainstateManager& chainman, CDeterministicMNManager& dmnman, - CMasternodeMetaMan& mn_metaman, CTxMemPool& mempool, - const CMasternodeSync& mn_sync, const llmq::CInstantSendManager& isman, - bool relay_txes) +std::unique_ptr CJWalletManager::make(ChainstateManager& chainman, CDeterministicMNManager& dmnman, + CMasternodeMetaMan& mn_metaman, CTxMemPool& mempool, + const CMasternodeSync& mn_sync, + const llmq::CInstantSendManager& isman, bool relay_txes) { #ifdef ENABLE_WALLET - return std::make_unique(chainman, dmnman, mn_metaman, mempool, mn_sync, isman, relay_txes); + return std::make_unique(chainman, dmnman, mn_metaman, mempool, mn_sync, isman, relay_txes); #else // Cannot be constructed if wallet support isn't built return nullptr; diff --git a/src/coinjoin/context.h b/src/coinjoin/walletman.h similarity index 74% rename from src/coinjoin/context.h rename to src/coinjoin/walletman.h index 18f64f7db4a6..720a4bdf2f81 100644 --- a/src/coinjoin/context.h +++ b/src/coinjoin/walletman.h @@ -2,8 +2,8 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef BITCOIN_COINJOIN_CONTEXT_H -#define BITCOIN_COINJOIN_CONTEXT_H +#ifndef BITCOIN_COINJOIN_WALLETMAN_H +#define BITCOIN_COINJOIN_WALLETMAN_H #include #include @@ -33,14 +33,14 @@ namespace wallet { class CWallet; } // namespace wallet -class CJContext : public CValidationInterface +class CJWalletManager : public CValidationInterface { public: - static std::unique_ptr make(ChainstateManager& chainman, CDeterministicMNManager& dmnman, - CMasternodeMetaMan& mn_metaman, CTxMemPool& mempool, - const CMasternodeSync& mn_sync, const llmq::CInstantSendManager& isman, - bool relay_txes); - virtual ~CJContext() = default; + static std::unique_ptr make(ChainstateManager& chainman, CDeterministicMNManager& dmnman, + CMasternodeMetaMan& mn_metaman, CTxMemPool& mempool, + const CMasternodeSync& mn_sync, const llmq::CInstantSendManager& isman, + bool relay_txes); + virtual ~CJWalletManager() = default; public: virtual void Schedule(CConnman& connman, CScheduler& scheduler) = 0; @@ -63,4 +63,4 @@ class CJContext : public CValidationInterface bool fInitialDownload) override = 0; }; -#endif // BITCOIN_COINJOIN_CONTEXT_H +#endif // BITCOIN_COINJOIN_WALLETMAN_H diff --git a/src/init.cpp b/src/init.cpp index 27eaf71fae31..6f7a09542a8a 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -78,8 +78,8 @@ #include #include -#include #include +#include #include #include #include @@ -325,8 +325,8 @@ void PrepareShutdown(NodeContext& node) g_active_notification_interface.reset(); } - if (node.cj_ctx) { - UnregisterValidationInterface(node.cj_ctx.get()); + if (node.cj_walletman) { + UnregisterValidationInterface(node.cj_walletman.get()); } if (g_ds_notification_interface) { @@ -391,7 +391,7 @@ void PrepareShutdown(NodeContext& node) // After all wallets are removed, destroy all CoinJoin objects // and reset them to nullptr - node.cj_ctx.reset(); + node.cj_walletman.reset(); node.dstxman.reset(); UnregisterAllValidationInterfaces(); @@ -2139,20 +2139,20 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) assert(!node.dstxman); node.dstxman = std::make_unique(); - assert(!node.cj_ctx); + assert(!node.cj_walletman); if (!node.mn_activeman) { - node.cj_ctx = CJContext::make(chainman, *node.dmnman, *node.mn_metaman, *node.mempool, *node.mn_sync, - *node.llmq_ctx->isman, !ignores_incoming_txs); + node.cj_walletman = CJWalletManager::make(chainman, *node.dmnman, *node.mn_metaman, *node.mempool, *node.mn_sync, + *node.llmq_ctx->isman, !ignores_incoming_txs); } - if (node.cj_ctx) { - RegisterValidationInterface(node.cj_ctx.get()); + if (node.cj_walletman) { + RegisterValidationInterface(node.cj_walletman.get()); } assert(!node.peerman); node.peerman = PeerManager::make(chainparams, *node.connman, *node.addrman, node.banman.get(), *node.dstxman, chainman, *node.mempool, *node.mn_metaman, *node.mn_sync, *node.govman, *node.sporkman, node.mn_activeman.get(), node.dmnman, - node.active_ctx, node.cj_ctx.get(), node.llmq_ctx, ignores_incoming_txs); + node.active_ctx, node.cj_walletman.get(), node.llmq_ctx, ignores_incoming_txs); RegisterValidationInterface(node.peerman.get()); g_ds_notification_interface = std::make_unique( @@ -2268,7 +2268,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) node.scheduler->scheduleEvery(std::bind(&CNetFulfilledRequestManager::DoMaintenance, std::ref(*node.netfulfilledman)), std::chrono::minutes{1}); node.scheduler->scheduleEvery(std::bind(&CMasternodeSync::DoMaintenance, std::ref(*node.mn_sync), std::cref(*node.peerman), std::cref(*node.govman)), std::chrono::seconds{1}); - node.scheduler->scheduleEvery(std::bind(&CMasternodeUtils::DoMaintenance, std::ref(*node.connman), std::ref(*node.dmnman), std::ref(*node.mn_sync), node.cj_ctx.get()), std::chrono::minutes{1}); + node.scheduler->scheduleEvery(std::bind(&CMasternodeUtils::DoMaintenance, std::ref(*node.connman), std::ref(*node.dmnman), std::ref(*node.mn_sync), node.cj_walletman.get()), std::chrono::minutes{1}); node.scheduler->scheduleEvery(std::bind(&CDeterministicMNManager::DoMaintenance, std::ref(*node.dmnman)), std::chrono::seconds{10}); if (node.govman->IsValid()) { @@ -2280,8 +2280,8 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) node.scheduler->scheduleEvery(std::bind(&llmq::CDKGSessionManager::CleanupOldContributions, std::ref(*node.llmq_ctx->qdkgsman)), std::chrono::hours{1}); } - if (node.cj_ctx) { - node.cj_ctx->Schedule(*node.connman, *node.scheduler); + if (node.cj_walletman) { + node.cj_walletman->Schedule(*node.connman, *node.scheduler); } if (::g_stats_client->active()) { diff --git a/src/masternode/utils.cpp b/src/masternode/utils.cpp index c392411108fb..4ed51031db27 100644 --- a/src/masternode/utils.cpp +++ b/src/masternode/utils.cpp @@ -8,16 +8,12 @@ #include #include -#include +#include #include #include -#ifdef ENABLE_WALLET -#include -#endif - void CMasternodeUtils::DoMaintenance(CConnman& connman, CDeterministicMNManager& dmnman, const CMasternodeSync& mn_sync, - CJContext* const cj_ctx) + CJWalletManager* const cj_walletman) { if (!mn_sync.IsBlockchainSynced()) return; if (ShutdownRequested()) return; @@ -40,7 +36,7 @@ void CMasternodeUtils::DoMaintenance(CConnman& connman, CDeterministicMNManager& return; } - auto mixing_masternodes = cj_ctx ? cj_ctx->getMixingMasternodes() : std::vector{}; + auto mixing_masternodes = cj_walletman ? cj_walletman->getMixingMasternodes() : std::vector{}; connman.ForEachNode(CConnman::AllNodes, [&](CNode* pnode) { if (pnode->m_masternode_probe_connection) { // we're not disconnecting masternode probes for at least PROBE_WAIT_INTERVAL seconds diff --git a/src/masternode/utils.h b/src/masternode/utils.h index 227027435476..e1e7b586a912 100644 --- a/src/masternode/utils.h +++ b/src/masternode/utils.h @@ -8,13 +8,13 @@ class CConnman; class CDeterministicMNManager; class CMasternodeSync; -class CJContext; +class CJWalletManager; class CMasternodeUtils { public: static void DoMaintenance(CConnman& connman, CDeterministicMNManager& dmnman, const CMasternodeSync& mn_sync, - CJContext* const cj_ctx); + CJWalletManager* const cj_walletman); }; #endif // BITCOIN_MASTERNODE_UTILS_H diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 962b64db38ff..97fec4a10733 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -41,8 +41,8 @@ #include #include -#include #include +#include #include #include #include @@ -592,7 +592,7 @@ class PeerManagerImpl final : public PeerManager CMasternodeMetaMan& mn_metaman, CMasternodeSync& mn_sync, CGovernanceManager& govman, CSporkManager& sporkman, const CActiveMasternodeManager* const mn_activeman, const std::unique_ptr& dmnman, - const std::unique_ptr& active_ctx, CJContext* const cj_ctx, + const std::unique_ptr& active_ctx, CJWalletManager* const cj_walletman, const std::unique_ptr& llmq_ctx, bool ignore_incoming_txs); /** Overridden from CValidationInterface. */ @@ -788,8 +788,8 @@ class PeerManagerImpl final : public PeerManager std::unique_ptr m_txreconciliation; const std::unique_ptr& m_dmnman; const std::unique_ptr& m_active_ctx; - /** Pointer to this node's CJContext. May be nullptr - check existence before dereferencing. */ - CJContext* const m_cj_ctx; + /** Pointer to this node's CJWalletManager. May be nullptr - check existence before dereferencing. */ + CJWalletManager* const m_cj_walletman; const std::unique_ptr& m_llmq_ctx; CMasternodeMetaMan& m_mn_metaman; CMasternodeSync& m_mn_sync; @@ -1963,10 +1963,10 @@ std::unique_ptr PeerManager::make(const CChainParams& chainparams, const CActiveMasternodeManager* const mn_activeman, const std::unique_ptr& dmnman, const std::unique_ptr& active_ctx, - CJContext* const cj_ctx, + CJWalletManager* const cj_walletman, const std::unique_ptr& llmq_ctx, bool ignore_incoming_txs) { - return std::make_unique(chainparams, connman, addrman, banman, dstxman, chainman, pool, mn_metaman, mn_sync, govman, sporkman, mn_activeman, dmnman, active_ctx, cj_ctx, llmq_ctx, ignore_incoming_txs); + return std::make_unique(chainparams, connman, addrman, banman, dstxman, chainman, pool, mn_metaman, mn_sync, govman, sporkman, mn_activeman, dmnman, active_ctx, cj_walletman, llmq_ctx, ignore_incoming_txs); } PeerManagerImpl::PeerManagerImpl(const CChainParams& chainparams, CConnman& connman, AddrMan& addrman, BanMan* banman, @@ -1975,7 +1975,7 @@ PeerManagerImpl::PeerManagerImpl(const CChainParams& chainparams, CConnman& conn CSporkManager& sporkman, const CActiveMasternodeManager* const mn_activeman, const std::unique_ptr& dmnman, const std::unique_ptr& active_ctx, - CJContext* const cj_ctx, + CJWalletManager* const cj_walletman, const std::unique_ptr& llmq_ctx, bool ignore_incoming_txs) : m_chainparams(chainparams), m_connman(connman), @@ -1986,7 +1986,7 @@ PeerManagerImpl::PeerManagerImpl(const CChainParams& chainparams, CConnman& conn m_mempool(pool), m_dmnman(dmnman), m_active_ctx(active_ctx), - m_cj_ctx(cj_ctx), + m_cj_walletman(cj_walletman), m_llmq_ctx(llmq_ctx), m_mn_metaman(mn_metaman), m_mn_sync(mn_sync), @@ -2275,7 +2275,7 @@ bool PeerManagerImpl::AlreadyHave(const CInv& inv) case MSG_ISDLOCK: return m_llmq_ctx->isman->AlreadyHave(inv); case MSG_DSQ: - return (m_cj_ctx && m_cj_ctx->hasQueue(inv.hash)) || (m_active_ctx && m_active_ctx->cj_server->HasQueue(inv.hash)); + return (m_cj_walletman && m_cj_walletman->hasQueue(inv.hash)) || (m_active_ctx && m_active_ctx->cj_server->HasQueue(inv.hash)); case MSG_PLATFORM_BAN: return m_mn_metaman.AlreadyHavePlatformBan(inv.hash); } @@ -2881,8 +2881,8 @@ void PeerManagerImpl::ProcessGetData(CNode& pfrom, Peer& peer, const std::atomic } if (!push && inv.type == MSG_DSQ) { auto opt_dsq = m_active_ctx ? m_active_ctx->cj_server->GetQueueFromHash(inv.hash) : std::nullopt; - if (m_cj_ctx && !opt_dsq.has_value()) { - opt_dsq = m_cj_ctx->getQueueFromHash(inv.hash); + if (m_cj_walletman && !opt_dsq.has_value()) { + opt_dsq = m_cj_walletman->getQueueFromHash(inv.hash); } if (opt_dsq.has_value()) { m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::DSQUEUE, *opt_dsq)); @@ -5359,8 +5359,8 @@ void PeerManagerImpl::ProcessMessage( if (found) { //probably one the extensions - if (m_cj_ctx) { - PostProcessMessage(m_cj_ctx->processMessage(pfrom, m_chainman.ActiveChainstate(), m_connman, m_mempool, msg_type, vRecv), pfrom.GetId()); + if (m_cj_walletman) { + PostProcessMessage(m_cj_walletman->processMessage(pfrom, m_chainman.ActiveChainstate(), m_connman, m_mempool, msg_type, vRecv), pfrom.GetId()); } if (m_active_ctx) { PostProcessMessage(m_active_ctx->cj_server->ProcessMessage(pfrom, msg_type, vRecv), pfrom.GetId()); diff --git a/src/net_processing.h b/src/net_processing.h index f957a14011cb..8a4a4e7aba88 100644 --- a/src/net_processing.h +++ b/src/net_processing.h @@ -23,7 +23,7 @@ class CDSTXManager; class CGovernanceManager; class ChainstateManager; class CInv; -class CJContext; +class CJWalletManager; class CMasternodeMetaMan; class CMasternodeSync; class CSporkManager; @@ -65,8 +65,8 @@ class PeerManager : public CValidationInterface, public NetEventsInterface const CActiveMasternodeManager* const mn_activeman, const std::unique_ptr& dmnman, const std::unique_ptr& active_ctx, - CJContext* const cj_ctx, const std::unique_ptr& llmq_ctx, - bool ignore_incoming_txs); + CJWalletManager* const cj_walletman, + const std::unique_ptr& llmq_ctx, bool ignore_incoming_txs); virtual ~PeerManager() { } /** diff --git a/src/node/context.cpp b/src/node/context.cpp index f63b1f4fca0a..a13ef83414e1 100644 --- a/src/node/context.cpp +++ b/src/node/context.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/node/context.h b/src/node/context.h index 8429e10daf57..15845e6ce2ce 100644 --- a/src/node/context.h +++ b/src/node/context.h @@ -23,7 +23,7 @@ class CChainstateHelper; class ChainstateManager; class CEvoDB; class CGovernanceManager; -class CJContext; +class CJWalletManager; class CMasternodeMetaMan; class CMasternodeSync; class CNetFulfilledRequestManager; @@ -81,6 +81,7 @@ struct NodeContext { //! Dash managers std::unique_ptr mn_activeman; std::unique_ptr cpoolman; + std::unique_ptr cj_walletman; std::unique_ptr dstxman; std::unique_ptr evodb; std::unique_ptr chain_helper; @@ -93,7 +94,6 @@ struct NodeContext { std::unique_ptr sporkman; //! Dash contexts std::unique_ptr active_ctx; - std::unique_ptr cj_ctx; std::unique_ptr llmq_ctx; //! Declare default constructor and destructor that are not inline, so code diff --git a/src/rpc/coinjoin.cpp b/src/rpc/coinjoin.cpp index 225936dae6db..7fe29ab4da85 100644 --- a/src/rpc/coinjoin.cpp +++ b/src/rpc/coinjoin.cpp @@ -2,8 +2,8 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include #include +#include #include #include #include @@ -15,7 +15,6 @@ #include #ifdef ENABLE_WALLET -#include #include #include #endif // ENABLE_WALLET @@ -473,8 +472,8 @@ static RPCHelpMan getcoinjoininfo() #ifdef ENABLE_WALLET CCoinJoinClientOptions::GetJsonInfo(obj); - if (node.cj_ctx) { - if (auto queue_size = node.cj_ctx->getQueueSize()) { + if (node.cj_walletman) { + if (auto queue_size = node.cj_walletman->getQueueSize()) { obj.pushKV("queue_size", queue_size.value()); } } diff --git a/src/test/coinjoin_dstxmanager_tests.cpp b/src/test/coinjoin_dstxmanager_tests.cpp index 04e9ce5f93e7..24afd2f8fe69 100644 --- a/src/test/coinjoin_dstxmanager_tests.cpp +++ b/src/test/coinjoin_dstxmanager_tests.cpp @@ -7,7 +7,6 @@ #include #include #include -#include #include