diff --git a/src/Makefile.am b/src/Makefile.am index 639a7d9eff83..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 \ @@ -292,6 +292,7 @@ BITCOIN_CORE_H = \ memusage.h \ merkleblock.h \ messagesigner.h \ + msg_result.h \ net.h \ net_permissions.h \ net_processing.h \ @@ -485,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/client.cpp b/src/coinjoin/client.cpp index c08a647cac7e..88d5ee4f8187 100644 --- a/src/coinjoin/client.cpp +++ b/src/coinjoin/client.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -39,14 +38,12 @@ 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) { return {}; } - - if (m_is_masternode) return {}; if (!m_mn_sync.IsBlockchainSynced()) return {}; assert(m_mn_metaman.IsValid()); @@ -138,13 +135,12 @@ 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; } 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; @@ -169,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; @@ -386,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; @@ -498,8 +483,6 @@ bool CCoinJoinClientSession::SendDenominate(const std::vectorcs_wallet); @@ -682,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(); @@ -699,7 +679,6 @@ void CCoinJoinClientSession::CompletedTransaction(PoolMessage nMessageID) void CCoinJoinClientManager::UpdatedSuccessBlock() { - if (m_is_masternode) return; nCachedLastSuccessBlock = nCachedBlockHeight; } @@ -791,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()) { @@ -972,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()) { @@ -1001,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; @@ -1840,8 +1817,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(); @@ -1850,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; @@ -1904,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 cba6903030b3..222122b0329e 100644 --- a/src/coinjoin/client.h +++ b/src/coinjoin/client.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -29,7 +30,6 @@ class CMasternodeSync; class CNode; class CoinJoinWalletManager; class CTxMemPool; -class PeerManager; class UniValue; @@ -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); @@ -239,20 +233,19 @@ 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, 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(); }; @@ -269,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; @@ -304,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 deleted file mode 100644 index 52884e802b0e..000000000000 --- a/src/coinjoin/context.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) 2023-2025 The Dash Core developers -// Distributed under the MIT/X11 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 - -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) : -#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}, -#endif // ENABLE_WALLET - dstxman{std::make_unique()} -{} - -CJContext::~CJContext() {} diff --git a/src/coinjoin/context.h b/src/coinjoin/context.h deleted file mode 100644 index eb924f345772..000000000000 --- a/src/coinjoin/context.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2023-2025 The Dash Core developers -// 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 - -#if defined(HAVE_CONFIG_H) -#include -#endif - -#include - -class CActiveMasternodeManager; -class CDeterministicMNManager; -class CDSTXManager; -class ChainstateManager; -class CMasternodeMetaMan; -class CMasternodeSync; -class CTxMemPool; -namespace llmq { -class CInstantSendManager; -}; - -#ifdef ENABLE_WALLET -class CCoinJoinClientQueueManager; -class CoinJoinWalletManager; -#endif // ENABLE_WALLET - -struct CJContext { - 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(); - -#ifdef ENABLE_WALLET - // The main object for accessing mixing - 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/coinjoin/interfaces.cpp b/src/coinjoin/interfaces.cpp index 98091b694c12..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: - CoinJoinWalletManager& walletman() + CJWalletManager& manager() { - return *Assert(Assert(m_node.cj_ctx)->walletman); + return *Assert(m_node.cj_walletman); } 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/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/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/coinjoin/walletman.cpp b/src/coinjoin/walletman.cpp new file mode 100644 index 000000000000..50b552d766fb --- /dev/null +++ b/src/coinjoin/walletman.cpp @@ -0,0 +1,163 @@ +// Copyright (c) 2023-2025 The Dash Core developers +// 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 + +#ifdef ENABLE_WALLET +#include +#endif // ENABLE_WALLET + +#include + +#ifdef ENABLE_WALLET +class CJWalletManagerImpl final : public CJWalletManager +{ +public: + 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; + +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() 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; + + CoinJoinWalletManager walletman; + const std::unique_ptr queueman; +}; + +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 CJWalletManagerImpl::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)), + std::chrono::seconds{1}); +} + +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; + + walletman.ForEachCJClientMan( + [&pindexNew](std::unique_ptr& clientman) { clientman->UpdatedBlockTip(pindexNew); }); +} + +bool CJWalletManagerImpl::hasQueue(const uint256& hash) const +{ + if (queueman) { + return queueman->HasQueue(hash); + } + return false; +} + +CCoinJoinClientManager* CJWalletManagerImpl::getClient(const std::string& name) +{ + return walletman.Get(name); +} + +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); + }); + if (queueman) { + return queueman->ProcessMessage(pfrom.GetId(), connman, msg_type, vRecv); + } + return {}; +} + +std::optional CJWalletManagerImpl::getQueueFromHash(const uint256& hash) const +{ + if (queueman) { + return queueman->GetQueueFromHash(hash); + } + return std::nullopt; +} + +std::optional CJWalletManagerImpl::getQueueSize() const +{ + if (queueman) { + return queueman->GetQueueSize(); + } + return std::nullopt; +} + +std::vector CJWalletManagerImpl::getMixingMasternodes() +{ + std::vector ret{}; + walletman.ForEachCJClientMan( + [&](const std::unique_ptr& clientman) { clientman->GetMixingMasternodesInfo(ret); }); + return ret; +} + +void CJWalletManagerImpl::addWallet(const std::shared_ptr& wallet) +{ + walletman.Add(wallet); +} + +void CJWalletManagerImpl::flushWallet(const std::string& name) +{ + walletman.Flush(name); +} + +void CJWalletManagerImpl::removeWallet(const std::string& name) +{ + walletman.Remove(name); +} +#endif // ENABLE_WALLET + +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); +#else + // Cannot be constructed if wallet support isn't built + return nullptr; +#endif // ENABLE_WALLET +} diff --git a/src/coinjoin/walletman.h b/src/coinjoin/walletman.h new file mode 100644 index 000000000000..720a4bdf2f81 --- /dev/null +++ b/src/coinjoin/walletman.h @@ -0,0 +1,66 @@ +// Copyright (c) 2023-2025 The Dash Core developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_COINJOIN_WALLETMAN_H +#define BITCOIN_COINJOIN_WALLETMAN_H + +#include +#include + +#include + +#include +#include + +class CBlockIndex; +class CChainState; +class CCoinJoinClientManager; +class CCoinJoinQueue; +class CConnman; +class CDataStream; +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 + +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 ~CJWalletManager() = default; + +public: + virtual void Schedule(CConnman& connman, CScheduler& scheduler) = 0; + +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() = 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 + virtual void UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, + bool fInitialDownload) override = 0; +}; + +#endif // BITCOIN_COINJOIN_WALLETMAN_H diff --git a/src/dsnotificationinterface.cpp b/src/dsnotificationinterface.cpp index 484a564039ab..1a1faa969563 100644 --- a/src/dsnotificationinterface.cpp +++ b/src/dsnotificationinterface.cpp @@ -2,39 +2,40 @@ // 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 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& 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) +{ +} void CDSNotificationInterface::InitializeCurrentBlockTip() { @@ -44,9 +45,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 +56,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,17 +72,12 @@ void CDSNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, con if (fInitialDownload) return; - m_cj_ctx->dstxman->UpdatedBlockTip(pindexNew, *m_llmq_ctx->clhandler, m_mn_sync); -#ifdef ENABLE_WALLET - m_cj_ctx->walletman->ForEachCJClientMan( - [&pindexNew](std::unique_ptr& clientman) { clientman->UpdatedBlockTip(pindexNew); }); -#endif // ENABLE_WALLET + m_dstxman.UpdatedBlockTip(pindexNew, *Assert(m_llmq_ctx)->clhandler, m_mn_sync); 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); @@ -97,37 +87,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 +123,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..52cf0b2f62af 100644 --- a/src/dsnotificationinterface.h +++ b/src/dsnotificationinterface.h @@ -8,23 +8,23 @@ #include class CConnman; +class CDSTXManager; class CDeterministicMNManager; class CGovernanceManager; class ChainstateManager; class CMasternodeSync; -struct CJContext; struct LLMQContext; class CDSNotificationInterface : public CValidationInterface { public: explicit 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); virtual ~CDSNotificationInterface() = default; // a small helper to initialize current block height in sub-modules on startup @@ -46,12 +46,12 @@ class CDSNotificationInterface : public CValidationInterface private: CConnman& m_connman; + CDSTXManager& m_dstxman; CMasternodeSync& m_mn_sync; CGovernanceManager& m_govman; 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/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/init.cpp b/src/init.cpp index 0753588739f1..6f7a09542a8a 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -78,8 +78,8 @@ #include #include -#include #include +#include #include #include #include @@ -325,6 +325,15 @@ void PrepareShutdown(NodeContext& node) g_active_notification_interface.reset(); } + if (node.cj_walletman) { + UnregisterValidationInterface(node.cj_walletman.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,18 +385,14 @@ 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(); // 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(); GetMainSignals().UnregisterBackgroundSignalScheduler(); @@ -2131,36 +2136,42 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) ChainstateManager& chainman = *Assert(node.chainman); + assert(!node.dstxman); + node.dstxman = std::make_unique(); + + assert(!node.cj_walletman); + if (!node.mn_activeman) { + 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_walletman) { + RegisterValidationInterface(node.cj_walletman.get()); + } + 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); + node.active_ctx, node.cj_walletman.get(), 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 ); 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); @@ -2257,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), 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_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()) { @@ -2267,11 +2278,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_walletman) { + node.cj_walletman->Schedule(*node.connman, *node.scheduler); } if (::g_stats_client->active()) { 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/masternode/utils.cpp b/src/masternode/utils.cpp index 2988b3ffe801..4ed51031db27 100644 --- a/src/masternode/utils.cpp +++ b/src/masternode/utils.cpp @@ -3,30 +3,21 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include -#include -#ifdef ENABLE_WALLET -#include -#endif -#include #include #include #include -#include -void CMasternodeUtils::DoMaintenance(CConnman& connman, CDeterministicMNManager& dmnman, - const CMasternodeSync& mn_sync, const CJContext& cj_ctx) +#include +#include +#include + +void CMasternodeUtils::DoMaintenance(CConnman& connman, CDeterministicMNManager& dmnman, const CMasternodeSync& mn_sync, + CJWalletManager* const cj_walletman) { 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 +36,7 @@ void CMasternodeUtils::DoMaintenance(CConnman& connman, CDeterministicMNManager& return; } + 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 @@ -75,12 +67,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..e1e7b586a912 100644 --- a/src/masternode/utils.h +++ b/src/masternode/utils.h @@ -8,13 +8,13 @@ class CConnman; class CDeterministicMNManager; class CMasternodeSync; -struct CJContext; +class CJWalletManager; 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, + CJWalletManager* const cj_walletman); }; #endif // BITCOIN_MASTERNODE_UTILS_H 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 63d5aac9657b..97fec4a10733 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 -#ifdef ENABLE_WALLET -#include -#endif // ENABLE_WALLET -#include -#include +#include +#include #include +#include +#include #include #include #include -#include +#include #include +#include #include #include #include @@ -77,9 +59,23 @@ #include #include #include - +#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include + using node::ReadBlockFromDisk; using node::fImporting; using node::fPruneMode; @@ -592,15 +588,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, CJWalletManager* const cj_walletman, + 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,12 +782,14 @@ 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; 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 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; @@ -1960,38 +1955,38 @@ 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, + CJWalletManager* const cj_walletman, 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_walletman, 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) + CJWalletManager* const cj_walletman, + 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), 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), @@ -2242,7 +2237,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)); } @@ -2280,11 +2275,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_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); } @@ -2459,7 +2450,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 +2742,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)); @@ -2890,11 +2881,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_walletman && !opt_dsq.has_value()) { + opt_dsq = m_cj_walletman->getQueueFromHash(inv.hash); } -#endif if (opt_dsq.has_value()) { m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::DSQUEUE, *opt_dsq)); push = true; @@ -3522,6 +3511,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)) { @@ -4565,7 +4557,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 +4589,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()); @@ -5367,14 +5359,9 @@ void PeerManagerImpl::ProcessMessage( if (found) { //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()); + if (m_cj_walletman) { + PostProcessMessage(m_cj_walletman->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()); } @@ -6205,7 +6192,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 +6267,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..8a4a4e7aba88 100644 --- a/src/net_processing.h +++ b/src/net_processing.h @@ -10,23 +10,26 @@ #include #include +#include + #include -class CActiveMasternodeManager; class AddrMan; -class CTxMemPool; +class CActiveMasternodeManager; class CCoinJoinQueue; -class CDeterministicMNManager; -class CMasternodeMetaMan; -class CMasternodeSync; -class ChainstateManager; class CCoinJoinServer; +class CDeterministicMNManager; +class CDSTXManager; class CGovernanceManager; +class ChainstateManager; class CInv; +class CJWalletManager; +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 */ @@ -56,13 +59,13 @@ 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, const std::unique_ptr& dmnman, const std::unique_ptr& active_ctx, - const std::unique_ptr& cj_ctx, + 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 e8407d8548f6..a13ef83414e1 100644 --- a/src/node/context.cpp +++ b/src/node/context.cpp @@ -6,7 +6,8 @@ #include #include -#include +#include +#include #include #include #include diff --git a/src/node/context.h b/src/node/context.h index fc04830e72d6..15845e6ce2ce 100644 --- a/src/node/context.h +++ b/src/node/context.h @@ -18,10 +18,12 @@ class CBlockPolicyEstimator; class CConnman; class CCreditPoolManager; class CDeterministicMNManager; +class CDSTXManager; class CChainstateHelper; class ChainstateManager; class CEvoDB; class CGovernanceManager; +class CJWalletManager; class CMasternodeMetaMan; class CMasternodeSync; class CNetFulfilledRequestManager; @@ -32,7 +34,6 @@ class CMNHFManager; class NetGroupManager; class PeerManager; struct ActiveContext; -struct CJContext; struct LLMQContext; namespace interfaces { @@ -80,6 +81,8 @@ 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; std::unique_ptr dmnman; @@ -91,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/protocol.h b/src/protocol.h index 75456d161fb7..ed1b71705b80 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -7,7 +7,6 @@ #define BITCOIN_PROTOCOL_H #include -#include #include #include #include @@ -568,60 +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_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/rpc/coinjoin.cpp b/src/rpc/coinjoin.cpp index ef578d726101..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,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_walletman) { + if (auto queue_size = node.cj_walletman->getQueueSize()) { + obj.pushKV("queue_size", queue_size.value()); + } } const std::shared_ptr wallet = GetWalletForJSONRPCRequest(request); 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/src/test/coinjoin_dstxmanager_tests.cpp b/src/test/coinjoin_dstxmanager_tests.cpp index bbe5c94c74ee..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