diff --git a/src/coinjoin/client.cpp b/src/coinjoin/client.cpp index 007bbe55f200..d20d5e4a52bf 100644 --- a/src/coinjoin/client.cpp +++ b/src/coinjoin/client.cpp @@ -42,7 +42,7 @@ PeerMsgRet CCoinJoinClientQueueManager::ProcessMessage(const CNode& peer, std::s PeerMsgRet CCoinJoinClientQueueManager::ProcessDSQueue(const CNode& peer, CDataStream& vRecv) { - assert(::mmetaman->IsValid()); + assert(m_mn_metaman.IsValid()); CCoinJoinQueue dsq; vRecv >> dsq; @@ -105,18 +105,18 @@ PeerMsgRet CCoinJoinClientQueueManager::ProcessDSQueue(const CNode& peer, CDataS dmn->pdmnState->addr.ToString()); return {}; } else { - int64_t nLastDsq = mmetaman->GetMetaInfo(dmn->proTxHash)->GetLastDsq(); - int64_t nDsqThreshold = mmetaman->GetDsqThreshold(dmn->proTxHash, tip_mn_list.GetValidMNsCount()); + int64_t nLastDsq = m_mn_metaman.GetMetaInfo(dmn->proTxHash)->GetLastDsq(); + int64_t nDsqThreshold = m_mn_metaman.GetDsqThreshold(dmn->proTxHash, tip_mn_list.GetValidMNsCount()); LogPrint(BCLog::COINJOIN, "DSQUEUE -- nLastDsq: %d nDsqThreshold: %d nDsqCount: %d\n", nLastDsq, - nDsqThreshold, mmetaman->GetDsqCount()); + nDsqThreshold, m_mn_metaman.GetDsqCount()); // don't allow a few nodes to dominate the queuing process - if (nLastDsq != 0 && nDsqThreshold > mmetaman->GetDsqCount()) { + if (nLastDsq != 0 && nDsqThreshold > m_mn_metaman.GetDsqCount()) { LogPrint(BCLog::COINJOIN, "DSQUEUE -- Masternode %s is sending too many dsq messages\n", dmn->proTxHash.ToString()); return {}; } - mmetaman->AllowMixing(dmn->proTxHash); + m_mn_metaman.AllowMixing(dmn->proTxHash); LogPrint(BCLog::COINJOIN, "DSQUEUE -- new CoinJoin queue (%s) from masternode %s\n", dsq.ToString(), dmn->pdmnState->addr.ToString()); @@ -155,12 +155,13 @@ void CCoinJoinClientManager::ProcessMessage(CNode& peer, CConnman& connman, cons } } -CCoinJoinClientSession::CCoinJoinClientSession(CWallet& wallet, CoinJoinWalletManager& walletman, CDeterministicMNManager& dmnman, const CMasternodeSync& mn_sync, - const std::unique_ptr& queueman) : +CCoinJoinClientSession::CCoinJoinClientSession(CWallet& wallet, CoinJoinWalletManager& walletman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, + const CMasternodeSync& mn_sync, const std::unique_ptr& queueman) : m_wallet(wallet), m_walletman(walletman), m_manager(*Assert(walletman.Get(wallet.GetName()))), m_dmnman(dmnman), + m_mn_metaman(mn_metaman), m_mn_sync(mn_sync), m_queueman(queueman) {} @@ -990,7 +991,7 @@ bool CCoinJoinClientManager::DoAutomaticDenominating(CConnman& connman, CTxMemPo AssertLockNotHeld(cs_deqsessions); LOCK(cs_deqsessions); if (int(deqSessions.size()) < CCoinJoinClientOptions::GetSessions()) { - deqSessions.emplace_back(m_wallet, m_walletman, m_dmnman, m_mn_sync, m_queueman); + deqSessions.emplace_back(m_wallet, m_walletman, m_dmnman, m_mn_metaman, m_mn_sync, m_queueman); } for (auto& session : deqSessions) { if (!CheckAutomaticBackup()) return false; @@ -1119,7 +1120,7 @@ bool CCoinJoinClientSession::JoinExistingQueue(CAmount nBalanceNeedsAnonymized, bool CCoinJoinClientSession::StartNewQueue(CAmount nBalanceNeedsAnonymized, CConnman& connman) { - assert(::mmetaman->IsValid()); + assert(m_mn_metaman.IsValid()); if (!CCoinJoinClientOptions::IsEnabled()) return false; if (nBalanceNeedsAnonymized <= 0) return false; @@ -1156,13 +1157,13 @@ bool CCoinJoinClientSession::StartNewQueue(CAmount nBalanceNeedsAnonymized, CCon continue; } - int64_t nLastDsq = mmetaman->GetMetaInfo(dmn->proTxHash)->GetLastDsq(); - int64_t nDsqThreshold = mmetaman->GetDsqThreshold(dmn->proTxHash, nMnCount); - if (nLastDsq != 0 && nDsqThreshold > mmetaman->GetDsqCount()) { + int64_t nLastDsq = m_mn_metaman.GetMetaInfo(dmn->proTxHash)->GetLastDsq(); + int64_t nDsqThreshold = m_mn_metaman.GetDsqThreshold(dmn->proTxHash, nMnCount); + if (nLastDsq != 0 && nDsqThreshold > m_mn_metaman.GetDsqCount()) { WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::StartNewQueue -- Too early to mix on this masternode!" /* Continued */ " masternode=%s addr=%s nLastDsq=%d nDsqThreshold=%d nDsqCount=%d\n", dmn->proTxHash.ToString(), dmn->pdmnState->addr.ToString(), nLastDsq, - nDsqThreshold, mmetaman->GetDsqCount()); + nDsqThreshold, m_mn_metaman.GetDsqCount()); nTries++; continue; } @@ -1890,10 +1891,9 @@ void CCoinJoinClientManager::GetJsonInfo(UniValue& obj) const } void CoinJoinWalletManager::Add(CWallet& wallet) { - assert(::masternodeSync != nullptr); m_wallet_manager_map.try_emplace( wallet.GetName(), - std::make_unique(wallet, *this, m_dmnman, m_mn_sync, m_queueman) + std::make_unique(wallet, *this, m_dmnman, m_mn_metaman, m_mn_sync, m_queueman) ); g_wallet_init_interface.InitCoinJoinSettings(*this); } diff --git a/src/coinjoin/client.h b/src/coinjoin/client.h index 99564414a99a..f07c4b7d0603 100644 --- a/src/coinjoin/client.h +++ b/src/coinjoin/client.h @@ -21,9 +21,10 @@ class CCoinJoinClientQueueManager; class CConnman; class CDeterministicMN; class CDeterministicMNManager; -class CoinJoinWalletManager; class CNode; +class CMasternodeMetaMan; class CMasternodeSync; +class CoinJoinWalletManager; class CTxMemPool; class UniValue; @@ -72,9 +73,10 @@ class CoinJoinWalletManager { using wallet_name_cjman_map = std::map>; public: - CoinJoinWalletManager(CConnman& connman, CDeterministicMNManager& dmnman, CTxMemPool& mempool, const CMasternodeSync& mn_sync, - const std::unique_ptr& queueman) - : m_connman(connman), m_dmnman(dmnman), m_mempool(mempool), m_mn_sync(mn_sync), m_queueman(queueman) {} + CoinJoinWalletManager(CConnman& connman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, CTxMemPool& mempool, + const CMasternodeSync& mn_sync, const std::unique_ptr& queueman) + : m_connman(connman), m_dmnman(dmnman), m_mn_metaman(mn_metaman), m_mempool(mempool), m_mn_sync(mn_sync), m_queueman(queueman) {} + ~CoinJoinWalletManager() { for (auto& [wallet_name, cj_man] : m_wallet_manager_map) { cj_man.reset(); @@ -94,6 +96,7 @@ class CoinJoinWalletManager { private: CConnman& m_connman; CDeterministicMNManager& m_dmnman; + CMasternodeMetaMan& m_mn_metaman; CTxMemPool& m_mempool; const CMasternodeSync& m_mn_sync; const std::unique_ptr& m_queueman; @@ -108,6 +111,7 @@ class CCoinJoinClientSession : public CCoinJoinBaseSession CoinJoinWalletManager& m_walletman; CCoinJoinClientManager& m_manager; CDeterministicMNManager& m_dmnman; + CMasternodeMetaMan& m_mn_metaman; const CMasternodeSync& m_mn_sync; const std::unique_ptr& m_queueman; @@ -157,8 +161,8 @@ class CCoinJoinClientSession : public CCoinJoinBaseSession void SetNull() override EXCLUSIVE_LOCKS_REQUIRED(cs_coinjoin); public: - explicit CCoinJoinClientSession(CWallet& wallet, CoinJoinWalletManager& walletman, CDeterministicMNManager& dmnman, const CMasternodeSync& mn_sync, - const std::unique_ptr& queueman); + explicit CCoinJoinClientSession(CWallet& wallet, CoinJoinWalletManager& walletman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, + const CMasternodeSync& mn_sync, const std::unique_ptr& queueman); void ProcessMessage(CNode& peer, CConnman& connman, const CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv); @@ -191,13 +195,14 @@ class CCoinJoinClientQueueManager : public CCoinJoinBaseManager CConnman& connman; CoinJoinWalletManager& m_walletman; CDeterministicMNManager& m_dmnman; + CMasternodeMetaMan& m_mn_metaman; const CMasternodeSync& m_mn_sync; mutable Mutex cs_ProcessDSQueue; public: explicit CCoinJoinClientQueueManager(CConnman& _connman, CoinJoinWalletManager& walletman, CDeterministicMNManager& dmnman, - const CMasternodeSync& mn_sync) : - connman(_connman), m_walletman(walletman), m_dmnman(dmnman), m_mn_sync(mn_sync) {}; + CMasternodeMetaMan& mn_metaman, const CMasternodeSync& mn_sync) : + connman(_connman), m_walletman(walletman), m_dmnman(dmnman), m_mn_metaman(mn_metaman), m_mn_sync(mn_sync) {}; PeerMsgRet ProcessMessage(const CNode& peer, std::string_view msg_type, CDataStream& vRecv) LOCKS_EXCLUDED(cs_vecqueue); PeerMsgRet ProcessDSQueue(const CNode& peer, CDataStream& vRecv); @@ -212,6 +217,7 @@ class CCoinJoinClientManager CWallet& m_wallet; CoinJoinWalletManager& m_walletman; CDeterministicMNManager& m_dmnman; + CMasternodeMetaMan& m_mn_metaman; const CMasternodeSync& m_mn_sync; const std::unique_ptr& m_queueman; @@ -244,9 +250,10 @@ class CCoinJoinClientManager CCoinJoinClientManager(CCoinJoinClientManager const&) = delete; CCoinJoinClientManager& operator=(CCoinJoinClientManager const&) = delete; - explicit CCoinJoinClientManager(CWallet& wallet, CoinJoinWalletManager& walletman, CDeterministicMNManager& dmnman, const CMasternodeSync& mn_sync, + explicit CCoinJoinClientManager(CWallet& wallet, CoinJoinWalletManager& walletman, CDeterministicMNManager& dmnman, + CMasternodeMetaMan& mn_metaman, const CMasternodeSync& mn_sync, const std::unique_ptr& queueman) : - m_wallet(wallet), m_walletman(walletman), m_dmnman(dmnman), m_mn_sync(mn_sync), m_queueman(queueman) {} + m_wallet(wallet), m_walletman(walletman), m_dmnman(dmnman), m_mn_metaman(mn_metaman), m_mn_sync(mn_sync), m_queueman(queueman) {} void ProcessMessage(CNode& peer, CConnman& connman, const CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv) LOCKS_EXCLUDED(cs_deqsessions); diff --git a/src/coinjoin/context.cpp b/src/coinjoin/context.cpp index 286a5928cadf..46ec89a156c1 100644 --- a/src/coinjoin/context.cpp +++ b/src/coinjoin/context.cpp @@ -13,14 +13,15 @@ #endif // ENABLE_WALLET #include -CJContext::CJContext(CChainState& chainstate, CConnman& connman, CDeterministicMNManager& dmnman, CTxMemPool& mempool, - const CActiveMasternodeManager* const mn_activeman, const CMasternodeSync& mn_sync, bool relay_txes) : +CJContext::CJContext(CChainState& chainstate, CConnman& connman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, + CTxMemPool& mempool, const CActiveMasternodeManager* const mn_activeman, const CMasternodeSync& mn_sync, + bool relay_txes) : dstxman{std::make_unique()}, #ifdef ENABLE_WALLET - walletman{std::make_unique(connman, dmnman, mempool, mn_sync, queueman)}, - queueman {relay_txes ? std::make_unique(connman, *walletman, dmnman, mn_sync) : nullptr}, + walletman{std::make_unique(connman, dmnman, mn_metaman, mempool, mn_sync, queueman)}, + queueman {relay_txes ? std::make_unique(connman, *walletman, dmnman, mn_metaman, mn_sync) : nullptr}, #endif // ENABLE_WALLET - server{std::make_unique(chainstate, connman, dmnman, *dstxman, mempool, mn_activeman, mn_sync)} + server{std::make_unique(chainstate, connman, dmnman, *dstxman, mn_metaman, mempool, mn_activeman, mn_sync)} {} CJContext::~CJContext() {} diff --git a/src/coinjoin/context.h b/src/coinjoin/context.h index c3257447c606..881daed6d0cd 100644 --- a/src/coinjoin/context.h +++ b/src/coinjoin/context.h @@ -18,6 +18,7 @@ class CCoinJoinServer; class CConnman; class CDeterministicMNManager; class CDSTXManager; +class CMasternodeMetaMan; class CMasternodeSync; class CTxMemPool; @@ -29,8 +30,9 @@ class CoinJoinWalletManager; struct CJContext { CJContext() = delete; CJContext(const CJContext&) = delete; - CJContext(CChainState& chainstate, CConnman& connman, CDeterministicMNManager& dmnman, CTxMemPool& mempool, - const CActiveMasternodeManager* const mn_activeman, const CMasternodeSync& mn_sync, bool relay_txes); + CJContext(CChainState& chainstate, CConnman& connman, CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_metaman, + CTxMemPool& mempool, const CActiveMasternodeManager* const mn_activeman, const CMasternodeSync& mn_sync, + bool relay_txes); ~CJContext(); const std::unique_ptr dstxman; diff --git a/src/coinjoin/server.cpp b/src/coinjoin/server.cpp index d1d279a57097..250e965c6192 100644 --- a/src/coinjoin/server.cpp +++ b/src/coinjoin/server.cpp @@ -44,7 +44,7 @@ PeerMsgRet CCoinJoinServer::ProcessMessage(CNode& peer, std::string_view msg_typ void CCoinJoinServer::ProcessDSACCEPT(CNode& peer, CDataStream& vRecv) { assert(m_mn_activeman); - assert(::mmetaman->IsValid()); + assert(m_mn_metaman.IsValid()); if (IsSessionReady()) { // too many users in this session already, reject new ones @@ -81,9 +81,9 @@ void CCoinJoinServer::ProcessDSACCEPT(CNode& peer, CDataStream& vRecv) } } - int64_t nLastDsq = mmetaman->GetMetaInfo(dmn->proTxHash)->GetLastDsq(); - int64_t nDsqThreshold = mmetaman->GetDsqThreshold(dmn->proTxHash, mnList.GetValidMNsCount()); - if (nLastDsq != 0 && nDsqThreshold > mmetaman->GetDsqCount()) { + int64_t nLastDsq = m_mn_metaman.GetMetaInfo(dmn->proTxHash)->GetLastDsq(); + int64_t nDsqThreshold = m_mn_metaman.GetDsqThreshold(dmn->proTxHash, mnList.GetValidMNsCount()); + if (nLastDsq != 0 && nDsqThreshold > m_mn_metaman.GetDsqCount()) { if (fLogIPs) { LogPrint(BCLog::COINJOIN, "DSACCEPT -- last dsq too recent, must wait: peer=%d, addr=%s\n", peer.GetId(), peer.addr.ToString()); } else { @@ -111,7 +111,7 @@ void CCoinJoinServer::ProcessDSACCEPT(CNode& peer, CDataStream& vRecv) PeerMsgRet CCoinJoinServer::ProcessDSQUEUE(const CNode& peer, CDataStream& vRecv) { - assert(::mmetaman->IsValid()); + assert(m_mn_metaman.IsValid()); CCoinJoinQueue dsq; vRecv >> dsq; @@ -162,15 +162,15 @@ PeerMsgRet CCoinJoinServer::ProcessDSQUEUE(const CNode& peer, CDataStream& vRecv } if (!dsq.fReady) { - int64_t nLastDsq = mmetaman->GetMetaInfo(dmn->proTxHash)->GetLastDsq(); - int64_t nDsqThreshold = mmetaman->GetDsqThreshold(dmn->proTxHash, tip_mn_list.GetValidMNsCount()); - LogPrint(BCLog::COINJOIN, "DSQUEUE -- nLastDsq: %d nDsqThreshold: %d nDsqCount: %d\n", nLastDsq, nDsqThreshold, mmetaman->GetDsqCount()); + int64_t nLastDsq = m_mn_metaman.GetMetaInfo(dmn->proTxHash)->GetLastDsq(); + int64_t nDsqThreshold = m_mn_metaman.GetDsqThreshold(dmn->proTxHash, tip_mn_list.GetValidMNsCount()); + LogPrint(BCLog::COINJOIN, "DSQUEUE -- nLastDsq: %d nDsqThreshold: %d nDsqCount: %d\n", nLastDsq, nDsqThreshold, m_mn_metaman.GetDsqCount()); //don't allow a few nodes to dominate the queuing process - if (nLastDsq != 0 && nDsqThreshold > mmetaman->GetDsqCount()) { + if (nLastDsq != 0 && nDsqThreshold > m_mn_metaman.GetDsqCount()) { LogPrint(BCLog::COINJOIN, "DSQUEUE -- Masternode %s is sending too many dsq messages\n", dmn->pdmnState->addr.ToString()); return {}; } - mmetaman->AllowMixing(dmn->proTxHash); + m_mn_metaman.AllowMixing(dmn->proTxHash); LogPrint(BCLog::COINJOIN, "DSQUEUE -- new CoinJoin queue (%s) from masternode %s\n", dsq.ToString(), dmn->pdmnState->addr.ToString()); diff --git a/src/coinjoin/server.h b/src/coinjoin/server.h index 3f0df1454351..9913224c28f4 100644 --- a/src/coinjoin/server.h +++ b/src/coinjoin/server.h @@ -15,6 +15,7 @@ class CCoinJoinServer; class CDataStream; class CDeterministicMNManager; class CDSTXManager; +class CMasternodeMetaMan; class CNode; class CTxMemPool; @@ -29,6 +30,7 @@ class CCoinJoinServer : public CCoinJoinBaseSession, public CCoinJoinBaseManager CConnman& connman; CDeterministicMNManager& m_dmnman; CDSTXManager& m_dstxman; + CMasternodeMetaMan& m_mn_metaman; CTxMemPool& mempool; const CActiveMasternodeManager* const m_mn_activeman; const CMasternodeSync& m_mn_sync; @@ -87,11 +89,13 @@ class CCoinJoinServer : public CCoinJoinBaseSession, public CCoinJoinBaseManager public: explicit CCoinJoinServer(CChainState& chainstate, CConnman& _connman, CDeterministicMNManager& dmnman, CDSTXManager& dstxman, - CTxMemPool& mempool, const CActiveMasternodeManager* const mn_activeman, const CMasternodeSync& mn_sync) : + CMasternodeMetaMan& mn_metaman, CTxMemPool& mempool, const CActiveMasternodeManager* const mn_activeman, + const CMasternodeSync& mn_sync) : m_chainstate(chainstate), connman(_connman), m_dmnman(dmnman), m_dstxman(dstxman), + m_mn_metaman(mn_metaman), mempool(mempool), m_mn_activeman(mn_activeman), m_mn_sync(mn_sync), diff --git a/src/dsnotificationinterface.cpp b/src/dsnotificationinterface.cpp index 4bb1010a03b4..ac0f116da857 100644 --- a/src/dsnotificationinterface.cpp +++ b/src/dsnotificationinterface.cpp @@ -26,12 +26,14 @@ CDSNotificationInterface::CDSNotificationInterface(CConnman& connman, CMasternodeSync& mn_sync, CGovernanceManager& govman, + const CActiveMasternodeManager* const mn_activeman, const std::unique_ptr& dmnman, const std::unique_ptr& llmq_ctx, const std::unique_ptr& cj_ctx) : m_connman(connman), m_mn_sync(mn_sync), m_govman(govman), + m_mn_activeman(mn_activeman), m_dmnman(dmnman), m_llmq_ctx(llmq_ctx), m_cj_ctx(cj_ctx) {} @@ -94,7 +96,7 @@ void CDSNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, con m_llmq_ctx->qdkgsman->UpdatedBlockTip(pindexNew, fInitialDownload); m_llmq_ctx->ehfSignalsHandler->UpdatedBlockTip(pindexNew); - if (!fDisableGovernance) m_govman.UpdatedBlockTip(pindexNew, m_connman); + if (!fDisableGovernance) m_govman.UpdatedBlockTip(pindexNew, m_connman, m_mn_activeman); } void CDSNotificationInterface::TransactionAddedToMempool(const CTransactionRef& ptx, int64_t nAcceptTime) diff --git a/src/dsnotificationinterface.h b/src/dsnotificationinterface.h index 4f982720d2b5..35092ea11a1c 100644 --- a/src/dsnotificationinterface.h +++ b/src/dsnotificationinterface.h @@ -7,6 +7,7 @@ #include +class CActiveMasternodeManager; class CConnman; class CDeterministicMNManager; class CGovernanceManager; @@ -20,6 +21,7 @@ class CDSNotificationInterface : public CValidationInterface explicit CDSNotificationInterface(CConnman& connman, CMasternodeSync& mn_sync, CGovernanceManager& govman, + const CActiveMasternodeManager* const mn_activeman, const std::unique_ptr& dmnman, const std::unique_ptr& llmq_ctx, const std::unique_ptr& cj_ctx); @@ -47,6 +49,7 @@ class CDSNotificationInterface : public CValidationInterface CMasternodeSync& m_mn_sync; CGovernanceManager& m_govman; + const CActiveMasternodeManager* const m_mn_activeman; const std::unique_ptr& m_dmnman; const std::unique_ptr& m_llmq_ctx; const std::unique_ptr& m_cj_ctx; diff --git a/src/evo/deterministicmns.cpp b/src/evo/deterministicmns.cpp index dff76f4fb537..d02c28cdffbe 100644 --- a/src/evo/deterministicmns.cpp +++ b/src/evo/deterministicmns.cpp @@ -27,8 +27,6 @@ static const std::string DB_LIST_SNAPSHOT = "dmn_S3"; static const std::string DB_LIST_DIFF = "dmn_D3"; -std::unique_ptr deterministicMNManager; - uint64_t CDeterministicMN::GetInternalId() const { // can't get it if it wasn't set yet diff --git a/src/evo/deterministicmns.h b/src/evo/deterministicmns.h index 9f56724814bd..df6072c4bc6a 100644 --- a/src/evo/deterministicmns.h +++ b/src/evo/deterministicmns.h @@ -637,6 +637,4 @@ bool CheckProUpServTx(CDeterministicMNManager& dmnman, const CTransaction& tx, g bool CheckProUpRegTx(CDeterministicMNManager& dmnman, const CTransaction& tx, gsl::not_null pindexPrev, TxValidationState& state, const CCoinsViewCache& view, bool check_sigs); bool CheckProUpRevTx(CDeterministicMNManager& dmnman, const CTransaction& tx, gsl::not_null pindexPrev, TxValidationState& state, bool check_sigs); -extern std::unique_ptr deterministicMNManager; - #endif // BITCOIN_EVO_DETERMINISTICMNS_H diff --git a/src/evo/mnauth.cpp b/src/evo/mnauth.cpp index 032492ebc6ad..6c61dc5af176 100644 --- a/src/evo/mnauth.cpp +++ b/src/evo/mnauth.cpp @@ -19,12 +19,13 @@ #include #include -void CMNAuth::PushMNAUTH(CNode& peer, CConnman& connman, const CBlockIndex* tip) +void CMNAuth::PushMNAUTH(CNode& peer, CConnman& connman, const CActiveMasternodeManager& mn_activeman, + const CBlockIndex* tip) { - if (!fMasternodeMode) return; + assert(fMasternodeMode); CMNAuth mnauth; - if (::activeMasternodeManager->GetProTxHash().IsNull()) { + if (mn_activeman.GetProTxHash().IsNull()) { return; } @@ -43,7 +44,7 @@ void CMNAuth::PushMNAUTH(CNode& peer, CConnman& connman, const CBlockIndex* tip) nOurNodeVersion = gArgs.GetArg("-pushversion", PROTOCOL_VERSION); } const bool is_basic_scheme_active{DeploymentActiveAfter(tip, Params().GetConsensus(), Consensus::DEPLOYMENT_V19)}; - auto pk = ::activeMasternodeManager->GetPubKey(); + auto pk = mn_activeman.GetPubKey(); const CBLSPublicKeyVersionWrapper pubKey(pk, !is_basic_scheme_active); uint256 signHash = [&]() { if (peer.nVersion < MNAUTH_NODE_VER_VERSION || nOurNodeVersion < MNAUTH_NODE_VER_VERSION) { @@ -53,19 +54,20 @@ void CMNAuth::PushMNAUTH(CNode& peer, CConnman& connman, const CBlockIndex* tip) } }(); - mnauth.proRegTxHash = ::activeMasternodeManager->GetProTxHash(); + mnauth.proRegTxHash = mn_activeman.GetProTxHash(); - mnauth.sig = ::activeMasternodeManager->Sign(signHash); + mnauth.sig = mn_activeman.Sign(signHash); LogPrint(BCLog::NET_NETCONN, "CMNAuth::%s -- Sending MNAUTH, peer=%d\n", __func__, peer.GetId()); connman.PushMessage(&peer, CNetMsgMaker(peer.GetCommonVersion()).Make(NetMsgType::MNAUTH, mnauth)); } -PeerMsgRet CMNAuth::ProcessMessage(CNode& peer, CConnman& connman, const CDeterministicMNList& tip_mn_list, std::string_view msg_type, CDataStream& vRecv) +PeerMsgRet CMNAuth::ProcessMessage(CNode& peer, CConnman& connman, CMasternodeMetaMan& mn_metaman, const CActiveMasternodeManager* const mn_activeman, + const CMasternodeSync& mn_sync, const CDeterministicMNList& tip_mn_list, std::string_view msg_type, CDataStream& vRecv) { - assert(::mmetaman->IsValid()); + assert(mn_metaman.IsValid()); - if (msg_type != NetMsgType::MNAUTH || !::masternodeSync->IsBlockchainSynced()) { + if (msg_type != NetMsgType::MNAUTH || !mn_sync.IsBlockchainSynced()) { // we can't verify MNAUTH messages when we don't have the latest MN list return {}; } @@ -123,7 +125,7 @@ PeerMsgRet CMNAuth::ProcessMessage(CNode& peer, CConnman& connman, const CDeterm } if (!peer.IsInboundConn()) { - mmetaman->GetMetaInfo(mnauth.proRegTxHash)->SetLastOutboundSuccess(GetTime().count()); + mn_metaman.GetMetaInfo(mnauth.proRegTxHash)->SetLastOutboundSuccess(GetTime().count()); if (peer.m_masternode_probe_connection) { LogPrint(BCLog::NET_NETCONN, "CMNAuth::ProcessMessage -- Masternode probe successful for %s, disconnecting. peer=%d\n", mnauth.proRegTxHash.ToString(), peer.GetId()); @@ -133,7 +135,7 @@ PeerMsgRet CMNAuth::ProcessMessage(CNode& peer, CConnman& connman, const CDeterm } const uint256 myProTxHash = fMasternodeMode ? - ::activeMasternodeManager->GetProTxHash() : + Assert(mn_activeman)->GetProTxHash() : uint256(); connman.ForEachNode([&](CNode* pnode2) { diff --git a/src/evo/mnauth.h b/src/evo/mnauth.h index e4311e3c0eff..211dae0cf20c 100644 --- a/src/evo/mnauth.h +++ b/src/evo/mnauth.h @@ -9,6 +9,7 @@ #include #include +class CActiveMasternodeManager; class CBlockIndex; class CConnman; class CDataStream; @@ -16,6 +17,8 @@ class CDeterministicMN; class CDeterministicMNList; class CDeterministicMNListDiff; class CDeterministicMNManager; +class CMasternodeMetaMan; +class CMasternodeSync; class CNode; class UniValue; @@ -48,13 +51,15 @@ class CMNAuth READWRITE(obj.proRegTxHash, obj.sig); } - static void PushMNAUTH(CNode& peer, CConnman& connman, const CBlockIndex* tip); + static void PushMNAUTH(CNode& peer, CConnman& connman, const CActiveMasternodeManager& mn_activeman, + const CBlockIndex* tip); /** * @pre CMasternodeMetaMan's database must be successfully loaded before * attempting to call this function regardless of sync state */ - static PeerMsgRet ProcessMessage(CNode& peer, CConnman& connman, const CDeterministicMNList& tip_mn_list, std::string_view msg_type, CDataStream& vRecv); + static PeerMsgRet ProcessMessage(CNode& peer, CConnman& connman, CMasternodeMetaMan& mn_metaman, const CActiveMasternodeManager* const mn_activeman, + const CMasternodeSync& mn_sync, const CDeterministicMNList& tip_mn_list, std::string_view msg_type, CDataStream& vRecv); static void NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff, CConnman& connman); }; diff --git a/src/governance/governance.cpp b/src/governance/governance.cpp index fab40235983f..021411112768 100644 --- a/src/governance/governance.cpp +++ b/src/governance/governance.cpp @@ -43,10 +43,14 @@ GovernanceStore::GovernanceStore() : { } -CGovernanceManager::CGovernanceManager(CNetFulfilledRequestManager& netfulfilledman, const std::unique_ptr& dmnman) : +CGovernanceManager::CGovernanceManager(CMasternodeMetaMan& mn_metaman, CNetFulfilledRequestManager& netfulfilledman, + const std::unique_ptr& dmnman, + const std::unique_ptr& mn_sync) : m_db{std::make_unique("governance.dat", "magicGovernanceCache")}, + m_mn_metaman{mn_metaman}, m_netfulfilledman{netfulfilledman}, m_dmnman{dmnman}, + m_mn_sync{mn_sync}, nTimeLastDiff(0), nCachedBlockHeight(0), setRequestedObjects(), @@ -118,7 +122,7 @@ bool CGovernanceManager::SerializeVoteForHash(const uint256& nHash, CDataStream& PeerMsgRet CGovernanceManager::ProcessMessage(CNode& peer, CConnman& connman, std::string_view msg_type, CDataStream& vRecv) { if (fDisableGovernance) return {}; - if (::masternodeSync == nullptr || !::masternodeSync->IsBlockchainSynced()) return {}; + if (m_mn_sync == nullptr || !m_mn_sync->IsBlockchainSynced()) return {}; const auto tip_mn_list = Assert(m_dmnman)->GetListAtChainTip(); // ANOTHER USER IS ASKING US TO HELP THEM SYNC GOVERNANCE OBJECT DATA @@ -126,7 +130,7 @@ PeerMsgRet CGovernanceManager::ProcessMessage(CNode& peer, CConnman& connman, st // Ignore such requests until we are fully synced. // We could start processing this after masternode list is synced // but this is a heavy one so it's better to finish sync first. - if (!::masternodeSync->IsSynced()) return {}; + if (!m_mn_sync->IsSynced()) return {}; uint256 nProp; CBloomFilter filter; @@ -157,7 +161,7 @@ PeerMsgRet CGovernanceManager::ProcessMessage(CNode& peer, CConnman& connman, st EraseObjectRequest(peer.GetId(), CInv(MSG_GOVERNANCE_OBJECT, nHash)); } - if (!::masternodeSync->IsBlockchainSynced()) { + if (!m_mn_sync->IsBlockchainSynced()) { LogPrint(BCLog::GOBJECT, "MNGOVERNANCEOBJECT -- masternode list not synced\n"); return {}; } @@ -225,7 +229,7 @@ PeerMsgRet CGovernanceManager::ProcessMessage(CNode& peer, CConnman& connman, st } // Ignore such messages until masternode list is synced - if (!::masternodeSync->IsBlockchainSynced()) { + if (!m_mn_sync->IsBlockchainSynced()) { LogPrint(BCLog::GOBJECT, "MNGOVERNANCEOBJECTVOTE -- masternode list not synced\n"); return {}; } @@ -243,11 +247,11 @@ PeerMsgRet CGovernanceManager::ProcessMessage(CNode& peer, CConnman& connman, st CGovernanceException exception; if (ProcessVote(&peer, vote, exception, connman)) { LogPrint(BCLog::GOBJECT, "MNGOVERNANCEOBJECTVOTE -- %s new\n", strHash); - ::masternodeSync->BumpAssetLastTime("MNGOVERNANCEOBJECTVOTE"); - vote.Relay(connman, tip_mn_list); + m_mn_sync->BumpAssetLastTime("MNGOVERNANCEOBJECTVOTE"); + vote.Relay(connman, *m_mn_sync, tip_mn_list); } else { LogPrint(BCLog::GOBJECT, "MNGOVERNANCEOBJECTVOTE -- Rejected vote, error = %s\n", exception.what()); - if ((exception.GetNodePenalty() != 0) && ::masternodeSync->IsSynced()) { + if ((exception.GetNodePenalty() != 0) && m_mn_sync->IsSynced()) { return tl::unexpected{exception.GetNodePenalty()}; } return {}; @@ -272,8 +276,8 @@ void CGovernanceManager::CheckOrphanVotes(CGovernanceObject& govobj, CConnman& c CGovernanceException e; if (pairVote.second < nNow) { fRemove = true; - } else if (govobj.ProcessVote(*this, tip_mn_list, vote, e)) { - vote.Relay(connman, tip_mn_list); + } else if (govobj.ProcessVote(m_mn_metaman, *this, tip_mn_list, vote, e)) { + vote.Relay(connman, *Assert(m_mn_sync), tip_mn_list); fRemove = true; } if (fRemove) { @@ -327,12 +331,12 @@ void CGovernanceManager::AddGovernanceObject(CGovernanceObject& govobj, CConnman } LogPrint(BCLog::GOBJECT, "CGovernanceManager::AddGovernanceObject -- %s new, received from peer %s\n", strHash, pfrom ? pfrom->GetLogString() : "nullptr"); - govobj.Relay(connman); + govobj.Relay(connman, *Assert(m_mn_sync)); // Update the rate buffer MasternodeRateUpdate(govobj); - ::masternodeSync->BumpAssetLastTime("CGovernanceManager::AddGovernanceObject"); + m_mn_sync->BumpAssetLastTime("CGovernanceManager::AddGovernanceObject"); // WE MIGHT HAVE PENDING/ORPHAN VOTES FOR THIS OBJECT @@ -344,14 +348,14 @@ void CGovernanceManager::AddGovernanceObject(CGovernanceObject& govobj, CConnman void CGovernanceManager::CheckAndRemove() { - assert(::mmetaman->IsValid()); + assert(m_mn_metaman.IsValid()); // Return on initial sync, spammed the debug.log and provided no use - if (::masternodeSync == nullptr || !::masternodeSync->IsBlockchainSynced()) return; + if (m_mn_sync == nullptr || !m_mn_sync->IsBlockchainSynced()) return; LogPrint(BCLog::GOBJECT, "CGovernanceManager::UpdateCachesAndClean\n"); - std::vector vecDirtyHashes = mmetaman->GetAndClearDirtyGovernanceObjectHashes(); + std::vector vecDirtyHashes = m_mn_metaman.GetAndClearDirtyGovernanceObjectHashes(); const auto tip_mn_list = Assert(m_dmnman)->GetListAtChainTip(); @@ -398,7 +402,7 @@ void CGovernanceManager::CheckAndRemove() if ((pObj->IsSetCachedDelete() || pObj->IsSetExpired()) && (nTimeSinceDeletion >= GOVERNANCE_DELETION_DELAY)) { LogPrint(BCLog::GOBJECT, "CGovernanceManager::UpdateCachesAndClean -- erase obj %s\n", (*it).first.ToString()); - mmetaman->RemoveGovernanceObject(pObj->GetHash()); + m_mn_metaman.RemoveGovernanceObject(pObj->GetHash()); // Remove vote references const object_ref_cm_t::list_t& listItems = cmapVoteToObject.GetItemList(); @@ -562,7 +566,7 @@ struct sortProposalsByVotes { std::optional CGovernanceManager::CreateSuperblockCandidate(int nHeight) const { if (!fMasternodeMode || fDisableGovernance) return std::nullopt; - if (::masternodeSync == nullptr || !::masternodeSync->IsSynced()) return std::nullopt; + if (m_mn_sync == nullptr || !m_mn_sync->IsSynced()) return std::nullopt; if (nHeight % Params().GetConsensus().nSuperblockCycle < Params().GetConsensus().nSuperblockCycle - Params().GetConsensus().nSuperblockMaturityWindow) return std::nullopt; if (HasAlreadyVotedFundingTrigger()) return std::nullopt; @@ -668,8 +672,11 @@ std::optional CGovernanceManager::CreateSuperblockCandidate(i return CSuperblock(nNextSuperblock, std::move(payments)); } -std::optional CGovernanceManager::CreateGovernanceTrigger(const std::optional& sb_opt, CConnman& connman) +std::optional CGovernanceManager::CreateGovernanceTrigger(const std::optional& sb_opt, CConnman& connman, + const CActiveMasternodeManager* const mn_activeman) { + if (!fMasternodeMode) return std::nullopt; + // no sb_opt, no trigger if (!sb_opt.has_value()) return std::nullopt; @@ -693,12 +700,12 @@ std::optional CGovernanceManager::CreateGovernanceTrigg return std::nullopt; } - if (mn_payees.front()->proTxHash != ::activeMasternodeManager->GetProTxHash()) { + if (mn_payees.front()->proTxHash != Assert(mn_activeman)->GetProTxHash()) { LogPrint(BCLog::GOBJECT, "CGovernanceManager::%s we are not the payee, skipping\n", __func__); return std::nullopt; } - gov_sb.SetMasternodeOutpoint(::activeMasternodeManager->GetOutPoint()); - gov_sb.Sign(*::activeMasternodeManager); + gov_sb.SetMasternodeOutpoint(mn_activeman->GetOutPoint()); + gov_sb.Sign(*mn_activeman); if (std::string strError; !gov_sb.IsValidLocally(m_dmnman->GetListAtChainTip(), strError, true)) { LogPrint(BCLog::GOBJECT, "CGovernanceManager::%s Created trigger is invalid:%s\n", __func__, strError); @@ -715,11 +722,12 @@ std::optional CGovernanceManager::CreateGovernanceTrigg return std::make_optional(gov_sb); } -void CGovernanceManager::VoteGovernanceTriggers(const std::optional& trigger_opt, CConnman& connman) +void CGovernanceManager::VoteGovernanceTriggers(const std::optional& trigger_opt, CConnman& connman, + const CActiveMasternodeManager* const mn_activeman) { // only active masternodes can vote on triggers if (!fMasternodeMode) return; - if (::activeMasternodeManager->GetProTxHash().IsNull()) return; + if (Assert(mn_activeman)->GetProTxHash().IsNull()) return; LOCK2(cs_main, cs); @@ -728,7 +736,7 @@ void CGovernanceManager::VoteGovernanceTriggers(const std::optionalGetOutPoint(), nHash, VOTE_SIGNAL_FUNDING, outcome); + if (!fMasternodeMode) return false; + + CGovernanceVote vote(Assert(mn_activeman)->GetOutPoint(), nHash, VOTE_SIGNAL_FUNDING, outcome); vote.SetTime(GetAdjustedTime()); - vote.Sign(*::activeMasternodeManager); + vote.Sign(*mn_activeman); CGovernanceException exception; if (!ProcessVoteAndRelay(vote, exception, connman)) { @@ -788,7 +799,7 @@ void CGovernanceManager::ResetVotedFundingTrigger() void CGovernanceManager::DoMaintenance(CConnman& connman) { if (fDisableGovernance) return; - if (::masternodeSync == nullptr || !::masternodeSync->IsSynced()) return; + if (m_mn_sync == nullptr || !m_mn_sync->IsSynced()) return; if (ShutdownRequested()) return; // CHECK OBJECTS WE'VE ASKED FOR, REMOVE OLD ENTRIES @@ -802,7 +813,7 @@ void CGovernanceManager::DoMaintenance(CConnman& connman) bool CGovernanceManager::ConfirmInventoryRequest(const CInv& inv) { // do not request objects until it's time to sync - if (!::masternodeSync->IsBlockchainSynced()) return false; + if (!Assert(m_mn_sync)->IsBlockchainSynced()) return false; LOCK(cs); @@ -855,7 +866,7 @@ bool CGovernanceManager::ConfirmInventoryRequest(const CInv& inv) void CGovernanceManager::SyncSingleObjVotes(CNode& peer, const uint256& nProp, const CBloomFilter& filter, CConnman& connman) { // do not provide any data until our node is synced - if (!::masternodeSync->IsSynced()) return; + if (!Assert(m_mn_sync)->IsSynced()) return; int nVoteCount = 0; @@ -907,7 +918,7 @@ PeerMsgRet CGovernanceManager::SyncObjects(CNode& peer, CConnman& connman) const assert(m_netfulfilledman.IsValid()); // do not provide any data until our node is synced - if (!::masternodeSync->IsSynced()) return {}; + if (!Assert(m_mn_sync)->IsSynced()) return {}; if (m_netfulfilledman.HasFulfilledRequest(peer.addr, NetMsgType::MNGOVERNANCESYNC)) { // Asking for the whole list multiple times in a short period of time is no good @@ -997,7 +1008,7 @@ bool CGovernanceManager::MasternodeRateCheck(const CGovernanceObject& govobj, bo fRateCheckBypassed = false; - if (!::masternodeSync->IsSynced() || !fRateChecksEnabled) { + if (!Assert(m_mn_sync)->IsSynced() || !fRateChecksEnabled) { return true; } @@ -1055,6 +1066,15 @@ bool CGovernanceManager::MasternodeRateCheck(const CGovernanceObject& govobj, bo return false; } +bool CGovernanceManager::ProcessVoteAndRelay(const CGovernanceVote& vote, CGovernanceException& exception, CConnman& connman) +{ + bool fOK = ProcessVote(/* pfrom = */ nullptr, vote, exception, connman); + if (fOK) { + vote.Relay(connman, *Assert(m_mn_sync), Assert(m_dmnman)->GetListAtChainTip()); + } + return fOK; +} + bool CGovernanceManager::ProcessVote(CNode* pfrom, const CGovernanceVote& vote, CGovernanceException& exception, CConnman& connman) { ENTER_CRITICAL_SECTION(cs); @@ -1104,14 +1124,14 @@ bool CGovernanceManager::ProcessVote(CNode* pfrom, const CGovernanceVote& vote, return false; } - bool fOk = govobj.ProcessVote(*this, Assert(m_dmnman)->GetListAtChainTip(), vote, exception) && cmapVoteToObject.Insert(nHashVote, &govobj); + bool fOk = govobj.ProcessVote(m_mn_metaman, *this, Assert(m_dmnman)->GetListAtChainTip(), vote, exception) && cmapVoteToObject.Insert(nHashVote, &govobj); LEAVE_CRITICAL_SECTION(cs); return fOk; } void CGovernanceManager::CheckPostponedObjects(CConnman& connman) { - if (!::masternodeSync->IsSynced()) return; + if (!Assert(m_mn_sync)->IsSynced()) return; LOCK2(cs_main, cs); @@ -1159,7 +1179,7 @@ void CGovernanceManager::CheckPostponedObjects(CConnman& connman) if (fValid) { if (fReady) { LogPrint(BCLog::GOBJECT, "CGovernanceManager::CheckPostponedObjects -- additional relay: hash = %s\n", govobj.GetHash().ToString()); - govobj.Relay(connman); + govobj.Relay(connman, *m_mn_sync); } else { it++; continue; @@ -1454,7 +1474,7 @@ UniValue CGovernanceManager::ToJson() const return jsonObj; } -void CGovernanceManager::UpdatedBlockTip(const CBlockIndex* pindex, CConnman& connman) +void CGovernanceManager::UpdatedBlockTip(const CBlockIndex* pindex, CConnman& connman, const CActiveMasternodeManager* const mn_activeman) { // Note this gets called from ActivateBestChain without cs_main being held // so it should be safe to lock our mutex here without risking a deadlock @@ -1466,8 +1486,8 @@ void CGovernanceManager::UpdatedBlockTip(const CBlockIndex* pindex, CConnman& co } const auto sb_opt = CreateSuperblockCandidate(pindex->nHeight); - const auto trigger_opt = CreateGovernanceTrigger(sb_opt, connman); - VoteGovernanceTriggers(trigger_opt, connman); + const auto trigger_opt = CreateGovernanceTrigger(sb_opt, connman, mn_activeman); + VoteGovernanceTriggers(trigger_opt, connman, mn_activeman); nCachedBlockHeight = pindex->nHeight; LogPrint(BCLog::GOBJECT, "CGovernanceManager::UpdatedBlockTip -- nCachedBlockHeight: %d\n", nCachedBlockHeight); @@ -1530,7 +1550,7 @@ void CGovernanceManager::CleanOrphanObjects() void CGovernanceManager::RemoveInvalidVotes() { - if (!::masternodeSync->IsSynced()) { + if (!Assert(m_mn_sync)->IsSynced()) { return; } diff --git a/src/governance/governance.h b/src/governance/governance.h index 94a1cbccb68e..cad15d52aa37 100644 --- a/src/governance/governance.h +++ b/src/governance/governance.h @@ -5,7 +5,6 @@ #ifndef BITCOIN_GOVERNANCE_GOVERNANCE_H #define BITCOIN_GOVERNANCE_GOVERNANCE_H -#include #include #include @@ -26,6 +25,8 @@ class CDeterministicMNManager; class CGovernanceManager; class CGovernanceObject; class CGovernanceVote; +class CMasternodeMetaMan; +class CMasternodeSync; class CNetFulfilledRequestManager; class CSporkManager; @@ -255,8 +256,10 @@ class CGovernanceManager : public GovernanceStore const std::unique_ptr m_db; bool is_valid{false}; + CMasternodeMetaMan& m_mn_metaman; CNetFulfilledRequestManager& m_netfulfilledman; const std::unique_ptr& m_dmnman; + const std::unique_ptr& m_mn_sync; int64_t nTimeLastDiff; // keep track of current block height @@ -270,7 +273,9 @@ class CGovernanceManager : public GovernanceStore std::map> mapTrigger; public: - explicit CGovernanceManager(CNetFulfilledRequestManager& netfulfilledman, const std::unique_ptr& dmnman); + explicit CGovernanceManager(CMasternodeMetaMan& mn_metaman, CNetFulfilledRequestManager& netfulfilledman, + const std::unique_ptr& dmnman, + const std::unique_ptr& mn_sync); ~CGovernanceManager(); bool LoadCache(bool load_cache); @@ -308,7 +313,7 @@ class CGovernanceManager : public GovernanceStore UniValue ToJson() const; - void UpdatedBlockTip(const CBlockIndex* pindex, CConnman& connman); + void UpdatedBlockTip(const CBlockIndex* pindex, CConnman& connman, const CActiveMasternodeManager* const mn_activeman); int64_t GetLastDiffTime() const { return nTimeLastDiff; } void UpdateLastDiffTime(int64_t nTimeIn) { nTimeLastDiff = nTimeIn; } @@ -337,14 +342,7 @@ class CGovernanceManager : public GovernanceStore bool MasternodeRateCheck(const CGovernanceObject& govobj, bool fUpdateFailStatus, bool fForce, bool& fRateCheckBypassed); - bool ProcessVoteAndRelay(const CGovernanceVote& vote, CGovernanceException& exception, CConnman& connman) - { - bool fOK = ProcessVote(nullptr, vote, exception, connman); - if (fOK) { - vote.Relay(connman, Assert(m_dmnman)->GetListAtChainTip()); - } - return fOK; - } + bool ProcessVoteAndRelay(const CGovernanceVote& vote, CGovernanceException& exception, CConnman& connman); void CheckPostponedObjects(CConnman& connman); @@ -370,9 +368,12 @@ class CGovernanceManager : public GovernanceStore private: std::optional CreateSuperblockCandidate(int nHeight) const; - std::optional CreateGovernanceTrigger(const std::optional& sb_opt, CConnman& connman); - void VoteGovernanceTriggers(const std::optional& trigger_opt, CConnman& connman); - bool VoteFundingTrigger(const uint256& nHash, const vote_outcome_enum_t outcome, CConnman& connman); + std::optional CreateGovernanceTrigger(const std::optional& sb_opt, CConnman& connman, + const CActiveMasternodeManager* const mn_activeman); + void VoteGovernanceTriggers(const std::optional& trigger_opt, CConnman& connman, + const CActiveMasternodeManager* const mn_activeman); + bool VoteFundingTrigger(const uint256& nHash, const vote_outcome_enum_t outcome, CConnman& connman, + const CActiveMasternodeManager* const mn_activeman); bool HasAlreadyVotedFundingTrigger() const; void RequestGovernanceObject(CNode* pfrom, const uint256& nHash, CConnman& connman, bool fUseFilter = false) const; diff --git a/src/governance/object.cpp b/src/governance/object.cpp index 3553ccafb4ce..dfd28b3879ee 100644 --- a/src/governance/object.cpp +++ b/src/governance/object.cpp @@ -80,9 +80,10 @@ CGovernanceObject::CGovernanceObject(const CGovernanceObject& other) : { } -bool CGovernanceObject::ProcessVote(CGovernanceManager& govman, const CDeterministicMNList& tip_mn_list, const CGovernanceVote& vote, CGovernanceException& exception) +bool CGovernanceObject::ProcessVote(CMasternodeMetaMan& mn_metaman, CGovernanceManager& govman, const CDeterministicMNList& tip_mn_list, + const CGovernanceVote& vote, CGovernanceException& exception) { - assert(::mmetaman->IsValid()); + assert(mn_metaman.IsValid()); LOCK(cs); @@ -180,7 +181,7 @@ bool CGovernanceObject::ProcessVote(CGovernanceManager& govman, const CDetermini return false; } - if (!mmetaman->AddGovernanceVote(dmn->proTxHash, vote.GetParentHash())) { + if (!mn_metaman.AddGovernanceVote(dmn->proTxHash, vote.GetParentHash())) { std::ostringstream ostr; ostr << "CGovernanceObject::ProcessVote -- Unable to add governance vote" << ", MN outpoint = " << vote.GetMasternodeOutpoint().ToStringShort() @@ -628,10 +629,10 @@ bool CGovernanceObject::GetCurrentMNVotes(const COutPoint& mnCollateralOutpoint, return true; } -void CGovernanceObject::Relay(CConnman& connman) const +void CGovernanceObject::Relay(CConnman& connman, const CMasternodeSync& mn_sync) const { // Do not relay until fully synced - if (!::masternodeSync->IsSynced()) { + if (!mn_sync.IsSynced()) { LogPrint(BCLog::GOBJECT, "CGovernanceObject::Relay -- won't relay until fully synced\n"); return; } diff --git a/src/governance/object.h b/src/governance/object.h index e3879802c029..d7f22bad9bf9 100644 --- a/src/governance/object.h +++ b/src/governance/object.h @@ -19,6 +19,8 @@ class CDeterministicMNList; class CGovernanceManager; class CGovernanceObject; class CGovernanceVote; +class CMasternodeMetaMan; +class CMasternodeSync; class CNode; extern RecursiveMutex cs_main; @@ -247,7 +249,7 @@ class CGovernanceObject UniValue GetJSONObject() const; - void Relay(CConnman& connman) const; + void Relay(CConnman& connman, const CMasternodeSync& mn_sync) const; uint256 GetHash() const; uint256 GetDataHash() const; @@ -289,7 +291,8 @@ class CGovernanceObject void LoadData(); void GetData(UniValue& objResult) const; - bool ProcessVote(CGovernanceManager& govman, const CDeterministicMNList& tip_mn_list, const CGovernanceVote& vote, CGovernanceException& exception); + bool ProcessVote(CMasternodeMetaMan& mn_metaman, CGovernanceManager& govman, const CDeterministicMNList& tip_mn_list, + const CGovernanceVote& vote, CGovernanceException& exception); /// Called when MN's which have voted on this object have been removed void ClearMasternodeVotes(const CDeterministicMNList& tip_mn_list); diff --git a/src/governance/vote.cpp b/src/governance/vote.cpp index 05f588c6a731..859aee529c08 100644 --- a/src/governance/vote.cpp +++ b/src/governance/vote.cpp @@ -122,10 +122,10 @@ std::string CGovernanceVote::ToString(const CDeterministicMNList& tip_mn_list) c return ostr.str(); } -void CGovernanceVote::Relay(CConnman& connman, const CDeterministicMNList& tip_mn_list) const +void CGovernanceVote::Relay(CConnman& connman, const CMasternodeSync& mn_sync, const CDeterministicMNList& tip_mn_list) const { // Do not relay until fully synced - if (!::masternodeSync->IsSynced()) { + if (!mn_sync.IsSynced()) { LogPrint(BCLog::GOBJECT, "CGovernanceVote::Relay -- won't relay until fully synced\n"); return; } diff --git a/src/governance/vote.h b/src/governance/vote.h index 2561a9c96a32..bb2c0a510b27 100644 --- a/src/governance/vote.h +++ b/src/governance/vote.h @@ -13,6 +13,7 @@ class CBLSPublicKey; class CConnman; class CDeterministicMNList; class CGovernanceVote; +class CMasternodeSync; class CKey; class CKeyID; @@ -104,7 +105,7 @@ class CGovernanceVote bool Sign(const CActiveMasternodeManager& mn_activeman); bool CheckSignature(const CBLSPublicKey& pubKey) const; bool IsValid(const CDeterministicMNList& tip_mn_list, bool useVotingKey) const; - void Relay(CConnman& connman, const CDeterministicMNList& tip_mn_list) const; + void Relay(CConnman& connman, const CMasternodeSync& mn_sync, const CDeterministicMNList& tip_mn_list) const; const COutPoint& GetMasternodeOutpoint() const { return masternodeOutpoint; } diff --git a/src/init.cpp b/src/init.cpp index 5eff0d0b11a5..0b45e98e0347 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -305,13 +305,11 @@ void PrepareShutdown(NodeContext& node) // After all scheduled tasks have been flushed, destroy pointers // and reset all to nullptr. - node.mn_sync = nullptr; - ::masternodeSync.reset(); + node.mn_sync.reset(); node.sporkman.reset(); node.govman.reset(); node.netfulfilledman.reset(); - node.mn_metaman = nullptr; - ::mmetaman.reset(); + node.mn_metaman.reset(); // Stop and delete all indexes only after flushing background callbacks. if (g_txindex) { @@ -345,8 +343,8 @@ void PrepareShutdown(NodeContext& node) node.llmq_ctx.reset(); } llmq::quorumSnapshotManager.reset(); - node.dmnman = nullptr; - deterministicMNManager.reset(); + node.mempool->DisconnectManagers(); + node.dmnman.reset(); node.cpoolman.reset(); node.mnhf_manager.reset(); node.evodb.reset(); @@ -369,9 +367,8 @@ void PrepareShutdown(NodeContext& node) pdsNotificationInterface = nullptr; } if (fMasternodeMode) { - UnregisterValidationInterface(node.mn_activeman); - node.mn_activeman = nullptr; - ::activeMasternodeManager.reset(); + UnregisterValidationInterface(node.mn_activeman.get()); + node.mn_activeman.reset(); } node.chain_clients.clear(); @@ -1679,15 +1676,14 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc node.chainman = &g_chainman; ChainstateManager& chainman = *Assert(node.chainman); - assert(!::mmetaman); - ::mmetaman = std::make_unique(); - node.mn_metaman = ::mmetaman.get(); + assert(!node.mn_metaman); + node.mn_metaman = std::make_unique(); assert(!node.netfulfilledman); node.netfulfilledman = std::make_unique(); assert(!node.govman); - node.govman = std::make_unique(*node.netfulfilledman, ::deterministicMNManager); + node.govman = std::make_unique(*node.mn_metaman, *node.netfulfilledman, node.dmnman, node.mn_sync); assert(!node.sporkman); node.sporkman = std::make_unique(); @@ -1716,9 +1712,8 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc } } - assert(!::masternodeSync); - ::masternodeSync = std::make_unique(*node.connman, *node.netfulfilledman, *node.govman); - node.mn_sync = ::masternodeSync.get(); + assert(!node.mn_sync); + node.mn_sync = std::make_unique(*node.connman, *node.netfulfilledman, *node.govman); fMasternodeMode = false; std::string strMasterNodeBLSPrivKey = args.GetArg("-masternodeblsprivkey", ""); @@ -1729,17 +1724,16 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc } fMasternodeMode = true; { - // Create and register activeMasternodeManager, will init later in ThreadImport - ::activeMasternodeManager = std::make_unique(keyOperator, *node.connman, ::deterministicMNManager); - node.mn_activeman = ::activeMasternodeManager.get(); - RegisterValidationInterface(node.mn_activeman); + // Create and register mn_activeman, will init later in ThreadImport + node.mn_activeman = std::make_unique(keyOperator, *node.connman, node.dmnman); + RegisterValidationInterface(node.mn_activeman.get()); } } assert(!node.peerman); node.peerman = PeerManager::make(chainparams, *node.connman, *node.addrman, node.banman.get(), *node.scheduler, chainman, *node.mempool, *node.mn_metaman, *node.mn_sync, - *node.govman, *node.sporkman, ::deterministicMNManager, + *node.govman, *node.sporkman, node.mn_activeman.get(), node.dmnman, node.cj_ctx, node.llmq_ctx, ignores_incoming_txs); RegisterValidationInterface(node.peerman.get()); @@ -1864,7 +1858,7 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc #endif pdsNotificationInterface = new CDSNotificationInterface( - *node.connman, *node.mn_sync, *node.govman, ::deterministicMNManager, node.llmq_ctx, node.cj_ctx + *node.connman, *node.mn_sync, *node.govman, node.mn_activeman.get(), node.dmnman, node.llmq_ctx, node.cj_ctx ); RegisterValidationInterface(pdsNotificationInterface); @@ -1949,11 +1943,13 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc pblocktree.reset(new CBlockTreeDB(nBlockTreeDBCache, false, fReset)); // Same logic as above with pblocktree - deterministicMNManager.reset(); - deterministicMNManager = std::make_unique(chainman.ActiveChainstate(), *node.connman, *node.evodb); - node.dmnman = deterministicMNManager.get(); + node.dmnman.reset(); + node.dmnman = std::make_unique(chainman.ActiveChainstate(), *node.connman, *node.evodb); + node.mempool->ConnectManagers(node.dmnman.get()); + node.cpoolman.reset(); node.cpoolman = std::make_unique(*node.evodb); + llmq::quorumSnapshotManager.reset(); llmq::quorumSnapshotManager.reset(new llmq::CQuorumSnapshotManager(*node.evodb)); @@ -1962,7 +1958,8 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc node.llmq_ctx->Stop(); } node.llmq_ctx.reset(); - node.llmq_ctx.reset(new LLMQContext(chainman.ActiveChainstate(), *node.connman, *node.dmnman, *node.evodb, *node.mnhf_manager, *node.sporkman, *node.mempool, node.mn_activeman, node.peerman, false, fReset || fReindexChainState)); + node.llmq_ctx = std::make_unique(chainman.ActiveChainstate(), *node.connman, *node.dmnman, *node.evodb, *node.mn_metaman, *node.mnhf_manager, *node.sporkman, + *node.mempool, node.mn_activeman.get(), *node.mn_sync, node.peerman, /* unit_tests = */ false, /* wipe = */ fReset || fReindexChainState); // Have to start it early to let VerifyDB check ChainLock signatures in coinbase node.llmq_ctx->Start(); @@ -2207,8 +2204,8 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc // ********************************************************* Step 7c: Setup CoinJoin - node.cj_ctx = std::make_unique(chainman.ActiveChainstate(), *node.connman, *node.dmnman, *node.mempool, node.mn_activeman, - *node.mn_sync, !ignores_incoming_txs); + node.cj_ctx = std::make_unique(chainman.ActiveChainstate(), *node.connman, *node.dmnman, *node.mn_metaman, *node.mempool, + node.mn_activeman.get(), *node.mn_sync, !ignores_incoming_txs); #ifdef ENABLE_WALLET node.coinjoin_loader = interfaces::MakeCoinJoinLoader(*node.cj_ctx->walletman); @@ -2380,7 +2377,7 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc } chainman.m_load_block = std::thread(&util::TraceThread, "loadblk", [=, &args, &chainman, &node] { - ThreadImport(chainman, *node.dmnman, *pdsNotificationInterface, vImportFiles, args); + ThreadImport(chainman, *node.dmnman, *pdsNotificationInterface, vImportFiles, node.mn_activeman.get(), args); }); // Wait for genesis block to be processed diff --git a/src/llmq/chainlocks.cpp b/src/llmq/chainlocks.cpp index 8ad1f327df2d..c5f3b0f525ab 100644 --- a/src/llmq/chainlocks.cpp +++ b/src/llmq/chainlocks.cpp @@ -25,17 +25,17 @@ namespace llmq { std::unique_ptr chainLocksHandler; -CChainLocksHandler::CChainLocksHandler(CChainState& chainstate, CConnman& _connman, CMasternodeSync& mn_sync, CQuorumManager& _qman, +CChainLocksHandler::CChainLocksHandler(CChainState& chainstate, CConnman& _connman, CQuorumManager& _qman, CSigningManager& _sigman, CSigSharesManager& _shareman, CSporkManager& sporkman, - CTxMemPool& _mempool) : + CTxMemPool& _mempool, const CMasternodeSync& mn_sync) : m_chainstate(chainstate), connman(_connman), - m_mn_sync(mn_sync), qman(_qman), sigman(_sigman), shareman(_shareman), spork_manager(sporkman), mempool(_mempool), + m_mn_sync(mn_sync), scheduler(std::make_unique()), scheduler_thread(std::make_unique(std::thread(util::TraceThread, "cl-schdlr", [&] { scheduler->serviceQueue(); }))) { diff --git a/src/llmq/chainlocks.h b/src/llmq/chainlocks.h index 9ee1dab921ed..e9041d544253 100644 --- a/src/llmq/chainlocks.h +++ b/src/llmq/chainlocks.h @@ -47,12 +47,12 @@ class CChainLocksHandler : public CRecoveredSigsListener private: CChainState& m_chainstate; CConnman& connman; - CMasternodeSync& m_mn_sync; CQuorumManager& qman; CSigningManager& sigman; CSigSharesManager& shareman; CSporkManager& spork_manager; CTxMemPool& mempool; + const CMasternodeSync& m_mn_sync; std::unique_ptr scheduler; std::unique_ptr scheduler_thread; @@ -85,9 +85,9 @@ class CChainLocksHandler : public CRecoveredSigsListener std::atomic lastCleanupTime{0}; public: - explicit CChainLocksHandler(CChainState& chainstate, CConnman& _connman, CMasternodeSync& mn_sync, CQuorumManager& _qman, + explicit CChainLocksHandler(CChainState& chainstate, CConnman& _connman, CQuorumManager& _qman, CSigningManager& _sigman, CSigSharesManager& _shareman, CSporkManager& sporkman, - CTxMemPool& _mempool); + CTxMemPool& _mempool, const CMasternodeSync& mn_sync); ~CChainLocksHandler(); void Start(); diff --git a/src/llmq/context.cpp b/src/llmq/context.cpp index 6963ce5cb675..cc32e7a0dd78 100644 --- a/src/llmq/context.cpp +++ b/src/llmq/context.cpp @@ -20,7 +20,8 @@ #include LLMQContext::LLMQContext(CChainState& chainstate, CConnman& connman, CDeterministicMNManager& dmnman, CEvoDB& evo_db, - CMNHFManager& mnhfman, CSporkManager& sporkman, CTxMemPool& mempool, const CActiveMasternodeManager* const mn_activeman, + CMasternodeMetaMan& mn_metaman, CMNHFManager& mnhfman, CSporkManager& sporkman, CTxMemPool& mempool, + const CActiveMasternodeManager* const mn_activeman, const CMasternodeSync& mn_sync, const std::unique_ptr& peerman, bool unit_tests, bool wipe) : bls_worker{std::make_shared()}, dkg_debugman{std::make_unique()}, @@ -29,22 +30,22 @@ LLMQContext::LLMQContext(CChainState& chainstate, CConnman& connman, CDeterminis llmq::quorumBlockProcessor = std::make_unique(chainstate, connman, dmnman, evo_db); return llmq::quorumBlockProcessor.get(); }()}, - qdkgsman{std::make_unique(*bls_worker, chainstate, connman, dmnman, *dkg_debugman, *quorum_block_processor, mn_activeman, sporkman, unit_tests, wipe)}, + qdkgsman{std::make_unique(*bls_worker, chainstate, connman, dmnman, *dkg_debugman, mn_metaman, *quorum_block_processor, mn_activeman, sporkman, unit_tests, wipe)}, qman{[&]() -> llmq::CQuorumManager* const { assert(llmq::quorumManager == nullptr); - llmq::quorumManager = std::make_unique(*bls_worker, chainstate, connman, dmnman, *qdkgsman, evo_db, *quorum_block_processor, mn_activeman, sporkman, ::masternodeSync); + llmq::quorumManager = std::make_unique(*bls_worker, chainstate, connman, dmnman, *qdkgsman, evo_db, *quorum_block_processor, mn_activeman, mn_sync, sporkman); return llmq::quorumManager.get(); }()}, sigman{std::make_unique(connman, mn_activeman, *llmq::quorumManager, unit_tests, wipe)}, shareman{std::make_unique(connman, *sigman, mn_activeman, *llmq::quorumManager, sporkman, peerman)}, clhandler{[&]() -> llmq::CChainLocksHandler* const { assert(llmq::chainLocksHandler == nullptr); - llmq::chainLocksHandler = std::make_unique(chainstate, connman, *::masternodeSync, *llmq::quorumManager, *sigman, *shareman, sporkman, mempool); + llmq::chainLocksHandler = std::make_unique(chainstate, connman, *llmq::quorumManager, *sigman, *shareman, sporkman, mempool, mn_sync); return llmq::chainLocksHandler.get(); }()}, isman{[&]() -> llmq::CInstantSendManager* const { assert(llmq::quorumInstantSendManager == nullptr); - llmq::quorumInstantSendManager = std::make_unique(*llmq::chainLocksHandler, chainstate, connman, *llmq::quorumManager, *sigman, *shareman, sporkman, mempool, *::masternodeSync, unit_tests, wipe); + llmq::quorumInstantSendManager = std::make_unique(*llmq::chainLocksHandler, chainstate, connman, *llmq::quorumManager, *sigman, *shareman, sporkman, mempool, mn_sync, unit_tests, wipe); return llmq::quorumInstantSendManager.get(); }()}, ehfSignalsHandler{std::make_unique(chainstate, connman, mnhfman, *sigman, *shareman, sporkman, *llmq::quorumManager, mempool)} diff --git a/src/llmq/context.h b/src/llmq/context.h index a5a3dd6de0f0..531dcb052567 100644 --- a/src/llmq/context.h +++ b/src/llmq/context.h @@ -14,6 +14,8 @@ class CConnman; class CDeterministicMNManager; class CDBWrapper; class CEvoDB; +class CMasternodeMetaMan; +class CMasternodeSync; class CMNHFManager; class CSporkManager; class CTxMemPool; @@ -35,7 +37,8 @@ struct LLMQContext { LLMQContext() = delete; LLMQContext(const LLMQContext&) = delete; LLMQContext(CChainState& chainstate, CConnman& connman, CDeterministicMNManager& dmnman, CEvoDB& evo_db, - CMNHFManager& mnhfman, CSporkManager& sporkman, CTxMemPool& mempool, const CActiveMasternodeManager* const mn_activeman, + CMasternodeMetaMan& mn_metaman, CMNHFManager& mnhfman, CSporkManager& sporkman, CTxMemPool& mempool, + const CActiveMasternodeManager* const mn_activeman, const CMasternodeSync& mn_sync, const std::unique_ptr& peerman, bool unit_tests, bool wipe); ~LLMQContext(); diff --git a/src/llmq/dkgsession.cpp b/src/llmq/dkgsession.cpp index cb0c9bb1bbfc..ead2adab8fde 100644 --- a/src/llmq/dkgsession.cpp +++ b/src/llmq/dkgsession.cpp @@ -450,7 +450,7 @@ void CDKGSession::VerifyAndComplain(CDKGPendingMessages& pendingMessages) void CDKGSession::VerifyConnectionAndMinProtoVersions() const { - assert(::mmetaman->IsValid()); + assert(m_mn_metaman.IsValid()); if (!IsQuorumPoseEnabled(params.type, m_sporkman)) { return; @@ -482,7 +482,7 @@ void CDKGSession::VerifyConnectionAndMinProtoVersions() const logger.Batch("%s does not have min proto version %d (has %d)", m->dmn->proTxHash.ToString(), MIN_MASTERNODE_PROTO_VERSION, it->second); } - if (mmetaman->GetMetaInfo(m->dmn->proTxHash)->OutboundFailedTooManyTimes()) { + if (m_mn_metaman.GetMetaInfo(m->dmn->proTxHash)->OutboundFailedTooManyTimes()) { m->badConnection = true; logger.Batch("%s failed to connect to it too many times", m->dmn->proTxHash.ToString()); } diff --git a/src/llmq/dkgsession.h b/src/llmq/dkgsession.h index 16da61894bbd..5b19d6a0973d 100644 --- a/src/llmq/dkgsession.h +++ b/src/llmq/dkgsession.h @@ -19,6 +19,7 @@ class CActiveMasternodeManager; class CInv; class CConnman; class CDeterministicMN; +class CMasternodeMetaMan; class CSporkManager; class UniValue; @@ -272,9 +273,11 @@ class CDKGSession CBLSWorker& blsWorker; CBLSWorkerCache cache; + CConnman& connman; CDeterministicMNManager& m_dmnman; CDKGSessionManager& dkgManager; CDKGDebugManager& dkgDebugManager; + CMasternodeMetaMan& m_mn_metaman; const CActiveMasternodeManager* const m_mn_activeman; const CSporkManager& m_sporkman; @@ -297,7 +300,6 @@ class CDKGSession uint256 myProTxHash; CBLSId myId; - CConnman& connman; std::optional myIdx; // all indexed by msg hash @@ -317,11 +319,12 @@ class CDKGSession std::set validCommitments GUARDED_BY(invCs); public: - CDKGSession(const Consensus::LLMQParams& _params, CBLSWorker& _blsWorker, CDeterministicMNManager& dmnman, - CDKGSessionManager& _dkgManager, CDKGDebugManager& _dkgDebugManager, CConnman& _connman, - const CActiveMasternodeManager* const mn_activeman, const CSporkManager& sporkman) : - params(_params), blsWorker(_blsWorker), cache(_blsWorker), m_dmnman(dmnman), dkgManager(_dkgManager), - dkgDebugManager(_dkgDebugManager), m_mn_activeman(mn_activeman), m_sporkman(sporkman), connman(_connman) {} + CDKGSession(const Consensus::LLMQParams& _params, CBLSWorker& _blsWorker, CConnman& _connman, + CDeterministicMNManager& dmnman, CDKGSessionManager& _dkgManager, CDKGDebugManager& _dkgDebugManager, + CMasternodeMetaMan& mn_metaman, const CActiveMasternodeManager* const mn_activeman, + const CSporkManager& sporkman) : + params(_params), blsWorker(_blsWorker), cache(_blsWorker), connman(_connman), m_dmnman(dmnman), dkgManager(_dkgManager), + dkgDebugManager(_dkgDebugManager), m_mn_metaman(mn_metaman), m_mn_activeman(mn_activeman), m_sporkman(sporkman) {} bool Init(gsl::not_null pQuorumBaseBlockIndex, Span mns, const uint256& _myProTxHash, int _quorumIndex); diff --git a/src/llmq/dkgsessionhandler.cpp b/src/llmq/dkgsessionhandler.cpp index 429b2b2c475f..43eb04a5fb16 100644 --- a/src/llmq/dkgsessionhandler.cpp +++ b/src/llmq/dkgsessionhandler.cpp @@ -25,21 +25,22 @@ namespace llmq { CDKGSessionHandler::CDKGSessionHandler(CBLSWorker& _blsWorker, CChainState& chainstate, CConnman& _connman, CDeterministicMNManager& dmnman, - CDKGDebugManager& _dkgDebugManager, CDKGSessionManager& _dkgManager, CQuorumBlockProcessor& _quorumBlockProcessor, - const CActiveMasternodeManager* const mn_activeman, const CSporkManager& sporkman, const Consensus::LLMQParams& _params, - int _quorumIndex) : + CDKGDebugManager& _dkgDebugManager, CDKGSessionManager& _dkgManager, CMasternodeMetaMan& mn_metaman, + CQuorumBlockProcessor& _quorumBlockProcessor, const CActiveMasternodeManager* const mn_activeman, + const CSporkManager& sporkman, const Consensus::LLMQParams& _params, int _quorumIndex) : blsWorker(_blsWorker), m_chainstate(chainstate), connman(_connman), m_dmnman(dmnman), dkgDebugManager(_dkgDebugManager), dkgManager(_dkgManager), + m_mn_metaman(mn_metaman), quorumBlockProcessor(_quorumBlockProcessor), m_mn_activeman(mn_activeman), m_sporkman(sporkman), params(_params), quorumIndex(_quorumIndex), - curSession(std::make_unique(_params, _blsWorker, dmnman, _dkgManager, _dkgDebugManager, _connman, m_mn_activeman, sporkman)), + curSession(std::make_unique(_params, _blsWorker, _connman, dmnman, _dkgManager, _dkgDebugManager, m_mn_metaman, m_mn_activeman, sporkman)), pendingContributions((size_t)_params.size * 2, MSG_QUORUM_CONTRIB), // we allow size*2 messages as we need to make sure we see bad behavior (double messages) pendingComplaints((size_t)_params.size * 2, MSG_QUORUM_COMPLAINT), pendingJustifications((size_t)_params.size * 2, MSG_QUORUM_JUSTIFICATION), @@ -187,7 +188,7 @@ void CDKGSessionHandler::StopThread() bool CDKGSessionHandler::InitNewQuorum(const CBlockIndex* pQuorumBaseBlockIndex) { - curSession = std::make_unique(params, blsWorker, m_dmnman, dkgManager, dkgDebugManager, connman, m_mn_activeman, m_sporkman); + curSession = std::make_unique(params, blsWorker, connman, m_dmnman, dkgManager, dkgDebugManager, m_mn_metaman, m_mn_activeman, m_sporkman); if (!DeploymentDIP0003Enforced(pQuorumBaseBlockIndex->nHeight, Params().GetConsensus())) { return false; @@ -533,7 +534,7 @@ void CDKGSessionHandler::HandleDKGRound() const auto tip_mn_list = m_dmnman.GetListAtChainTip(); utils::EnsureQuorumConnections(params, connman, m_dmnman, m_sporkman, tip_mn_list, pQuorumBaseBlockIndex, curSession->myProTxHash); if (curSession->AreWeMember()) { - utils::AddQuorumProbeConnections(params, connman, m_dmnman, m_sporkman, tip_mn_list, pQuorumBaseBlockIndex, curSession->myProTxHash); + utils::AddQuorumProbeConnections(params, connman, m_dmnman, m_mn_metaman, m_sporkman, tip_mn_list, pQuorumBaseBlockIndex, curSession->myProTxHash); } WaitForNextPhase(QuorumPhase::Initialized, QuorumPhase::Contribute, curQuorumHash); diff --git a/src/llmq/dkgsessionhandler.h b/src/llmq/dkgsessionhandler.h index c8121edcf15c..fb509be8ec8b 100644 --- a/src/llmq/dkgsessionhandler.h +++ b/src/llmq/dkgsessionhandler.h @@ -19,6 +19,7 @@ class CBlockIndex; class CBLSWorker; class CChainState; class CDeterministicMNManager; +class CMasternodeMetaMan; class CSporkManager; class PeerManager; @@ -125,6 +126,7 @@ class CDKGSessionHandler CDeterministicMNManager& m_dmnman; CDKGDebugManager& dkgDebugManager; CDKGSessionManager& dkgManager; + CMasternodeMetaMan& m_mn_metaman; CQuorumBlockProcessor& quorumBlockProcessor; const CActiveMasternodeManager* const m_mn_activeman; const CSporkManager& m_sporkman; @@ -147,9 +149,9 @@ class CDKGSessionHandler public: CDKGSessionHandler(CBLSWorker& _blsWorker, CChainState& chainstate, CConnman& _connman, CDeterministicMNManager& dmnman, - CDKGDebugManager& _dkgDebugManager, CDKGSessionManager& _dkgManager, CQuorumBlockProcessor& _quorumBlockProcessor, - const CActiveMasternodeManager* const mn_activeman, const CSporkManager& sporkman, const Consensus::LLMQParams& _params, - int _quorumIndex); + CDKGDebugManager& _dkgDebugManager, CDKGSessionManager& _dkgManager, CMasternodeMetaMan& mn_metaman, + CQuorumBlockProcessor& _quorumBlockProcessor, const CActiveMasternodeManager* const mn_activeman, + const CSporkManager& sporkman, const Consensus::LLMQParams& _params, int _quorumIndex); ~CDKGSessionHandler() = default; void UpdatedBlockTip(const CBlockIndex *pindexNew); diff --git a/src/llmq/dkgsessionmgr.cpp b/src/llmq/dkgsessionmgr.cpp index 9715368f6ce1..707edf9ec0e3 100644 --- a/src/llmq/dkgsessionmgr.cpp +++ b/src/llmq/dkgsessionmgr.cpp @@ -25,8 +25,8 @@ static const std::string DB_SKCONTRIB = "qdkg_S"; static const std::string DB_ENC_CONTRIB = "qdkg_E"; CDKGSessionManager::CDKGSessionManager(CBLSWorker& _blsWorker, CChainState& chainstate, CConnman& _connman, CDeterministicMNManager& dmnman, - CDKGDebugManager& _dkgDebugManager, CQuorumBlockProcessor& _quorumBlockProcessor, const CActiveMasternodeManager* const mn_activeman, - const CSporkManager& sporkman, bool unitTests, bool fWipe) : + CDKGDebugManager& _dkgDebugManager, CMasternodeMetaMan& mn_metaman, CQuorumBlockProcessor& _quorumBlockProcessor, + const CActiveMasternodeManager* const mn_activeman, const CSporkManager& sporkman, bool unitTests, bool fWipe) : db(std::make_unique(unitTests ? "" : (GetDataDir() / "llmq/dkgdb"), 1 << 20, unitTests, fWipe)), blsWorker(_blsWorker), m_chainstate(chainstate), @@ -49,7 +49,7 @@ CDKGSessionManager::CDKGSessionManager(CBLSWorker& _blsWorker, CChainState& chai for (const auto i : irange::range(session_count)) { dkgSessionHandlers.emplace(std::piecewise_construct, std::forward_as_tuple(params.type, i), - std::forward_as_tuple(blsWorker, m_chainstate, connman, dmnman, dkgDebugManager, *this, quorumBlockProcessor, mn_activeman, spork_manager, params, i)); + std::forward_as_tuple(blsWorker, m_chainstate, connman, dmnman, dkgDebugManager, *this, mn_metaman, quorumBlockProcessor, mn_activeman, spork_manager, params, i)); } } } diff --git a/src/llmq/dkgsessionmgr.h b/src/llmq/dkgsessionmgr.h index d237f77eaab1..d920b50bfb6a 100644 --- a/src/llmq/dkgsessionmgr.h +++ b/src/llmq/dkgsessionmgr.h @@ -20,6 +20,7 @@ class CChainState; class CDBWrapper; class CDeterministicMNManager; class CDKGDebugManager; +class CMasternodeMetaMan; class CSporkManager; class PeerManager; @@ -67,8 +68,8 @@ class CDKGSessionManager public: CDKGSessionManager(CBLSWorker& _blsWorker, CChainState& chainstate, CConnman& _connman, CDeterministicMNManager& dmnman, - CDKGDebugManager& _dkgDebugManager, CQuorumBlockProcessor& _quorumBlockProcessor, const CActiveMasternodeManager* const mn_activeman, - const CSporkManager& sporkman, bool unitTests, bool fWipe); + CDKGDebugManager& _dkgDebugManager, CMasternodeMetaMan& mn_metaman, CQuorumBlockProcessor& _quorumBlockProcessor, + const CActiveMasternodeManager* const mn_activeman, const CSporkManager& sporkman, bool unitTests, bool fWipe); ~CDKGSessionManager() = default; void StartThreads(); diff --git a/src/llmq/quorums.cpp b/src/llmq/quorums.cpp index eb4fc0c605a3..8b8021ae2107 100644 --- a/src/llmq/quorums.cpp +++ b/src/llmq/quorums.cpp @@ -207,7 +207,7 @@ bool CQuorum::ReadContributions(CEvoDB& evoDb) CQuorumManager::CQuorumManager(CBLSWorker& _blsWorker, CChainState& chainstate, CConnman& _connman, CDeterministicMNManager& dmnman, CDKGSessionManager& _dkgManager, CEvoDB& _evoDb, CQuorumBlockProcessor& _quorumBlockProcessor, - const CActiveMasternodeManager* const mn_activeman, const CSporkManager& sporkman, const std::unique_ptr& mn_sync) : + const CActiveMasternodeManager* const mn_activeman, const CMasternodeSync& mn_sync, const CSporkManager& sporkman) : blsWorker(_blsWorker), m_chainstate(chainstate), connman(_connman), @@ -216,8 +216,8 @@ CQuorumManager::CQuorumManager(CBLSWorker& _blsWorker, CChainState& chainstate, m_evoDb(_evoDb), quorumBlockProcessor(_quorumBlockProcessor), m_mn_activeman(mn_activeman), - m_sporkman(sporkman), - m_mn_sync(mn_sync) + m_mn_sync(mn_sync), + m_sporkman(sporkman) { utils::InitQuorumsCache(mapQuorumsCache, false); quorumThreadInterrupt.reset(); @@ -296,7 +296,7 @@ void CQuorumManager::TriggerQuorumDataRecoveryThreads(const CBlockIndex* pIndex) void CQuorumManager::UpdatedBlockTip(const CBlockIndex* pindexNew, bool fInitialDownload) const { - if (!m_mn_sync->IsBlockchainSynced()) return; + if (!m_mn_sync.IsBlockchainSynced()) return; for (const auto& params : Params().GetConsensus().llmqs) { CheckQuorumConnections(params, pindexNew); @@ -916,7 +916,7 @@ void CQuorumManager::StartQuorumDataRecoveryThread(const CQuorumCPtr pQuorum, co }; printLog("Start"); - while (!m_mn_sync->IsBlockchainSynced() && !quorumThreadInterrupt) { + while (!m_mn_sync.IsBlockchainSynced() && !quorumThreadInterrupt) { quorumThreadInterrupt.sleep_for(std::chrono::seconds(nRequestTimeout)); } diff --git a/src/llmq/quorums.h b/src/llmq/quorums.h index 6d9515dffa70..75dc65fff66f 100644 --- a/src/llmq/quorums.h +++ b/src/llmq/quorums.h @@ -225,8 +225,8 @@ class CQuorumManager CEvoDB& m_evoDb; CQuorumBlockProcessor& quorumBlockProcessor; const CActiveMasternodeManager* const m_mn_activeman; + const CMasternodeSync& m_mn_sync; const CSporkManager& m_sporkman; - const std::unique_ptr& m_mn_sync; mutable Mutex cs_map_quorums; mutable std::map> mapQuorumsCache GUARDED_BY(cs_map_quorums); @@ -241,7 +241,7 @@ class CQuorumManager public: CQuorumManager(CBLSWorker& _blsWorker, CChainState& chainstate, CConnman& _connman, CDeterministicMNManager& dmnman, CDKGSessionManager& _dkgManager, CEvoDB& _evoDb, CQuorumBlockProcessor& _quorumBlockProcessor, - const CActiveMasternodeManager* const mn_activeman, const CSporkManager& sporkman, const std::unique_ptr& mn_sync); + const CActiveMasternodeManager* const mn_activeman, const CMasternodeSync& mn_sync, const CSporkManager& sporkman); ~CQuorumManager() { Stop(); }; void Start(); diff --git a/src/llmq/utils.cpp b/src/llmq/utils.cpp index 2f2ed213c45b..9fc63deb47e3 100644 --- a/src/llmq/utils.cpp +++ b/src/llmq/utils.cpp @@ -808,11 +808,11 @@ bool EnsureQuorumConnections(const Consensus::LLMQParams& llmqParams, CConnman& return true; } -void AddQuorumProbeConnections(const Consensus::LLMQParams& llmqParams, CConnman& connman, CDeterministicMNManager& dmnman, const CSporkManager& sporkman, - const CDeterministicMNList& tip_mn_list, gsl::not_null pQuorumBaseBlockIndex, - const uint256 &myProTxHash) +void AddQuorumProbeConnections(const Consensus::LLMQParams& llmqParams, CConnman& connman, CDeterministicMNManager& dmnman, + CMasternodeMetaMan& mn_metaman, const CSporkManager& sporkman, const CDeterministicMNList& tip_mn_list, + gsl::not_null pQuorumBaseBlockIndex, const uint256 &myProTxHash) { - assert(::mmetaman->IsValid()); + assert(mn_metaman.IsValid()); if (!IsQuorumPoseEnabled(llmqParams.type, sporkman)) { return; @@ -826,7 +826,7 @@ void AddQuorumProbeConnections(const Consensus::LLMQParams& llmqParams, CConnman if (dmn->proTxHash == myProTxHash) { continue; } - auto lastOutbound = mmetaman->GetMetaInfo(dmn->proTxHash)->GetLastOutboundSuccess(); + auto lastOutbound = mn_metaman.GetMetaInfo(dmn->proTxHash)->GetLastOutboundSuccess(); if (curTime - lastOutbound < 10 * 60) { // avoid re-probing nodes too often continue; diff --git a/src/llmq/utils.h b/src/llmq/utils.h index e9e1275be876..9e219b507aed 100644 --- a/src/llmq/utils.h +++ b/src/llmq/utils.h @@ -19,9 +19,11 @@ class CBlockIndex; class CDeterministicMN; class CDeterministicMNList; class CDeterministicMNManager; -using CDeterministicMNCPtr = std::shared_ptr; +class CMasternodeMetaMan; class CSporkManager; +using CDeterministicMNCPtr = std::shared_ptr; + namespace llmq { @@ -39,9 +41,9 @@ std::set CalcDeterministicWatchConnections(Consensus::LLMQType llmqType, bool EnsureQuorumConnections(const Consensus::LLMQParams& llmqParams, CConnman& connman, CDeterministicMNManager& dmnman, const CSporkManager& sporkman, const CDeterministicMNList& tip_mn_list, gsl::not_null pQuorumBaseBlockIndex, const uint256& myProTxHash); -void AddQuorumProbeConnections(const Consensus::LLMQParams& llmqParams, CConnman& connman, CDeterministicMNManager& dmnman, const CSporkManager& sporkman, - const CDeterministicMNList& tip_mn_list, gsl::not_null pQuorumBaseBlockIndex, - const uint256& myProTxHash); +void AddQuorumProbeConnections(const Consensus::LLMQParams& llmqParams, CConnman& connman, CDeterministicMNManager& dmnman, + CMasternodeMetaMan& mn_metaman, const CSporkManager& sporkman, const CDeterministicMNList& tip_mn_list, + gsl::not_null pQuorumBaseBlockIndex, const uint256& myProTxHash); template void InitQuorumsCache(CacheType& cache, bool limit_by_connections = true); diff --git a/src/masternode/meta.cpp b/src/masternode/meta.cpp index 7c7861640c98..3160e280ad66 100644 --- a/src/masternode/meta.cpp +++ b/src/masternode/meta.cpp @@ -9,8 +9,6 @@ #include -std::unique_ptr mmetaman; - const std::string MasternodeMetaStore::SERIALIZATION_VERSION_STRING = "CMasternodeMetaMan-Version-3"; CMasternodeMetaMan::CMasternodeMetaMan() : diff --git a/src/masternode/meta.h b/src/masternode/meta.h index b2c4dfc3718c..d6177a8ca1a8 100644 --- a/src/masternode/meta.h +++ b/src/masternode/meta.h @@ -176,6 +176,4 @@ class CMasternodeMetaMan : public MasternodeMetaStore std::vector GetAndClearDirtyGovernanceObjectHashes(); }; -extern std::unique_ptr mmetaman; - #endif // BITCOIN_MASTERNODE_META_H diff --git a/src/masternode/node.cpp b/src/masternode/node.cpp index dd3d128f574b..23bfce2d474e 100644 --- a/src/masternode/node.cpp +++ b/src/masternode/node.cpp @@ -15,9 +15,6 @@ #include #include -// Keep track of the active Masternode -std::unique_ptr activeMasternodeManager; - CActiveMasternodeManager::CActiveMasternodeManager(const CBLSSecretKey& sk, CConnman& connman, const std::unique_ptr& dmnman) : m_info(sk, sk.GetPublicKey()), m_connman{connman}, diff --git a/src/masternode/node.h b/src/masternode/node.h index a06a25e5425d..d63e14b5d9d0 100644 --- a/src/masternode/node.h +++ b/src/masternode/node.h @@ -80,6 +80,4 @@ class CActiveMasternodeManager final : public CValidationInterface bool GetLocalAddress(CService& addrRet) EXCLUSIVE_LOCKS_REQUIRED(cs); }; -extern std::unique_ptr activeMasternodeManager; - #endif // BITCOIN_MASTERNODE_NODE_H diff --git a/src/masternode/sync.cpp b/src/masternode/sync.cpp index ad83eaf49fe1..5094f412b5fc 100644 --- a/src/masternode/sync.cpp +++ b/src/masternode/sync.cpp @@ -15,7 +15,6 @@ #include class CMasternodeSync; -std::unique_ptr masternodeSync; CMasternodeSync::CMasternodeSync(CConnman& _connman, CNetFulfilledRequestManager& netfulfilledman, const CGovernanceManager& govman) : nTimeAssetSyncStarted(GetTime()), diff --git a/src/masternode/sync.h b/src/masternode/sync.h index 0a9859b76a75..aeba83ae779a 100644 --- a/src/masternode/sync.h +++ b/src/masternode/sync.h @@ -26,8 +26,6 @@ static constexpr int MASTERNODE_SYNC_TICK_SECONDS = 6; static constexpr int MASTERNODE_SYNC_TIMEOUT_SECONDS = 30; // our blocks are 2.5 minutes so 30 seconds should be fine static constexpr int MASTERNODE_SYNC_RESET_SECONDS = 900; // Reset fReachedBestHeader in CMasternodeSync::Reset if UpdateBlockTip hasn't been called for this seconds -extern std::unique_ptr masternodeSync; - // // CMasternodeSync : Sync masternode assets in stages // diff --git a/src/net_processing.cpp b/src/net_processing.cpp index e938e44ba8e7..96c3766fda2e 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -297,6 +297,7 @@ class PeerManagerImpl final : public PeerManager CScheduler &scheduler, 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& cj_ctx, const std::unique_ptr& llmq_ctx, @@ -423,6 +424,7 @@ class PeerManagerImpl final : public PeerManager CMasternodeSync& m_mn_sync; CGovernanceManager& m_govman; CSporkManager& m_sporkman; + const CActiveMasternodeManager* const m_mn_activeman; /** The height of the best chain */ std::atomic m_best_height{-1}; @@ -1735,17 +1737,19 @@ std::unique_ptr PeerManager::make(const CChainParams& chainparams, CScheduler &scheduler, 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& cj_ctx, const std::unique_ptr& llmq_ctx, bool ignore_incoming_txs) { - return std::make_unique(chainparams, connman, addrman, banman, scheduler, chainman, pool, mn_metaman, mn_sync, govman, sporkman, dmnman, cj_ctx, llmq_ctx, ignore_incoming_txs); + return std::make_unique(chainparams, connman, addrman, banman, scheduler, chainman, pool, mn_metaman, mn_sync, govman, sporkman, mn_activeman, dmnman, cj_ctx, llmq_ctx, ignore_incoming_txs); } PeerManagerImpl::PeerManagerImpl(const CChainParams& chainparams, CConnman& connman, CAddrMan& addrman, BanMan* banman, CScheduler &scheduler, 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& cj_ctx, const std::unique_ptr& llmq_ctx, @@ -1763,6 +1767,7 @@ PeerManagerImpl::PeerManagerImpl(const CChainParams& chainparams, CConnman& conn m_mn_sync(mn_sync), m_govman(govman), m_sporkman(sporkman), + m_mn_activeman(mn_activeman), m_ignore_incoming_txs(ignore_incoming_txs) { assert(std::addressof(g_chainman) == std::addressof(m_chainman)); @@ -3293,8 +3298,8 @@ void PeerManagerImpl::ProcessMessage( pfrom.ConnectionTypeAsString()); } - if (!pfrom.m_masternode_probe_connection) { - CMNAuth::PushMNAUTH(pfrom, m_connman, m_chainman.ActiveChain().Tip()); + if (fMasternodeMode && !pfrom.m_masternode_probe_connection) { + CMNAuth::PushMNAUTH(pfrom, m_connman, *Assert(m_mn_activeman), m_chainman.ActiveChain().Tip()); } // Tell our peer we prefer to receive headers rather than inv's @@ -4625,7 +4630,7 @@ void PeerManagerImpl::ProcessMessage( ProcessPeerMsgRet(m_sporkman.ProcessMessage(pfrom, m_connman, msg_type, vRecv), pfrom); m_mn_sync.ProcessMessage(pfrom, msg_type, vRecv); ProcessPeerMsgRet(m_govman.ProcessMessage(pfrom, m_connman, msg_type, vRecv), pfrom); - ProcessPeerMsgRet(CMNAuth::ProcessMessage(pfrom, m_connman, m_dmnman->GetListAtChainTip(), msg_type, vRecv), pfrom); + ProcessPeerMsgRet(CMNAuth::ProcessMessage(pfrom, m_connman, m_mn_metaman, m_mn_activeman, m_mn_sync, m_dmnman->GetListAtChainTip(), msg_type, vRecv), pfrom); ProcessPeerMsgRet(m_llmq_ctx->quorum_block_processor->ProcessMessage(pfrom, msg_type, vRecv), pfrom); ProcessPeerMsgRet(m_llmq_ctx->qdkgsman->ProcessMessage(pfrom, this, msg_type, vRecv), pfrom); ProcessPeerMsgRet(m_llmq_ctx->qman->ProcessMessage(pfrom, msg_type, vRecv), pfrom); diff --git a/src/net_processing.h b/src/net_processing.h index 23b7a9595f3f..07ad18d79442 100644 --- a/src/net_processing.h +++ b/src/net_processing.h @@ -12,6 +12,7 @@ #include +class CActiveMasternodeManager; class CAddrMan; class CTxMemPool; class CDeterministicMNManager; @@ -52,6 +53,7 @@ class PeerManager : public CValidationInterface, public NetEventsInterface BanMan* banman, CScheduler &scheduler, 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& cj_ctx, const std::unique_ptr& llmq_ctx, bool ignore_incoming_txs); diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp index 0910c6b0b945..c1fc6d6ffeb1 100644 --- a/src/node/blockstorage.cpp +++ b/src/node/blockstorage.cpp @@ -120,7 +120,7 @@ struct CImportingNow { }; void ThreadImport(ChainstateManager& chainman, CDeterministicMNManager& dmnman, CDSNotificationInterface& dsnfi, - std::vector vImportFiles, const ArgsManager& args) + std::vector vImportFiles, CActiveMasternodeManager* const mn_activeman, const ArgsManager& args) { ScheduleBatchPriority(); @@ -210,8 +210,7 @@ void ThreadImport(ChainstateManager& chainman, CDeterministicMNManager& dmnman, } if (fMasternodeMode) { - assert(activeMasternodeManager); - activeMasternodeManager->Init(::ChainActive().Tip()); + Assert(mn_activeman)->Init(::ChainActive().Tip()); } g_wallet_init_interface.AutoLockMasternodeCollaterals(); diff --git a/src/node/blockstorage.h b/src/node/blockstorage.h index 6bbf27f22ace..bcb07175e8c3 100644 --- a/src/node/blockstorage.h +++ b/src/node/blockstorage.h @@ -11,6 +11,7 @@ #include #include +class CActiveMasternodeManager; class ArgsManager; class CBlock; class CBlockIndex; @@ -36,6 +37,6 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex); FlatFilePos SaveBlockToDisk(const CBlock& block, int nHeight, CChain& active_chain, const CChainParams& chainparams, const FlatFilePos* dbp); void ThreadImport(ChainstateManager& chainman, CDeterministicMNManager& dmnman, CDSNotificationInterface& dsnfi, - std::vector vImportFiles, const ArgsManager& args); + std::vector vImportFiles, CActiveMasternodeManager* const mn_activeman, const ArgsManager& args); #endif // BITCOIN_NODE_BLOCKSTORAGE_H diff --git a/src/node/context.cpp b/src/node/context.cpp index f92008007b6b..ba850e80af53 100644 --- a/src/node/context.cpp +++ b/src/node/context.cpp @@ -7,14 +7,18 @@ #include #include #include -#include #include +#include +#include +#include +#include #include #include #include #include -#include -#include +#include +#include +#include #include #include #include diff --git a/src/node/context.h b/src/node/context.h index bd03c9c8f601..88d812884233 100644 --- a/src/node/context.h +++ b/src/node/context.h @@ -71,19 +71,19 @@ struct NodeContext { std::unique_ptr scheduler; std::function rpc_interruption_point = [] {}; //! Dash + std::unique_ptr mn_activeman; std::unique_ptr cpoolman; std::unique_ptr evodb; std::unique_ptr chain_helper; + std::unique_ptr dmnman; std::unique_ptr govman; std::unique_ptr cj_ctx; + std::unique_ptr mn_metaman; + std::unique_ptr mn_sync; std::unique_ptr mnhf_manager; std::unique_ptr netfulfilledman; std::unique_ptr sporkman; std::unique_ptr llmq_ctx; - CActiveMasternodeManager* mn_activeman{nullptr}; - CDeterministicMNManager* dmnman{nullptr}; - CMasternodeMetaMan* mn_metaman{nullptr}; - CMasternodeSync* mn_sync{nullptr}; //! Declare default constructor and destructor that are not inline, so code //! instantiating the NodeContext struct doesn't need to #include class diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp index 6937cbdf2cdf..eff295d891c0 100644 --- a/src/node/interfaces.cpp +++ b/src/node/interfaces.cpp @@ -482,7 +482,7 @@ class NodeImpl : public Node void setNetworkActive(bool active) override { if (m_context->connman) { - m_context->connman->SetNetworkActive(active, m_context->mn_sync); + m_context->connman->SetNetworkActive(active, m_context->mn_sync.get()); } } bool getNetworkActive() override { return m_context->connman && m_context->connman->GetNetworkActive(); } diff --git a/src/rpc/governance.cpp b/src/rpc/governance.cpp index cf271484b1f7..b91261fb6963 100644 --- a/src/rpc/governance.cpp +++ b/src/rpc/governance.cpp @@ -399,7 +399,7 @@ static UniValue gobject_submit(const JSONRPCRequest& request) if (fMissingConfirmations) { node.govman->AddPostponedObject(govobj); - govobj.Relay(*node.connman); + govobj.Relay(*node.connman, *node.mn_sync); } else { node.govman->AddGovernanceObject(govobj, *node.connman); } diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index ba1dbf7313e4..191ff6e7c557 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -896,7 +896,7 @@ static RPCHelpMan setnetworkactive() throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); } - node.connman->SetNetworkActive(request.params[0].get_bool(), node.mn_sync); + node.connman->SetNetworkActive(request.params[0].get_bool(), node.mn_sync.get()); return node.connman->GetNetworkActive(); }, diff --git a/src/rpc/quorums.cpp b/src/rpc/quorums.cpp index 78551db8e69b..53873a4454f9 100644 --- a/src/rpc/quorums.cpp +++ b/src/rpc/quorums.cpp @@ -884,7 +884,7 @@ static UniValue _quorum(const JSONRPCRequest& request) } else if (command == "quorumdkginfo") { return quorum_dkginfo(new_request, llmq_ctx, chainman); } else if (command == "quorumdkgstatus") { - return quorum_dkgstatus(new_request, *node.dmnman, node.mn_activeman, chainman, *node.sporkman, llmq_ctx); + return quorum_dkgstatus(new_request, *node.dmnman, node.mn_activeman.get(), chainman, *node.sporkman, llmq_ctx); } else if (command == "quorummemberof") { return quorum_memberof(new_request, chainman, node, llmq_ctx); } else if (command == "quorumsign" || command == "quorumverify" || command == "quorumhasrecsig" || command == "quorumgetrecsig" || command == "quorumisconflicting") { diff --git a/src/test/denialofservice_tests.cpp b/src/test/denialofservice_tests.cpp index 66a24a65c14a..b383e3625d44 100644 --- a/src/test/denialofservice_tests.cpp +++ b/src/test/denialofservice_tests.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -66,7 +67,7 @@ BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction) auto connman = std::make_unique(0x1337, 0x1337, *m_node.addrman); auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, nullptr, *m_node.scheduler, *m_node.chainman, *m_node.mempool, *m_node.mn_metaman, *m_node.mn_sync, - *m_node.govman, *m_node.sporkman, ::deterministicMNManager, + *m_node.govman, *m_node.sporkman, /* mn_activeman = */ nullptr, m_node.dmnman, m_node.cj_ctx, m_node.llmq_ctx, /* ignore_incoming_txs = */ false); // Mock an outbound peer @@ -137,7 +138,7 @@ BOOST_AUTO_TEST_CASE(stale_tip_peer_management) auto connman = std::make_unique(0x1337, 0x1337, *m_node.addrman); auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, nullptr, *m_node.scheduler, *m_node.chainman, *m_node.mempool, *m_node.mn_metaman, *m_node.mn_sync, - *m_node.govman, *m_node.sporkman, ::deterministicMNManager, + *m_node.govman, *m_node.sporkman, /* mn_activeman = */ nullptr, m_node.dmnman, m_node.cj_ctx, m_node.llmq_ctx, /* ignore_incoming_txs = */ false); constexpr int max_outbound_full_relay = MAX_OUTBOUND_FULL_RELAY_CONNECTIONS; @@ -212,7 +213,7 @@ BOOST_AUTO_TEST_CASE(peer_discouragement) auto connman = std::make_unique(0x1337, 0x1337, *m_node.addrman); auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool, *m_node.mn_metaman, *m_node.mn_sync, - *m_node.govman, *m_node.sporkman, ::deterministicMNManager, + *m_node.govman, *m_node.sporkman, /* mn_activeman = */ nullptr, m_node.dmnman, m_node.cj_ctx, m_node.llmq_ctx, /* ignore_incoming_txs = */ false); banman->ClearBanned(); @@ -260,7 +261,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime) auto connman = std::make_unique(0x1337, 0x1337, *m_node.addrman); auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool, *m_node.mn_metaman, *m_node.mn_sync, - *m_node.govman, *m_node.sporkman, ::deterministicMNManager, + *m_node.govman, *m_node.sporkman, /* mn_activeman = */ nullptr, m_node.dmnman, m_node.cj_ctx, m_node.llmq_ctx, /* ignore_incoming_txs = */ false); banman->ClearBanned(); diff --git a/src/test/evo_deterministicmns_tests.cpp b/src/test/evo_deterministicmns_tests.cpp index 355688163e47..66ed487a54e7 100644 --- a/src/test/evo_deterministicmns_tests.cpp +++ b/src/test/evo_deterministicmns_tests.cpp @@ -640,6 +640,9 @@ void FuncTestMempoolReorg(TestChainSetup& setup) SignTransaction(*(setup.m_node.mempool), tx_reg, setup.coinbaseKey); CTxMemPool testPool; + if (setup.m_node.dmnman) { + testPool.ConnectManagers(setup.m_node.dmnman.get()); + } TestMemPoolEntryHelper entry; LOCK2(cs_main, testPool.cs); @@ -709,6 +712,9 @@ void FuncTestMempoolDualProregtx(TestChainSetup& setup) SignTransaction(*(setup.m_node.mempool), tx_reg2, setup.coinbaseKey); CTxMemPool testPool; + if (setup.m_node.dmnman) { + testPool.ConnectManagers(setup.m_node.dmnman.get()); + } TestMemPoolEntryHelper entry; LOCK2(cs_main, testPool.cs); diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 76f32ec3db68..027a2a26cfd9 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -109,14 +109,16 @@ void DashTestSetup(NodeContext& node, const CChainParams& chainparams) { CChainState& chainstate = Assert(node.chainman)->ActiveChainstate(); - ::deterministicMNManager = std::make_unique(chainstate, *node.connman, *node.evodb); - node.dmnman = ::deterministicMNManager.get(); - node.cj_ctx = std::make_unique(chainstate, *node.connman, *node.dmnman, *node.mempool, /* mn_activeman = */ nullptr, *node.mn_sync, /* relay_txes = */ true); + node.dmnman = std::make_unique(chainstate, *node.connman, *node.evodb); + node.mempool->ConnectManagers(node.dmnman.get()); + + node.cj_ctx = std::make_unique(chainstate, *node.connman, *node.dmnman, *node.mn_metaman, *node.mempool, + /* mn_activeman = */ nullptr, *node.mn_sync, /* relay_txes = */ true); #ifdef ENABLE_WALLET node.coinjoin_loader = interfaces::MakeCoinJoinLoader(*node.cj_ctx->walletman); #endif // ENABLE_WALLET - node.llmq_ctx = std::make_unique(chainstate, *node.connman, *node.dmnman, *node.evodb, *node.mnhf_manager, *node.sporkman, *node.mempool, - /* mn_activeman = */ nullptr, node.peerman, /* unit_tests = */ true, /* wipe = */ false); + node.llmq_ctx = std::make_unique(chainstate, *node.connman, *node.dmnman, *node.evodb, *node.mn_metaman, *node.mnhf_manager, *node.sporkman, *node.mempool, + /* mn_activeman = */ nullptr, *node.mn_sync, node.peerman, /* unit_tests = */ true, /* wipe = */ false); node.chain_helper = std::make_unique(*node.cpoolman, *node.dmnman, *node.mnhf_manager, *node.govman, *(node.llmq_ctx->quorum_block_processor), chainparams.GetConsensus(), *node.mn_sync, *node.sporkman, *(node.llmq_ctx->clhandler)); } @@ -130,8 +132,8 @@ void DashTestSetupClose(NodeContext& node) #ifdef ENABLE_WALLET node.coinjoin_loader.reset(); #endif // ENABLE_WALLET - node.dmnman = nullptr; - ::deterministicMNManager.reset(); + node.mempool->DisconnectManagers(); + node.dmnman.reset(); node.cj_ctx.reset(); } @@ -227,13 +229,11 @@ ChainTestingSetup::ChainTestingSetup(const std::string& chainName, const std::ve m_node.connman = std::make_unique(0x1337, 0x1337, *m_node.addrman); // Deterministic randomness for tests. - ::mmetaman = std::make_unique(); - m_node.mn_metaman = ::mmetaman.get(); + m_node.mn_metaman = std::make_unique(); m_node.netfulfilledman = std::make_unique(); m_node.sporkman = std::make_unique(); - m_node.govman = std::make_unique(*m_node.netfulfilledman, ::deterministicMNManager); - ::masternodeSync = std::make_unique(*m_node.connman, *m_node.netfulfilledman, *m_node.govman); - m_node.mn_sync = ::masternodeSync.get(); + m_node.govman = std::make_unique(*m_node.mn_metaman, *m_node.netfulfilledman, m_node.dmnman, m_node.mn_sync); + m_node.mn_sync = std::make_unique(*m_node.connman, *m_node.netfulfilledman, *m_node.govman); // Start script-checking threads. Set g_parallel_script_checks to true so they are used. constexpr int script_check_threads = 2; @@ -247,13 +247,11 @@ ChainTestingSetup::~ChainTestingSetup() StopScriptCheckWorkerThreads(); GetMainSignals().FlushBackgroundCallbacks(); GetMainSignals().UnregisterBackgroundSignalScheduler(); - m_node.mn_sync = nullptr; - ::masternodeSync.reset(); + m_node.mn_sync.reset(); m_node.govman.reset(); m_node.sporkman.reset(); m_node.netfulfilledman.reset(); - m_node.mn_metaman = nullptr; - ::mmetaman.reset(); + m_node.mn_metaman.reset(); m_node.connman.reset(); m_node.addrman.reset(); m_node.args = nullptr; @@ -286,8 +284,8 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector(GetDataDir() / "banlist", nullptr, DEFAULT_MISBEHAVING_BANTIME); m_node.peerman = PeerManager::make(chainparams, *m_node.connman, *m_node.addrman, m_node.banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool, *m_node.mn_metaman, *m_node.mn_sync, - *m_node.govman, *m_node.sporkman, ::deterministicMNManager, m_node.cj_ctx, m_node.llmq_ctx, - /* ignore_incoming_txs = */ false); + *m_node.govman, *m_node.sporkman, /* mn_activeman = */ nullptr, m_node.dmnman, + m_node.cj_ctx, m_node.llmq_ctx, /* ignore_incoming_txs = */ false); { CConnman::Options options; options.m_msgproc = m_node.peerman.get(); diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 6b06b37d2c77..d9aef7af1925 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -347,6 +347,13 @@ CTxMemPool::CTxMemPool(CBlockPolicyEstimator* estimator, int check_ratio) _clear(); //lock free clear } +void CTxMemPool::ConnectManagers(CDeterministicMNManager* dmnman) +{ + // Do not allow double-initialization + assert(m_dmnman == nullptr); + m_dmnman = Assert(dmnman); +} + bool CTxMemPool::isSpent(const COutPoint& outpoint) const { LOCK(cs); @@ -415,46 +422,8 @@ void CTxMemPool::addUnchecked(const CTxMemPoolEntry &entry, setEntries &setAnces // Invalid ProTxes should never get this far because transactions should be // fully checked by AcceptToMemoryPool() at this point, so we just assume that // everything is fine here. - if (tx.nType == TRANSACTION_PROVIDER_REGISTER) { - auto proTx = *Assert(GetTxPayload(tx)); - if (!proTx.collateralOutpoint.hash.IsNull()) { - mapProTxRefs.emplace(tx.GetHash(), proTx.collateralOutpoint.hash); - } - mapProTxAddresses.emplace(proTx.addr, tx.GetHash()); - mapProTxPubKeyIDs.emplace(proTx.keyIDOwner, tx.GetHash()); - mapProTxBlsPubKeyHashes.emplace(proTx.pubKeyOperator.GetHash(), tx.GetHash()); - if (!proTx.collateralOutpoint.hash.IsNull()) { - mapProTxCollaterals.emplace(proTx.collateralOutpoint, tx.GetHash()); - } else { - mapProTxCollaterals.emplace(COutPoint(tx.GetHash(), proTx.collateralOutpoint.n), tx.GetHash()); - } - } else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_SERVICE) { - auto proTx = *Assert(GetTxPayload(tx)); - mapProTxRefs.emplace(proTx.proTxHash, tx.GetHash()); - mapProTxAddresses.emplace(proTx.addr, tx.GetHash()); - } else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_REGISTRAR) { - auto proTx = *Assert(GetTxPayload(tx)); - mapProTxRefs.emplace(proTx.proTxHash, tx.GetHash()); - mapProTxBlsPubKeyHashes.emplace(proTx.pubKeyOperator.GetHash(), tx.GetHash()); - auto dmn = Assert(deterministicMNManager->GetListAtChainTip().GetMN(proTx.proTxHash)); - newit->validForProTxKey = ::SerializeHash(dmn->pdmnState->pubKeyOperator); - if (dmn->pdmnState->pubKeyOperator != proTx.pubKeyOperator) { - newit->isKeyChangeProTx = true; - } - } else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_REVOKE) { - auto proTx = *Assert(GetTxPayload(tx)); - mapProTxRefs.emplace(proTx.proTxHash, tx.GetHash()); - auto dmn = deterministicMNManager->GetListAtChainTip().GetMN(proTx.proTxHash); - assert(dmn); - newit->validForProTxKey = ::SerializeHash(dmn->pdmnState->pubKeyOperator); - if (dmn->pdmnState->pubKeyOperator.Get() != CBLSPublicKey()) { - newit->isKeyChangeProTx = true; - } - } else if (tx.nType == TRANSACTION_ASSET_UNLOCK) { - auto assetUnlockTx = *Assert(GetTxPayload(tx)); - mapAssetUnlockExpiry.insert({tx.GetHash(), assetUnlockTx.getHeightToExpiry()}); - } else if (tx.nType == TRANSACTION_MNHF_SIGNAL) { - PrioritiseTransaction(tx.GetHash(), 0.1 * COIN); + if (m_dmnman) { + addUncheckedProTx(newit, tx); } } @@ -590,6 +559,52 @@ bool CTxMemPool::removeSpentIndex(const uint256 txhash) return true; } +void CTxMemPool::addUncheckedProTx(indexed_transaction_set::iterator& newit, const CTransaction& tx) +{ + assert(m_dmnman); + + if (tx.nType == TRANSACTION_PROVIDER_REGISTER) { + auto proTx = *Assert(GetTxPayload(tx)); + if (!proTx.collateralOutpoint.hash.IsNull()) { + mapProTxRefs.emplace(tx.GetHash(), proTx.collateralOutpoint.hash); + } + mapProTxAddresses.emplace(proTx.addr, tx.GetHash()); + mapProTxPubKeyIDs.emplace(proTx.keyIDOwner, tx.GetHash()); + mapProTxBlsPubKeyHashes.emplace(proTx.pubKeyOperator.GetHash(), tx.GetHash()); + if (!proTx.collateralOutpoint.hash.IsNull()) { + mapProTxCollaterals.emplace(proTx.collateralOutpoint, tx.GetHash()); + } else { + mapProTxCollaterals.emplace(COutPoint(tx.GetHash(), proTx.collateralOutpoint.n), tx.GetHash()); + } + } else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_SERVICE) { + auto proTx = *Assert(GetTxPayload(tx)); + mapProTxRefs.emplace(proTx.proTxHash, tx.GetHash()); + mapProTxAddresses.emplace(proTx.addr, tx.GetHash()); + } else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_REGISTRAR) { + auto proTx = *Assert(GetTxPayload(tx)); + mapProTxRefs.emplace(proTx.proTxHash, tx.GetHash()); + mapProTxBlsPubKeyHashes.emplace(proTx.pubKeyOperator.GetHash(), tx.GetHash()); + auto dmn = Assert(m_dmnman->GetListAtChainTip().GetMN(proTx.proTxHash)); + newit->validForProTxKey = ::SerializeHash(dmn->pdmnState->pubKeyOperator); + if (dmn->pdmnState->pubKeyOperator != proTx.pubKeyOperator) { + newit->isKeyChangeProTx = true; + } + } else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_REVOKE) { + auto proTx = *Assert(GetTxPayload(tx)); + mapProTxRefs.emplace(proTx.proTxHash, tx.GetHash()); + auto dmn = Assert(m_dmnman->GetListAtChainTip().GetMN(proTx.proTxHash)); + newit->validForProTxKey = ::SerializeHash(dmn->pdmnState->pubKeyOperator); + if (dmn->pdmnState->pubKeyOperator.Get() != CBLSPublicKey()) { + newit->isKeyChangeProTx = true; + } + } else if (tx.nType == TRANSACTION_ASSET_UNLOCK) { + auto assetUnlockTx = *Assert(GetTxPayload(tx)); + mapAssetUnlockExpiry.insert({tx.GetHash(), assetUnlockTx.getHeightToExpiry()}); + } else if (tx.nType == TRANSACTION_MNHF_SIGNAL) { + PrioritiseTransaction(tx.GetHash(), 0.1 * COIN); + } +} + void CTxMemPool::removeUnchecked(txiter it, MemPoolRemovalReason reason) { if (reason != MemPoolRemovalReason::BLOCK) { @@ -615,6 +630,23 @@ void CTxMemPool::removeUnchecked(txiter it, MemPoolRemovalReason reason) } else vTxHashes.clear(); + if (m_dmnman) { + removeUncheckedProTx(it->GetTx()); + } + + totalTxSize -= it->GetTxSize(); + m_total_fee -= it->GetFee(); + cachedInnerUsage -= it->DynamicMemoryUsage(); + cachedInnerUsage -= memusage::DynamicUsage(it->GetMemPoolParentsConst()) + memusage::DynamicUsage(it->GetMemPoolChildrenConst()); + mapTx.erase(it); + nTransactionsUpdated++; + if (minerPolicyEstimator) {minerPolicyEstimator->removeTx(hash, false);} + removeAddressIndex(hash); + removeSpentIndex(hash); +} + +void CTxMemPool::removeUncheckedProTx(const CTransaction& tx) +{ auto eraseProTxRef = [&](const uint256& proTxHash, const uint256& txHash) { auto its = mapProTxRefs.equal_range(proTxHash); for (auto it = its.first; it != its.second;) { @@ -626,40 +658,30 @@ void CTxMemPool::removeUnchecked(txiter it, MemPoolRemovalReason reason) } }; - if (it->GetTx().nType == TRANSACTION_PROVIDER_REGISTER) { - auto proTx = *Assert(GetTxPayload(it->GetTx())); + if (tx.nType == TRANSACTION_PROVIDER_REGISTER) { + auto proTx = *Assert(GetTxPayload(tx)); if (!proTx.collateralOutpoint.IsNull()) { - eraseProTxRef(it->GetTx().GetHash(), proTx.collateralOutpoint.hash); + eraseProTxRef(tx.GetHash(), proTx.collateralOutpoint.hash); } mapProTxAddresses.erase(proTx.addr); mapProTxPubKeyIDs.erase(proTx.keyIDOwner); mapProTxBlsPubKeyHashes.erase(proTx.pubKeyOperator.GetHash()); mapProTxCollaterals.erase(proTx.collateralOutpoint); - mapProTxCollaterals.erase(COutPoint(it->GetTx().GetHash(), proTx.collateralOutpoint.n)); - } else if (it->GetTx().nType == TRANSACTION_PROVIDER_UPDATE_SERVICE) { - auto proTx = *Assert(GetTxPayload(it->GetTx())); - eraseProTxRef(proTx.proTxHash, it->GetTx().GetHash()); + mapProTxCollaterals.erase(COutPoint(tx.GetHash(), proTx.collateralOutpoint.n)); + } else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_SERVICE) { + auto proTx = *Assert(GetTxPayload(tx)); + eraseProTxRef(proTx.proTxHash, tx.GetHash()); mapProTxAddresses.erase(proTx.addr); - } else if (it->GetTx().nType == TRANSACTION_PROVIDER_UPDATE_REGISTRAR) { - auto proTx = *Assert(GetTxPayload(it->GetTx())); - eraseProTxRef(proTx.proTxHash, it->GetTx().GetHash()); + } else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_REGISTRAR) { + auto proTx = *Assert(GetTxPayload(tx)); + eraseProTxRef(proTx.proTxHash, tx.GetHash()); mapProTxBlsPubKeyHashes.erase(proTx.pubKeyOperator.GetHash()); - } else if (it->GetTx().nType == TRANSACTION_PROVIDER_UPDATE_REVOKE) { - auto proTx = *Assert(GetTxPayload(it->GetTx())); - eraseProTxRef(proTx.proTxHash, it->GetTx().GetHash()); - } else if (it->GetTx().nType == TRANSACTION_ASSET_UNLOCK) { - mapAssetUnlockExpiry.erase(it->GetTx().GetHash()); + } else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_REVOKE) { + auto proTx = *Assert(GetTxPayload(tx)); + eraseProTxRef(proTx.proTxHash, tx.GetHash()); + } else if (tx.nType == TRANSACTION_ASSET_UNLOCK) { + mapAssetUnlockExpiry.erase(tx.GetHash()); } - - totalTxSize -= it->GetTxSize(); - m_total_fee -= it->GetFee(); - cachedInnerUsage -= it->DynamicMemoryUsage(); - cachedInnerUsage -= memusage::DynamicUsage(it->GetMemPoolParentsConst()) + memusage::DynamicUsage(it->GetMemPoolChildrenConst()); - mapTx.erase(it); - nTransactionsUpdated++; - if (minerPolicyEstimator) {minerPolicyEstimator->removeTx(hash, false);} - removeAddressIndex(hash); - removeSpentIndex(hash); } // Calculates descendants of entry that are not already in setDescendants, and adds to @@ -829,6 +851,8 @@ void CTxMemPool::removeProTxCollateralConflicts(const CTransaction &tx, const CO void CTxMemPool::removeProTxSpentCollateralConflicts(const CTransaction &tx) { + assert(m_dmnman); + // Remove TXs that refer to a MN for which the collateral was spent auto removeSpentCollateralConflict = [&](const uint256& proTxHash) { // Can't use equal_range here as every call to removeRecursive might invalidate iterators @@ -849,7 +873,7 @@ void CTxMemPool::removeProTxSpentCollateralConflicts(const CTransaction &tx) } } }; - auto mnList = deterministicMNManager->GetListAtChainTip(); + auto mnList = m_dmnman->GetListAtChainTip(); for (const auto& in : tx.vin) { auto collateralIt = mapProTxCollaterals.find(in.prevout); if (collateralIt != mapProTxCollaterals.end()) { @@ -966,7 +990,9 @@ void CTxMemPool::removeForBlock(const std::vector& vtx, unsigne RemoveStaged(stage, true, MemPoolRemovalReason::BLOCK); } removeConflicts(*tx); - removeProTxConflicts(*tx); + if (m_dmnman) { + removeProTxConflicts(*tx); + } ClearPrioritisation(tx->GetHash()); } lastRollingFeeUpdate = GetTime(); @@ -1240,6 +1266,8 @@ TxMempoolInfo CTxMemPool::info(const uint256& hash) const } bool CTxMemPool::existsProviderTxConflict(const CTransaction &tx) const { + assert(m_dmnman); + LOCK(cs); auto hasKeyChangeInMempool = [&](const uint256& proTxHash) { @@ -1293,7 +1321,7 @@ bool CTxMemPool::existsProviderTxConflict(const CTransaction &tx) const { auto& proTx = *opt_proTx; // this method should only be called with validated ProTxs - auto dmn = deterministicMNManager->GetListAtChainTip().GetMN(proTx.proTxHash); + auto dmn = m_dmnman->GetListAtChainTip().GetMN(proTx.proTxHash); if (!dmn) { LogPrint(BCLog::MEMPOOL, "%s: ERROR: Masternode is not in the list, proTxHash: %s\n", __func__, proTx.proTxHash.ToString()); return true; // i.e. failed to find validated ProTx == conflict @@ -1315,7 +1343,7 @@ bool CTxMemPool::existsProviderTxConflict(const CTransaction &tx) const { } auto& proTx = *opt_proTx; // this method should only be called with validated ProTxs - auto dmn = deterministicMNManager->GetListAtChainTip().GetMN(proTx.proTxHash); + auto dmn = m_dmnman->GetListAtChainTip().GetMN(proTx.proTxHash); if (!dmn) { LogPrint(BCLog::MEMPOOL, "%s: ERROR: Masternode is not in the list, proTxHash: %s\n", __func__, proTx.proTxHash.ToString()); return true; // i.e. failed to find validated ProTx == conflict diff --git a/src/txmempool.h b/src/txmempool.h index 34536cd5b7f7..fe93c641fa32 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -361,6 +361,7 @@ struct entry_time {}; struct ancestor_score {}; class CBlockPolicyEstimator; +class CDeterministicMNManager; /** * Information about a mempool transaction. @@ -472,6 +473,7 @@ class CTxMemPool const int m_check_ratio; //!< Value n means that 1 times in n we check. std::atomic nTransactionsUpdated{0}; //!< Used by getblocktemplate to trigger CreateNewBlock() invocation CBlockPolicyEstimator* minerPolicyEstimator; + CDeterministicMNManager* m_dmnman{nullptr}; uint64_t totalTxSize GUARDED_BY(cs); //!< sum of all mempool tx' byte sizes CAmount m_total_fee GUARDED_BY(cs); //!< sum of all mempool tx's fees (NOT modified fee) @@ -599,6 +601,21 @@ class CTxMemPool */ explicit CTxMemPool(CBlockPolicyEstimator* estimator = nullptr, int check_ratio = 0); + /** + * Set CDeterministicMNManager pointer. + * + * Separated from constructor as it's initialized after CTxMemPool + * is created. Required for ProTx processing. + */ + void ConnectManagers(CDeterministicMNManager* dmnman); + + /** + * Reset CDeterministicMNManager pointer. + * + * @pre Must be called before CDeterministicMNManager is destroyed. + */ + void DisconnectManagers() { m_dmnman = nullptr; } + /** * If sanity-checking is turned on, check makes sure the pool is * consistent (does not contain two transactions that spend the same inputs, @@ -759,6 +776,10 @@ class CTxMemPool TxMempoolInfo info(const uint256& hash) const; std::vector infoAll() const; + /** + * @pre Caller must ensure that CDeterministicMNManager exists and has been + * set using ConnectManagers() for the CTxMemPool instance. + */ bool existsProviderTxConflict(const CTransaction &tx) const; size_t DynamicMemoryUsage() const; @@ -816,6 +837,12 @@ class CTxMemPool /** Sever link between specified transaction and direct children. */ void UpdateChildrenForRemoval(txiter entry) EXCLUSIVE_LOCKS_REQUIRED(cs); + /** + * addUnchecked extension for Dash-specific transactions (ProTx). + * Depends on CDeterministicMNManager. + */ + void addUncheckedProTx(indexed_transaction_set::iterator& newit, const CTransaction& tx); + /** Before calling removeUnchecked for a given transaction, * UpdateForRemoveFromMempool must be called on the entire (dependent) set * of transactions being removed at the same time. We use each @@ -825,6 +852,8 @@ class CTxMemPool * removal. */ void removeUnchecked(txiter entry, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs); + void removeUncheckedProTx(const CTransaction& tx); + public: /** visited marks a CTxMemPoolEntry as having been traversed * during the lifetime of the most recently created Epoch::Guard