From a247a63d70d38eca0f618858ea0b178dae9a8993 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Thu, 4 Apr 2024 10:02:07 +0000 Subject: [PATCH 1/5] refactor: make CTxMemPool ProTx paths conditional on CDeterministicMNManager presence Despite removeUnchecked not explicitly requiring CDeterministicMNManager, it has also been made conditional due to addUnchecked requiring the manager and allowing for some operations but not others when pertaining to a transaction type could allow inconsistencies to arise. Better to treat as one unit and skip both if manager isn't present. --- src/txmempool.cpp | 153 ++++++++++++++++++++++++++-------------------- src/txmempool.h | 9 +++ 2 files changed, 96 insertions(+), 66 deletions(-) diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 6b06b37d2c77..2c79cd291b06 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -415,46 +415,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 (::deterministicMNManager) { + addUncheckedProTx(newit, tx); } } @@ -590,6 +552,52 @@ bool CTxMemPool::removeSpentIndex(const uint256 txhash) return true; } +void CTxMemPool::addUncheckedProTx(indexed_transaction_set::iterator& newit, const CTransaction& tx) +{ + assert(::deterministicMNManager); + + 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 = Assert(deterministicMNManager->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 +623,23 @@ void CTxMemPool::removeUnchecked(txiter it, MemPoolRemovalReason reason) } else vTxHashes.clear(); + if (::deterministicMNManager) { + 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 +651,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 +844,8 @@ void CTxMemPool::removeProTxCollateralConflicts(const CTransaction &tx, const CO void CTxMemPool::removeProTxSpentCollateralConflicts(const CTransaction &tx) { + assert(::deterministicMNManager); + // 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 @@ -966,7 +983,9 @@ void CTxMemPool::removeForBlock(const std::vector& vtx, unsigne RemoveStaged(stage, true, MemPoolRemovalReason::BLOCK); } removeConflicts(*tx); - removeProTxConflicts(*tx); + if (::deterministicMNManager) { + removeProTxConflicts(*tx); + } ClearPrioritisation(tx->GetHash()); } lastRollingFeeUpdate = GetTime(); @@ -1240,6 +1259,8 @@ TxMempoolInfo CTxMemPool::info(const uint256& hash) const } bool CTxMemPool::existsProviderTxConflict(const CTransaction &tx) const { + assert(::deterministicMNManager); + LOCK(cs); auto hasKeyChangeInMempool = [&](const uint256& proTxHash) { diff --git a/src/txmempool.h b/src/txmempool.h index 34536cd5b7f7..fa86c8a02f88 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -759,6 +759,7 @@ class CTxMemPool TxMempoolInfo info(const uint256& hash) const; std::vector infoAll() const; + /** @pre Caller must ensure that CDeterministicMNManager exists */ bool existsProviderTxConflict(const CTransaction &tx) const; size_t DynamicMemoryUsage() const; @@ -816,6 +817,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 +832,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 From c99fb42ddfb72dbe6a2ae558edee6beb0b646ae8 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Tue, 2 Apr 2024 14:00:22 +0000 Subject: [PATCH 2/5] refactor: remove CMasternodeSync global, move to NodeContext --- src/coinjoin/client.cpp | 1 - src/evo/mnauth.cpp | 5 +-- src/evo/mnauth.h | 4 ++- src/governance/governance.cpp | 54 ++++++++++++++++++------------ src/governance/governance.h | 16 ++++----- src/governance/object.cpp | 4 +-- src/governance/object.h | 3 +- src/governance/vote.cpp | 4 +-- src/governance/vote.h | 3 +- src/init.cpp | 13 ++++--- src/llmq/chainlocks.cpp | 6 ++-- src/llmq/chainlocks.h | 6 ++-- src/llmq/context.cpp | 8 ++--- src/llmq/context.h | 3 +- src/llmq/quorums.cpp | 10 +++--- src/llmq/quorums.h | 4 +-- src/masternode/sync.cpp | 1 - src/masternode/sync.h | 2 -- src/net_processing.cpp | 2 +- src/node/context.cpp | 5 +-- src/node/context.h | 2 +- src/node/interfaces.cpp | 2 +- src/rpc/governance.cpp | 2 +- src/rpc/net.cpp | 2 +- src/test/denialofservice_tests.cpp | 1 + src/test/util/setup_common.cpp | 10 +++--- 26 files changed, 91 insertions(+), 82 deletions(-) diff --git a/src/coinjoin/client.cpp b/src/coinjoin/client.cpp index 007bbe55f200..d8e0d51ef161 100644 --- a/src/coinjoin/client.cpp +++ b/src/coinjoin/client.cpp @@ -1890,7 +1890,6 @@ 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) diff --git a/src/evo/mnauth.cpp b/src/evo/mnauth.cpp index 032492ebc6ad..67ee0ea4eef8 100644 --- a/src/evo/mnauth.cpp +++ b/src/evo/mnauth.cpp @@ -61,11 +61,12 @@ void CMNAuth::PushMNAUTH(CNode& peer, CConnman& connman, const CBlockIndex* tip) 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, const CMasternodeSync& mn_sync, + const CDeterministicMNList& tip_mn_list, std::string_view msg_type, CDataStream& vRecv) { assert(::mmetaman->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 {}; } diff --git a/src/evo/mnauth.h b/src/evo/mnauth.h index e4311e3c0eff..fa6d231f94cf 100644 --- a/src/evo/mnauth.h +++ b/src/evo/mnauth.h @@ -16,6 +16,7 @@ class CDeterministicMN; class CDeterministicMNList; class CDeterministicMNListDiff; class CDeterministicMNManager; +class CMasternodeSync; class CNode; class UniValue; @@ -54,7 +55,8 @@ class CMNAuth * @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, 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..1c1ed3a1e326 100644 --- a/src/governance/governance.cpp +++ b/src/governance/governance.cpp @@ -43,10 +43,13 @@ GovernanceStore::GovernanceStore() : { } -CGovernanceManager::CGovernanceManager(CNetFulfilledRequestManager& netfulfilledman, const std::unique_ptr& dmnman) : +CGovernanceManager::CGovernanceManager(CNetFulfilledRequestManager& netfulfilledman, + const std::unique_ptr& dmnman, + const std::unique_ptr& mn_sync) : m_db{std::make_unique("governance.dat", "magicGovernanceCache")}, m_netfulfilledman{netfulfilledman}, m_dmnman{dmnman}, + m_mn_sync{mn_sync}, nTimeLastDiff(0), nCachedBlockHeight(0), setRequestedObjects(), @@ -118,7 +121,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 +129,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 +160,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 +228,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 +246,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 {}; @@ -273,7 +276,7 @@ void CGovernanceManager::CheckOrphanVotes(CGovernanceObject& govobj, CConnman& c if (pairVote.second < nNow) { fRemove = true; } else if (govobj.ProcessVote(*this, tip_mn_list, vote, e)) { - vote.Relay(connman, tip_mn_list); + vote.Relay(connman, *Assert(m_mn_sync), tip_mn_list); fRemove = true; } if (fRemove) { @@ -327,12 +330,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 @@ -347,7 +350,7 @@ void CGovernanceManager::CheckAndRemove() assert(::mmetaman->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"); @@ -562,7 +565,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; @@ -788,7 +791,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 +805,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 +858,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 +910,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 +1000,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 +1058,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); @@ -1111,7 +1123,7 @@ bool CGovernanceManager::ProcessVote(CNode* pfrom, const CGovernanceVote& vote, void CGovernanceManager::CheckPostponedObjects(CConnman& connman) { - if (!::masternodeSync->IsSynced()) return; + if (!Assert(m_mn_sync)->IsSynced()) return; LOCK2(cs_main, cs); @@ -1159,7 +1171,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; @@ -1530,7 +1542,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..8483023fba8d 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,7 @@ class CDeterministicMNManager; class CGovernanceManager; class CGovernanceObject; class CGovernanceVote; +class CMasternodeSync; class CNetFulfilledRequestManager; class CSporkManager; @@ -257,6 +257,7 @@ class CGovernanceManager : public GovernanceStore 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 +271,9 @@ class CGovernanceManager : public GovernanceStore std::map> mapTrigger; public: - explicit CGovernanceManager(CNetFulfilledRequestManager& netfulfilledman, const std::unique_ptr& dmnman); + explicit CGovernanceManager(CNetFulfilledRequestManager& netfulfilledman, + const std::unique_ptr& dmnman, + const std::unique_ptr& mn_sync); ~CGovernanceManager(); bool LoadCache(bool load_cache); @@ -337,14 +340,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); diff --git a/src/governance/object.cpp b/src/governance/object.cpp index 3553ccafb4ce..3217b3703b37 100644 --- a/src/governance/object.cpp +++ b/src/governance/object.cpp @@ -628,10 +628,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..5ee5e3f79f73 100644 --- a/src/governance/object.h +++ b/src/governance/object.h @@ -19,6 +19,7 @@ class CDeterministicMNList; class CGovernanceManager; class CGovernanceObject; class CGovernanceVote; +class CMasternodeSync; class CNode; extern RecursiveMutex cs_main; @@ -247,7 +248,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; 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..86b86273fa89 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -305,8 +305,7 @@ 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(); @@ -1687,7 +1686,7 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc node.netfulfilledman = std::make_unique(); assert(!node.govman); - node.govman = std::make_unique(*node.netfulfilledman, ::deterministicMNManager); + node.govman = std::make_unique(*node.netfulfilledman, ::deterministicMNManager, node.mn_sync); assert(!node.sporkman); node.sporkman = std::make_unique(); @@ -1716,9 +1715,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", ""); @@ -1962,7 +1960,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.mnhf_manager, *node.sporkman, + *node.mempool, node.mn_activeman, *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(); 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..5228d358d659 100644 --- a/src/llmq/context.cpp +++ b/src/llmq/context.cpp @@ -21,7 +21,7 @@ LLMQContext::LLMQContext(CChainState& chainstate, CConnman& connman, CDeterministicMNManager& dmnman, CEvoDB& evo_db, CMNHFManager& mnhfman, CSporkManager& sporkman, CTxMemPool& mempool, const CActiveMasternodeManager* const mn_activeman, - const std::unique_ptr& peerman, bool unit_tests, bool wipe) : + const CMasternodeSync& mn_sync, const std::unique_ptr& peerman, bool unit_tests, bool wipe) : bls_worker{std::make_shared()}, dkg_debugman{std::make_unique()}, quorum_block_processor{[&]() -> llmq::CQuorumBlockProcessor* const { @@ -32,19 +32,19 @@ LLMQContext::LLMQContext(CChainState& chainstate, CConnman& connman, CDeterminis qdkgsman{std::make_unique(*bls_worker, chainstate, connman, dmnman, *dkg_debugman, *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..b3723fc973ef 100644 --- a/src/llmq/context.h +++ b/src/llmq/context.h @@ -14,6 +14,7 @@ class CConnman; class CDeterministicMNManager; class CDBWrapper; class CEvoDB; +class CMasternodeSync; class CMNHFManager; class CSporkManager; class CTxMemPool; @@ -36,7 +37,7 @@ struct LLMQContext { 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, - const std::unique_ptr& peerman, bool unit_tests, bool wipe); + const CMasternodeSync& mn_sync, const std::unique_ptr& peerman, bool unit_tests, bool wipe); ~LLMQContext(); void Interrupt(); 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/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..6051b3a38f58 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -4625,7 +4625,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_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/node/context.cpp b/src/node/context.cpp index f92008007b6b..52c110b3416a 100644 --- a/src/node/context.cpp +++ b/src/node/context.cpp @@ -9,12 +9,13 @@ #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..13dc1826cc16 100644 --- a/src/node/context.h +++ b/src/node/context.h @@ -76,6 +76,7 @@ struct NodeContext { std::unique_ptr chain_helper; std::unique_ptr govman; std::unique_ptr cj_ctx; + std::unique_ptr mn_sync; std::unique_ptr mnhf_manager; std::unique_ptr netfulfilledman; std::unique_ptr sporkman; @@ -83,7 +84,6 @@ struct NodeContext { 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/test/denialofservice_tests.cpp b/src/test/denialofservice_tests.cpp index 66a24a65c14a..7361ea811f83 100644 --- a/src/test/denialofservice_tests.cpp +++ b/src/test/denialofservice_tests.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 76f32ec3db68..bda6b0468f00 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -116,7 +116,7 @@ void DashTestSetup(NodeContext& node, const CChainParams& chainparams) 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); + /* 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)); } @@ -231,9 +231,8 @@ ChainTestingSetup::ChainTestingSetup(const std::string& chainName, const std::ve m_node.mn_metaman = ::mmetaman.get(); 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.netfulfilledman, ::deterministicMNManager, 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,8 +246,7 @@ 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(); From 81b1247e6d04749482286a4037e0a20471d95bc2 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Sat, 30 Mar 2024 00:16:48 +0000 Subject: [PATCH 3/5] refactor: remove CActiveMasternodeManager global, move to NodeContext --- src/dsnotificationinterface.cpp | 4 +++- src/dsnotificationinterface.h | 3 +++ src/evo/mnauth.cpp | 17 ++++++++------- src/evo/mnauth.h | 6 +++-- src/governance/governance.cpp | 35 ++++++++++++++++++------------ src/governance/governance.h | 11 ++++++---- src/init.cpp | 22 +++++++++---------- src/masternode/node.cpp | 3 --- src/masternode/node.h | 2 -- src/net_processing.cpp | 13 +++++++---- src/net_processing.h | 2 ++ src/node/blockstorage.cpp | 5 ++--- src/node/blockstorage.h | 3 ++- src/node/context.cpp | 1 + src/node/context.h | 2 +- src/rpc/quorums.cpp | 2 +- src/test/denialofservice_tests.cpp | 8 +++---- src/test/util/setup_common.cpp | 4 ++-- 18 files changed, 81 insertions(+), 62 deletions(-) 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/mnauth.cpp b/src/evo/mnauth.cpp index 67ee0ea4eef8..ff733cfe4215 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,15 +54,15 @@ 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 CMasternodeSync& mn_sync, +PeerMsgRet CMNAuth::ProcessMessage(CNode& peer, CConnman& connman, const CActiveMasternodeManager* const mn_activeman, const CMasternodeSync& mn_sync, const CDeterministicMNList& tip_mn_list, std::string_view msg_type, CDataStream& vRecv) { assert(::mmetaman->IsValid()); @@ -134,7 +135,7 @@ PeerMsgRet CMNAuth::ProcessMessage(CNode& peer, CConnman& connman, const CMaster } 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 fa6d231f94cf..1212efbb204e 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; @@ -49,13 +50,14 @@ 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 CMasternodeSync& mn_sync, + static PeerMsgRet ProcessMessage(CNode& peer, CConnman& connman, 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 1c1ed3a1e326..31dbe42a3928 100644 --- a/src/governance/governance.cpp +++ b/src/governance/governance.cpp @@ -671,8 +671,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; @@ -696,12 +699,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); @@ -718,11 +721,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); @@ -731,7 +735,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)) { @@ -1466,7 +1473,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 @@ -1478,8 +1485,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); diff --git a/src/governance/governance.h b/src/governance/governance.h index 8483023fba8d..58e070ce5f8a 100644 --- a/src/governance/governance.h +++ b/src/governance/governance.h @@ -311,7 +311,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; } @@ -366,9 +366,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/init.cpp b/src/init.cpp index 86b86273fa89..4f3dfc430d73 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -368,9 +368,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(); @@ -1727,17 +1726,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, ::deterministicMNManager); + 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(), ::deterministicMNManager, node.cj_ctx, node.llmq_ctx, ignores_incoming_txs); RegisterValidationInterface(node.peerman.get()); @@ -1862,7 +1860,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(), ::deterministicMNManager, node.llmq_ctx, node.cj_ctx ); RegisterValidationInterface(pdsNotificationInterface); @@ -1961,7 +1959,7 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc } node.llmq_ctx.reset(); node.llmq_ctx = std::make_unique(chainman.ActiveChainstate(), *node.connman, *node.dmnman, *node.evodb, *node.mnhf_manager, *node.sporkman, - *node.mempool, node.mn_activeman, *node.mn_sync, node.peerman, /* unit_tests = */ false, /* wipe = */ fReset || fReindexChainState); + *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(); @@ -2206,7 +2204,7 @@ 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.cj_ctx = std::make_unique(chainman.ActiveChainstate(), *node.connman, *node.dmnman, *node.mempool, node.mn_activeman.get(), *node.mn_sync, !ignores_incoming_txs); #ifdef ENABLE_WALLET @@ -2379,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/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/net_processing.cpp b/src/net_processing.cpp index 6051b3a38f58..24d1c0ff819f 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_mn_sync, m_dmnman->GetListAtChainTip(), msg_type, vRecv), pfrom); + ProcessPeerMsgRet(CMNAuth::ProcessMessage(pfrom, m_connman, 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 52c110b3416a..7592fbe95fa1 100644 --- a/src/node/context.cpp +++ b/src/node/context.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/src/node/context.h b/src/node/context.h index 13dc1826cc16..09e3c07826db 100644 --- a/src/node/context.h +++ b/src/node/context.h @@ -71,6 +71,7 @@ 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; @@ -81,7 +82,6 @@ struct NodeContext { std::unique_ptr netfulfilledman; std::unique_ptr sporkman; std::unique_ptr llmq_ctx; - CActiveMasternodeManager* mn_activeman{nullptr}; CDeterministicMNManager* dmnman{nullptr}; CMasternodeMetaMan* mn_metaman{nullptr}; 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 7361ea811f83..005d4f408056 100644 --- a/src/test/denialofservice_tests.cpp +++ b/src/test/denialofservice_tests.cpp @@ -67,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, ::deterministicMNManager, m_node.cj_ctx, m_node.llmq_ctx, /* ignore_incoming_txs = */ false); // Mock an outbound peer @@ -138,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, ::deterministicMNManager, m_node.cj_ctx, m_node.llmq_ctx, /* ignore_incoming_txs = */ false); constexpr int max_outbound_full_relay = MAX_OUTBOUND_FULL_RELAY_CONNECTIONS; @@ -213,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, ::deterministicMNManager, m_node.cj_ctx, m_node.llmq_ctx, /* ignore_incoming_txs = */ false); banman->ClearBanned(); @@ -261,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, ::deterministicMNManager, m_node.cj_ctx, m_node.llmq_ctx, /* ignore_incoming_txs = */ false); banman->ClearBanned(); diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index bda6b0468f00..b10f7f4e094f 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -284,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, ::deterministicMNManager, + m_node.cj_ctx, m_node.llmq_ctx, /* ignore_incoming_txs = */ false); { CConnman::Options options; options.m_msgproc = m_node.peerman.get(); From cf90cf20c6821615af29099fbf36788cb7d62f53 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Sat, 30 Mar 2024 19:12:34 +0000 Subject: [PATCH 4/5] refactor: remove CMasternodeMetaMan global, move to NodeContext --- src/coinjoin/client.cpp | 31 ++++++++++++++++--------------- src/coinjoin/client.h | 27 +++++++++++++++++---------- src/coinjoin/context.cpp | 11 ++++++----- src/coinjoin/context.h | 6 ++++-- src/coinjoin/server.cpp | 20 ++++++++++---------- src/coinjoin/server.h | 6 +++++- src/evo/mnauth.cpp | 8 ++++---- src/evo/mnauth.h | 5 +++-- src/governance/governance.cpp | 13 +++++++------ src/governance/governance.h | 4 +++- src/governance/object.cpp | 7 ++++--- src/governance/object.h | 4 +++- src/init.cpp | 16 +++++++--------- src/llmq/context.cpp | 7 ++++--- src/llmq/context.h | 6 ++++-- src/llmq/dkgsession.cpp | 4 ++-- src/llmq/dkgsession.h | 15 +++++++++------ src/llmq/dkgsessionhandler.cpp | 13 +++++++------ src/llmq/dkgsessionhandler.h | 8 +++++--- src/llmq/dkgsessionmgr.cpp | 6 +++--- src/llmq/dkgsessionmgr.h | 5 +++-- src/llmq/utils.cpp | 10 +++++----- src/llmq/utils.h | 10 ++++++---- src/masternode/meta.cpp | 2 -- src/masternode/meta.h | 2 -- src/net_processing.cpp | 2 +- src/node/context.cpp | 1 + src/node/context.h | 2 +- src/test/util/setup_common.cpp | 13 ++++++------- 29 files changed, 146 insertions(+), 118 deletions(-) diff --git a/src/coinjoin/client.cpp b/src/coinjoin/client.cpp index d8e0d51ef161..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; } @@ -1892,7 +1893,7 @@ void CCoinJoinClientManager::GetJsonInfo(UniValue& obj) const void CoinJoinWalletManager::Add(CWallet& wallet) { 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/evo/mnauth.cpp b/src/evo/mnauth.cpp index ff733cfe4215..6c61dc5af176 100644 --- a/src/evo/mnauth.cpp +++ b/src/evo/mnauth.cpp @@ -62,10 +62,10 @@ void CMNAuth::PushMNAUTH(CNode& peer, CConnman& connman, const CActiveMasternode connman.PushMessage(&peer, CNetMsgMaker(peer.GetCommonVersion()).Make(NetMsgType::MNAUTH, mnauth)); } -PeerMsgRet CMNAuth::ProcessMessage(CNode& peer, CConnman& connman, const CActiveMasternodeManager* const mn_activeman, const CMasternodeSync& mn_sync, - 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 || !mn_sync.IsBlockchainSynced()) { // we can't verify MNAUTH messages when we don't have the latest MN list @@ -125,7 +125,7 @@ PeerMsgRet CMNAuth::ProcessMessage(CNode& peer, CConnman& connman, const CActive } 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()); diff --git a/src/evo/mnauth.h b/src/evo/mnauth.h index 1212efbb204e..211dae0cf20c 100644 --- a/src/evo/mnauth.h +++ b/src/evo/mnauth.h @@ -17,6 +17,7 @@ class CDeterministicMN; class CDeterministicMNList; class CDeterministicMNListDiff; class CDeterministicMNManager; +class CMasternodeMetaMan; class CMasternodeSync; class CNode; @@ -57,8 +58,8 @@ class CMNAuth * @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 CActiveMasternodeManager* const mn_activeman, const CMasternodeSync& mn_sync, - 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 31dbe42a3928..021411112768 100644 --- a/src/governance/governance.cpp +++ b/src/governance/governance.cpp @@ -43,10 +43,11 @@ GovernanceStore::GovernanceStore() : { } -CGovernanceManager::CGovernanceManager(CNetFulfilledRequestManager& netfulfilledman, +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}, @@ -275,7 +276,7 @@ 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)) { + } 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; } @@ -347,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 (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(); @@ -401,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(); @@ -1123,7 +1124,7 @@ 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; } diff --git a/src/governance/governance.h b/src/governance/governance.h index 58e070ce5f8a..cad15d52aa37 100644 --- a/src/governance/governance.h +++ b/src/governance/governance.h @@ -25,6 +25,7 @@ class CDeterministicMNManager; class CGovernanceManager; class CGovernanceObject; class CGovernanceVote; +class CMasternodeMetaMan; class CMasternodeSync; class CNetFulfilledRequestManager; class CSporkManager; @@ -255,6 +256,7 @@ 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; @@ -271,7 +273,7 @@ class CGovernanceManager : public GovernanceStore std::map> mapTrigger; public: - explicit CGovernanceManager(CNetFulfilledRequestManager& netfulfilledman, + explicit CGovernanceManager(CMasternodeMetaMan& mn_metaman, CNetFulfilledRequestManager& netfulfilledman, const std::unique_ptr& dmnman, const std::unique_ptr& mn_sync); ~CGovernanceManager(); diff --git a/src/governance/object.cpp b/src/governance/object.cpp index 3217b3703b37..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() diff --git a/src/governance/object.h b/src/governance/object.h index 5ee5e3f79f73..d7f22bad9bf9 100644 --- a/src/governance/object.h +++ b/src/governance/object.h @@ -19,6 +19,7 @@ class CDeterministicMNList; class CGovernanceManager; class CGovernanceObject; class CGovernanceVote; +class CMasternodeMetaMan; class CMasternodeSync; class CNode; @@ -290,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/init.cpp b/src/init.cpp index 4f3dfc430d73..02154bf68646 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -309,8 +309,7 @@ void PrepareShutdown(NodeContext& node) 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) { @@ -1677,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.mn_sync); + node.govman = std::make_unique(*node.mn_metaman, *node.netfulfilledman, ::deterministicMNManager, node.mn_sync); assert(!node.sporkman); node.sporkman = std::make_unique(); @@ -1958,7 +1956,7 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc node.llmq_ctx->Stop(); } node.llmq_ctx.reset(); - node.llmq_ctx = std::make_unique(chainman.ActiveChainstate(), *node.connman, *node.dmnman, *node.evodb, *node.mnhf_manager, *node.sporkman, + 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(); @@ -2204,8 +2202,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.get(), - *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); diff --git a/src/llmq/context.cpp b/src/llmq/context.cpp index 5228d358d659..cc32e7a0dd78 100644 --- a/src/llmq/context.cpp +++ b/src/llmq/context.cpp @@ -20,8 +20,9 @@ #include LLMQContext::LLMQContext(CChainState& chainstate, CConnman& connman, CDeterministicMNManager& dmnman, CEvoDB& evo_db, - 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) : + 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()}, quorum_block_processor{[&]() -> llmq::CQuorumBlockProcessor* const { @@ -29,7 +30,7 @@ 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, mn_sync, sporkman); diff --git a/src/llmq/context.h b/src/llmq/context.h index b3723fc973ef..531dcb052567 100644 --- a/src/llmq/context.h +++ b/src/llmq/context.h @@ -14,6 +14,7 @@ class CConnman; class CDeterministicMNManager; class CDBWrapper; class CEvoDB; +class CMasternodeMetaMan; class CMasternodeSync; class CMNHFManager; class CSporkManager; @@ -36,8 +37,9 @@ 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, - const CMasternodeSync& mn_sync, const std::unique_ptr& peerman, bool unit_tests, bool wipe); + 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(); void Interrupt(); 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/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/net_processing.cpp b/src/net_processing.cpp index 24d1c0ff819f..96c3766fda2e 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -4630,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_mn_activeman, m_mn_sync, 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/node/context.cpp b/src/node/context.cpp index 7592fbe95fa1..7aa05d0288cd 100644 --- a/src/node/context.cpp +++ b/src/node/context.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/src/node/context.h b/src/node/context.h index 09e3c07826db..604227ff7a18 100644 --- a/src/node/context.h +++ b/src/node/context.h @@ -77,13 +77,13 @@ struct NodeContext { std::unique_ptr chain_helper; 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; CDeterministicMNManager* dmnman{nullptr}; - CMasternodeMetaMan* mn_metaman{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/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index b10f7f4e094f..3ab291a77786 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -111,11 +111,12 @@ void DashTestSetup(NodeContext& node, const CChainParams& chainparams) ::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.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, + 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)); @@ -227,11 +228,10 @@ 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, m_node.mn_sync); + m_node.govman = std::make_unique(*m_node.mn_metaman, *m_node.netfulfilledman, ::deterministicMNManager, 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. @@ -250,8 +250,7 @@ ChainTestingSetup::~ChainTestingSetup() 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; From a5be37c58b729c2d3558178bd1fc8f917e7395c0 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Thu, 4 Apr 2024 10:27:33 +0000 Subject: [PATCH 5/5] refactor: remove CDeterministicMNManager global, move to NodeContext --- src/evo/deterministicmns.cpp | 2 -- src/evo/deterministicmns.h | 2 -- src/init.cpp | 20 +++++++++-------- src/node/context.cpp | 3 ++- src/node/context.h | 2 +- src/test/denialofservice_tests.cpp | 8 +++---- src/test/evo_deterministicmns_tests.cpp | 6 +++++ src/test/util/setup_common.cpp | 13 ++++++----- src/txmempool.cpp | 29 +++++++++++++++---------- src/txmempool.h | 22 ++++++++++++++++++- 10 files changed, 70 insertions(+), 37 deletions(-) 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/init.cpp b/src/init.cpp index 02154bf68646..0b45e98e0347 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -343,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(); @@ -1683,7 +1683,7 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc node.netfulfilledman = std::make_unique(); assert(!node.govman); - node.govman = std::make_unique(*node.mn_metaman, *node.netfulfilledman, ::deterministicMNManager, node.mn_sync); + node.govman = std::make_unique(*node.mn_metaman, *node.netfulfilledman, node.dmnman, node.mn_sync); assert(!node.sporkman); node.sporkman = std::make_unique(); @@ -1725,7 +1725,7 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc fMasternodeMode = true; { // Create and register mn_activeman, will init later in ThreadImport - node.mn_activeman = std::make_unique(keyOperator, *node.connman, ::deterministicMNManager); + node.mn_activeman = std::make_unique(keyOperator, *node.connman, node.dmnman); RegisterValidationInterface(node.mn_activeman.get()); } } @@ -1733,7 +1733,7 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc 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, node.mn_activeman.get(), ::deterministicMNManager, + *node.govman, *node.sporkman, node.mn_activeman.get(), node.dmnman, node.cj_ctx, node.llmq_ctx, ignores_incoming_txs); RegisterValidationInterface(node.peerman.get()); @@ -1858,7 +1858,7 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc #endif pdsNotificationInterface = new CDSNotificationInterface( - *node.connman, *node.mn_sync, *node.govman, node.mn_activeman.get(), ::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); @@ -1943,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)); diff --git a/src/node/context.cpp b/src/node/context.cpp index 7aa05d0288cd..ba850e80af53 100644 --- a/src/node/context.cpp +++ b/src/node/context.cpp @@ -7,8 +7,9 @@ #include #include #include -#include #include +#include +#include #include #include #include diff --git a/src/node/context.h b/src/node/context.h index 604227ff7a18..88d812884233 100644 --- a/src/node/context.h +++ b/src/node/context.h @@ -75,6 +75,7 @@ struct NodeContext { 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; @@ -83,7 +84,6 @@ struct NodeContext { std::unique_ptr netfulfilledman; std::unique_ptr sporkman; std::unique_ptr llmq_ctx; - CDeterministicMNManager* dmnman{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/test/denialofservice_tests.cpp b/src/test/denialofservice_tests.cpp index 005d4f408056..b383e3625d44 100644 --- a/src/test/denialofservice_tests.cpp +++ b/src/test/denialofservice_tests.cpp @@ -67,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, /* mn_activeman = */ nullptr, ::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 @@ -138,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, /* mn_activeman = */ nullptr, ::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; @@ -213,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, /* mn_activeman = */ nullptr, ::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(); @@ -261,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, /* mn_activeman = */ nullptr, ::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 3ab291a77786..027a2a26cfd9 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -109,8 +109,9 @@ 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.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 @@ -131,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(); } @@ -231,7 +232,7 @@ ChainTestingSetup::ChainTestingSetup(const std::string& chainName, const std::ve 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.mn_metaman, *m_node.netfulfilledman, ::deterministicMNManager, m_node.mn_sync); + 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. @@ -283,7 +284,7 @@ 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, /* mn_activeman = */ nullptr, ::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); { CConnman::Options options; diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 2c79cd291b06..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,7 +422,7 @@ 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 (::deterministicMNManager) { + if (m_dmnman) { addUncheckedProTx(newit, tx); } } @@ -554,7 +561,7 @@ bool CTxMemPool::removeSpentIndex(const uint256 txhash) void CTxMemPool::addUncheckedProTx(indexed_transaction_set::iterator& newit, const CTransaction& tx) { - assert(::deterministicMNManager); + assert(m_dmnman); if (tx.nType == TRANSACTION_PROVIDER_REGISTER) { auto proTx = *Assert(GetTxPayload(tx)); @@ -577,7 +584,7 @@ void CTxMemPool::addUncheckedProTx(indexed_transaction_set::iterator& newit, con 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)); + auto dmn = Assert(m_dmnman->GetListAtChainTip().GetMN(proTx.proTxHash)); newit->validForProTxKey = ::SerializeHash(dmn->pdmnState->pubKeyOperator); if (dmn->pdmnState->pubKeyOperator != proTx.pubKeyOperator) { newit->isKeyChangeProTx = true; @@ -585,7 +592,7 @@ void CTxMemPool::addUncheckedProTx(indexed_transaction_set::iterator& newit, con } else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_REVOKE) { auto proTx = *Assert(GetTxPayload(tx)); mapProTxRefs.emplace(proTx.proTxHash, tx.GetHash()); - auto dmn = Assert(deterministicMNManager->GetListAtChainTip().GetMN(proTx.proTxHash)); + auto dmn = Assert(m_dmnman->GetListAtChainTip().GetMN(proTx.proTxHash)); newit->validForProTxKey = ::SerializeHash(dmn->pdmnState->pubKeyOperator); if (dmn->pdmnState->pubKeyOperator.Get() != CBLSPublicKey()) { newit->isKeyChangeProTx = true; @@ -623,7 +630,7 @@ void CTxMemPool::removeUnchecked(txiter it, MemPoolRemovalReason reason) } else vTxHashes.clear(); - if (::deterministicMNManager) { + if (m_dmnman) { removeUncheckedProTx(it->GetTx()); } @@ -844,7 +851,7 @@ void CTxMemPool::removeProTxCollateralConflicts(const CTransaction &tx, const CO void CTxMemPool::removeProTxSpentCollateralConflicts(const CTransaction &tx) { - assert(::deterministicMNManager); + assert(m_dmnman); // Remove TXs that refer to a MN for which the collateral was spent auto removeSpentCollateralConflict = [&](const uint256& proTxHash) { @@ -866,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()) { @@ -983,7 +990,7 @@ void CTxMemPool::removeForBlock(const std::vector& vtx, unsigne RemoveStaged(stage, true, MemPoolRemovalReason::BLOCK); } removeConflicts(*tx); - if (::deterministicMNManager) { + if (m_dmnman) { removeProTxConflicts(*tx); } ClearPrioritisation(tx->GetHash()); @@ -1259,7 +1266,7 @@ TxMempoolInfo CTxMemPool::info(const uint256& hash) const } bool CTxMemPool::existsProviderTxConflict(const CTransaction &tx) const { - assert(::deterministicMNManager); + assert(m_dmnman); LOCK(cs); @@ -1314,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 @@ -1336,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 fa86c8a02f88..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,7 +776,10 @@ class CTxMemPool TxMempoolInfo info(const uint256& hash) const; std::vector infoAll() const; - /** @pre Caller must ensure that CDeterministicMNManager exists */ + /** + * @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;