diff --git a/src/coinjoin/server.cpp b/src/coinjoin/server.cpp index 6b94fdea35ff5..382e95d7eb541 100644 --- a/src/coinjoin/server.cpp +++ b/src/coinjoin/server.cpp @@ -322,7 +322,7 @@ void CCoinJoinServer::CommitFinalTransaction() TRY_LOCK(cs_main, lockMain); TxValidationState validationState; mempool.PrioritiseTransaction(hashTx, 0.1 * COIN); - if (!lockMain || !AcceptToMemoryPool(::ChainstateActive(), mempool, validationState, finalTransaction, false /* bypass_limits */, DEFAULT_MAX_RAW_TX_FEE /* nAbsurdFee */)) { + if (!lockMain || !AcceptToMemoryPool(m_chainstate, mempool, validationState, finalTransaction, false /* bypass_limits */, DEFAULT_MAX_RAW_TX_FEE /* nAbsurdFee */)) { LogPrint(BCLog::COINJOIN, "CCoinJoinServer::CommitFinalTransaction -- AcceptToMemoryPool() error: Transaction not valid\n"); WITH_LOCK(cs_coinjoin, SetNull()); // not much we can do in this case, just notify clients @@ -455,7 +455,7 @@ void CCoinJoinServer::ConsumeCollateral(const CTransactionRef& txref) const { LOCK(cs_main); TxValidationState validationState; - if (!AcceptToMemoryPool(::ChainstateActive(), mempool, validationState, txref, false /* bypass_limits */, 0 /* nAbsurdFee */)) { + if (!AcceptToMemoryPool(m_chainstate, mempool, validationState, txref, false /* bypass_limits */, 0 /* nAbsurdFee */)) { LogPrint(BCLog::COINJOIN, "%s -- AcceptToMemoryPool failed\n", __func__); } else { connman.RelayTransaction(*txref); diff --git a/src/coinjoin/server.h b/src/coinjoin/server.h index 183cd3f32eabf..c2e54aef61ae3 100644 --- a/src/coinjoin/server.h +++ b/src/coinjoin/server.h @@ -8,6 +8,7 @@ #include #include +class CChainState; class CCoinJoinServer; class CTxMemPool; class PeerManager; @@ -22,8 +23,9 @@ extern std::unique_ptr coinJoinServer; class CCoinJoinServer : public CCoinJoinBaseSession, public CCoinJoinBaseManager { private: - CTxMemPool& mempool; + CChainState& m_chainstate; CConnman& connman; + CTxMemPool& mempool; const CMasternodeSync& m_mn_sync; // Mixing uses collateral transactions to trust parties entering the pool @@ -79,9 +81,10 @@ class CCoinJoinServer : public CCoinJoinBaseSession, public CCoinJoinBaseManager void SetNull() EXCLUSIVE_LOCKS_REQUIRED(cs_coinjoin); public: - explicit CCoinJoinServer(CTxMemPool& mempool, CConnman& _connman, const CMasternodeSync& mn_sync) : - mempool(mempool), + explicit CCoinJoinServer(CChainState& chainstate, CConnman& _connman, CTxMemPool& mempool, const CMasternodeSync& mn_sync) : + m_chainstate(chainstate), connman(_connman), + mempool(mempool), m_mn_sync(mn_sync), vecSessionCollaterals(), fUnitTest(false) diff --git a/src/evo/deterministicmns.cpp b/src/evo/deterministicmns.cpp index 169ab1da3e401..8fedeae5df984 100644 --- a/src/evo/deterministicmns.cpp +++ b/src/evo/deterministicmns.cpp @@ -1192,7 +1192,7 @@ bool CDeterministicMNManager::MigrateDBIfNeeded() LogPrintf("CDeterministicMNManager::%s -- upgrading DB to migrate MN type\n", __func__); - if (::ChainActive().Tip() == nullptr) { + if (m_chainstate.m_chain.Tip() == nullptr) { // should have no records LogPrintf("CDeterministicMNManager::%s -- Chain empty. evoDB:%d.\n", __func__, m_evoDb.IsEmpty()); return m_evoDb.IsEmpty(); @@ -1203,7 +1203,7 @@ bool CDeterministicMNManager::MigrateDBIfNeeded() return true; } - if (::ChainActive().Tip()->pprev != nullptr && llmq::utils::IsV19Active(::ChainActive().Tip()->pprev)) { + if (m_chainstate.m_chain.Tip()->pprev != nullptr && llmq::utils::IsV19Active(m_chainstate.m_chain.Tip()->pprev)) { // too late LogPrintf("CDeterministicMNManager::%s -- migration is not possible\n", __func__); return false; @@ -1212,25 +1212,25 @@ bool CDeterministicMNManager::MigrateDBIfNeeded() // Removing the old EVODB_BEST_BLOCK value early results in older version to crash immediately, even if the upgrade // process is cancelled in-between. But if the new version sees that the old EVODB_BEST_BLOCK is already removed, // then we must assume that the upgrade process was already running before but was interrupted. - if (::ChainActive().Height() > 1 && !m_evoDb.GetRawDB().Exists(DB_OLD_BEST_BLOCK)) { + if (m_chainstate.m_chain.Height() > 1 && !m_evoDb.GetRawDB().Exists(DB_OLD_BEST_BLOCK)) { LogPrintf("CDeterministicMNManager::%s -- previous migration attempt failed.\n", __func__); return false; } m_evoDb.GetRawDB().Erase(DB_OLD_BEST_BLOCK); - if (::ChainActive().Height() < Params().GetConsensus().DIP0003Height) { + if (m_chainstate.m_chain.Height() < Params().GetConsensus().DIP0003Height) { // not reached DIP3 height yet, so no upgrade needed LogPrintf("CDeterministicMNManager::%s -- migration not needed. dip3 not reached\n", __func__); auto dbTx = m_evoDb.BeginTransaction(); - m_evoDb.WriteBestBlock(::ChainActive().Tip()->GetBlockHash()); + m_evoDb.WriteBestBlock(m_chainstate.m_chain.Tip()->GetBlockHash()); dbTx->Commit(); return true; } CDBBatch batch(m_evoDb.GetRawDB()); - for (const auto nHeight : irange::range(Params().GetConsensus().DIP0003Height, ::ChainActive().Height() + 1)) { - auto pindex = ::ChainActive()[nHeight]; + for (const auto nHeight : irange::range(Params().GetConsensus().DIP0003Height, m_chainstate.m_chain.Height() + 1)) { + auto pindex = m_chainstate.m_chain[nHeight]; // Unserialise CDeterministicMNListDiff using MN_OLD_FORMAT and set it's type to the default value TYPE_REGULAR_MASTERNODE // It will be later written with format MN_CURRENT_FORMAT which includes the type field and MN state bls version. CDataStream diff_data(SER_DISK, CLIENT_VERSION); @@ -1258,7 +1258,7 @@ bool CDeterministicMNManager::MigrateDBIfNeeded() // Writing EVODB_BEST_BLOCK (which is b_b4 now) marks the DB as upgraded auto dbTx = m_evoDb.BeginTransaction(); - m_evoDb.WriteBestBlock(::ChainActive().Tip()->GetBlockHash()); + m_evoDb.WriteBestBlock(m_chainstate.m_chain.Tip()->GetBlockHash()); dbTx->Commit(); LogPrintf("CDeterministicMNManager::%s -- done migrating\n", __func__); @@ -1291,7 +1291,7 @@ bool CDeterministicMNManager::MigrateDBIfNeeded2() LogPrintf("CDeterministicMNManager::%s -- upgrading DB to migrate MN state bls version\n", __func__); - if (::ChainActive().Tip() == nullptr) { + if (m_chainstate.m_chain.Tip() == nullptr) { // should have no records LogPrintf("CDeterministicMNManager::%s -- Chain empty. evoDB:%d.\n", __func__, m_evoDb.IsEmpty()); return m_evoDb.IsEmpty(); @@ -1302,7 +1302,7 @@ bool CDeterministicMNManager::MigrateDBIfNeeded2() return true; } - if (::ChainActive().Tip()->pprev != nullptr && llmq::utils::IsV19Active(::ChainActive().Tip()->pprev)) { + if (m_chainstate.m_chain.Tip()->pprev != nullptr && llmq::utils::IsV19Active(m_chainstate.m_chain.Tip()->pprev)) { // too late LogPrintf("CDeterministicMNManager::%s -- migration is not possible\n", __func__); return false; @@ -1311,25 +1311,25 @@ bool CDeterministicMNManager::MigrateDBIfNeeded2() // Removing the old EVODB_BEST_BLOCK value early results in older version to crash immediately, even if the upgrade // process is cancelled in-between. But if the new version sees that the old EVODB_BEST_BLOCK is already removed, // then we must assume that the upgrade process was already running before but was interrupted. - if (::ChainActive().Height() > 1 && !m_evoDb.GetRawDB().Exists(DB_OLD_BEST_BLOCK)) { + if (m_chainstate.m_chain.Height() > 1 && !m_evoDb.GetRawDB().Exists(DB_OLD_BEST_BLOCK)) { LogPrintf("CDeterministicMNManager::%s -- previous migration attempt failed.\n", __func__); return false; } m_evoDb.GetRawDB().Erase(DB_OLD_BEST_BLOCK); - if (::ChainActive().Height() < Params().GetConsensus().DIP0003Height) { + if (m_chainstate.m_chain.Height() < Params().GetConsensus().DIP0003Height) { // not reached DIP3 height yet, so no upgrade needed LogPrintf("CDeterministicMNManager::%s -- migration not needed. dip3 not reached\n", __func__); auto dbTx = m_evoDb.BeginTransaction(); - m_evoDb.WriteBestBlock(::ChainActive().Tip()->GetBlockHash()); + m_evoDb.WriteBestBlock(m_chainstate.m_chain.Tip()->GetBlockHash()); dbTx->Commit(); return true; } CDBBatch batch(m_evoDb.GetRawDB()); - for (const auto nHeight : irange::range(Params().GetConsensus().DIP0003Height, ::ChainActive().Height() + 1)) { - auto pindex = ::ChainActive()[nHeight]; + for (const auto nHeight : irange::range(Params().GetConsensus().DIP0003Height, m_chainstate.m_chain.Height() + 1)) { + auto pindex = m_chainstate.m_chain[nHeight]; // Unserialise CDeterministicMNListDiff using MN_TYPE_FORMAT and set MN state bls version to LEGACY_BLS_VERSION. // It will be later written with format MN_CURRENT_FORMAT which includes the type field. CDataStream diff_data(SER_DISK, CLIENT_VERSION); @@ -1357,7 +1357,7 @@ bool CDeterministicMNManager::MigrateDBIfNeeded2() // Writing EVODB_BEST_BLOCK (which is b_b4 now) marks the DB as upgraded auto dbTx = m_evoDb.BeginTransaction(); - m_evoDb.WriteBestBlock(::ChainActive().Tip()->GetBlockHash()); + m_evoDb.WriteBestBlock(m_chainstate.m_chain.Tip()->GetBlockHash()); dbTx->Commit(); LogPrintf("CDeterministicMNManager::%s -- done migrating\n", __func__); diff --git a/src/evo/deterministicmns.h b/src/evo/deterministicmns.h index 23e3e6b9b2c2c..9e7b98fe1fa16 100644 --- a/src/evo/deterministicmns.h +++ b/src/evo/deterministicmns.h @@ -24,9 +24,10 @@ #include #include -class CConnman; class CBlock; class CBlockIndex; +class CChainState; +class CConnman; class TxValidationState; extern RecursiveMutex cs_main; @@ -580,16 +581,17 @@ class CDeterministicMNManager // Main thread has indicated we should perform cleanup up to this height std::atomic to_cleanup {0}; - CEvoDB& m_evoDb; + CChainState& m_chainstate; CConnman& connman; + CEvoDB& m_evoDb; std::unordered_map mnListsCache GUARDED_BY(cs); std::unordered_map mnListDiffsCache GUARDED_BY(cs); const CBlockIndex* tipIndex GUARDED_BY(cs) {nullptr}; public: - explicit CDeterministicMNManager(CEvoDB& evoDb, CConnman& _connman) : - m_evoDb(evoDb), connman(_connman) {} + explicit CDeterministicMNManager(CChainState& chainstate, CConnman& _connman, CEvoDB& evoDb) : + m_chainstate(chainstate), connman(_connman), m_evoDb(evoDb) {} ~CDeterministicMNManager() = default; bool ProcessBlock(const CBlock& block, const CBlockIndex* pindex, BlockValidationState& state, diff --git a/src/init.cpp b/src/init.cpp index 80a72fa1248d6..0d10dc13ca488 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1937,12 +1937,13 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc // Same logic as above with pblocktree deterministicMNManager.reset(); - deterministicMNManager.reset(new CDeterministicMNManager(*node.evodb, *node.connman)); + deterministicMNManager.reset(new CDeterministicMNManager(chainman.ActiveChainstate(), *node.connman, *node.evodb)); + creditPoolManager.reset(); creditPoolManager.reset(new CCreditPoolManager(*node.evodb)); llmq::quorumSnapshotManager.reset(); llmq::quorumSnapshotManager.reset(new llmq::CQuorumSnapshotManager(*node.evodb)); node.llmq_ctx.reset(); - node.llmq_ctx.reset(new LLMQContext(*node.evodb, *node.mempool, *node.connman, *::sporkManager, node.peerman, false, fReset || fReindexChainState)); + node.llmq_ctx.reset(new LLMQContext(chainman.ActiveChainstate(), *node.connman, *node.evodb, *::sporkManager, *node.mempool, node.peerman, false, fReset || fReindexChainState)); if (fReset) { pblocktree->WriteReindexing(true); @@ -2248,7 +2249,7 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc // ********************************************************* Step 10a: Setup CoinJoin - ::coinJoinServer = std::make_unique(*node.mempool, *node.connman, *::masternodeSync); + ::coinJoinServer = std::make_unique(chainman.ActiveChainstate(), *node.connman, *node.mempool, *::masternodeSync); #ifdef ENABLE_WALLET if (!ignores_incoming_txs) { ::coinJoinClientQueueManager = std::make_unique(*node.connman, *::masternodeSync); diff --git a/src/llmq/blockprocessor.cpp b/src/llmq/blockprocessor.cpp index 8ad2c704258b0..509c8445d6c7a 100644 --- a/src/llmq/blockprocessor.cpp +++ b/src/llmq/blockprocessor.cpp @@ -46,8 +46,8 @@ static const std::string DB_MINED_COMMITMENT_BY_INVERSED_HEIGHT_Q_INDEXED = "q_m static const std::string DB_BEST_BLOCK_UPGRADE = "q_bbu2"; -CQuorumBlockProcessor::CQuorumBlockProcessor(CEvoDB& evoDb, CConnman& _connman, const std::unique_ptr& peerman) : - m_evoDb(evoDb), connman(_connman), m_peerman(peerman) +CQuorumBlockProcessor::CQuorumBlockProcessor(CChainState& chainstate, CConnman& _connman, CEvoDB& evoDb, const std::unique_ptr& peerman) : + m_chainstate(chainstate), connman(_connman), m_evoDb(evoDb), m_peerman(peerman) { utils::InitQuorumsCache(mapHasMinedCommitmentCache); } @@ -82,7 +82,7 @@ void CQuorumBlockProcessor::ProcessMessage(const CNode& peer, std::string_view m const CBlockIndex* pQuorumBaseBlockIndex; { LOCK(cs_main); - pQuorumBaseBlockIndex = g_chainman.m_blockman.LookupBlockIndex(qc.quorumHash); + pQuorumBaseBlockIndex = m_chainstate.m_blockman.LookupBlockIndex(qc.quorumHash); if (pQuorumBaseBlockIndex == nullptr) { LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- unknown block %s in commitment, peer=%d\n", __func__, qc.quorumHash.ToString(), peer.GetId()); @@ -90,7 +90,7 @@ void CQuorumBlockProcessor::ProcessMessage(const CNode& peer, std::string_view m // fully synced return; } - if (::ChainActive().Tip()->GetAncestor(pQuorumBaseBlockIndex->nHeight) != pQuorumBaseBlockIndex) { + if (m_chainstate.m_chain.Tip()->GetAncestor(pQuorumBaseBlockIndex->nHeight) != pQuorumBaseBlockIndex) { LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- block %s not in active chain, peer=%d\n", __func__, qc.quorumHash.ToString(), peer.GetId()); // same, can't punish @@ -103,7 +103,7 @@ void CQuorumBlockProcessor::ProcessMessage(const CNode& peer, std::string_view m m_peerman->Misbehaving(peer.GetId(), 100); return; } - if (pQuorumBaseBlockIndex->nHeight < (::ChainActive().Height() - llmq_params_opt->dkgInterval)) { + if (pQuorumBaseBlockIndex->nHeight < (m_chainstate.m_chain.Height() - llmq_params_opt->dkgInterval)) { LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- block %s is too old, peer=%d\n", __func__, qc.quorumHash.ToString(), peer.GetId()); // TODO: enable punishment in some future version when all/most nodes are running with this fix @@ -171,7 +171,7 @@ bool CQuorumBlockProcessor::ProcessBlock(const CBlock& block, const CBlockIndex* // Note: must only check quorums that were enabled at the _previous_ block height to match mining logic for (const Consensus::LLMQParams& params : utils::GetEnabledQuorumParams(pindex->pprev)) { // skip these checks when replaying blocks after the crash - if (::ChainActive().Tip() == nullptr) { + if (m_chainstate.m_chain.Tip() == nullptr) { break; } @@ -234,7 +234,7 @@ bool CQuorumBlockProcessor::ProcessCommitment(int nHeight, const uint256& blockH nHeight, ToUnderlying(qc.llmqType), qc.quorumIndex, quorumHash.ToString(), qc.CountSigners(), qc.CountValidMembers(), qc.quorumPublicKey.ToString(), fJustCheck); // skip `bad-qc-block` checks below when replaying blocks after the crash - if (::ChainActive().Tip() == nullptr) { + if (m_chainstate.m_chain.Tip() == nullptr) { quorumHash = qc.quorumHash; } @@ -268,7 +268,7 @@ bool CQuorumBlockProcessor::ProcessCommitment(int nHeight, const uint256& blockH return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-qc-height"); } - const auto* pQuorumBaseBlockIndex = g_chainman.m_blockman.LookupBlockIndex(qc.quorumHash); + const auto* pQuorumBaseBlockIndex = m_chainstate.m_blockman.LookupBlockIndex(qc.quorumHash); if (!qc.Verify(pQuorumBaseBlockIndex, fBLSChecks)) { LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s height=%d, type=%d, quorumIndex=%d, quorumHash=%s, signers=%s, validMembers=%d, quorumPublicKey=%s qc verify failed.\n", __func__, @@ -358,20 +358,20 @@ bool CQuorumBlockProcessor::UpgradeDB() { LOCK(cs_main); - if (::ChainActive().Tip() == nullptr) { + if (m_chainstate.m_chain.Tip() == nullptr) { // should have no records return m_evoDb.IsEmpty(); } uint256 bestBlock; - if (m_evoDb.GetRawDB().Read(DB_BEST_BLOCK_UPGRADE, bestBlock) && bestBlock == ::ChainActive().Tip()->GetBlockHash()) { + if (m_evoDb.GetRawDB().Read(DB_BEST_BLOCK_UPGRADE, bestBlock) && bestBlock == m_chainstate.m_chain.Tip()->GetBlockHash()) { return true; } LogPrintf("CQuorumBlockProcessor::%s -- Upgrading DB...\n", __func__); - if (::ChainActive().Height() >= Params().GetConsensus().DIP0003EnforcementHeight) { - const auto* pindex = ::ChainActive()[Params().GetConsensus().DIP0003EnforcementHeight]; + if (m_chainstate.m_chain.Height() >= Params().GetConsensus().DIP0003EnforcementHeight) { + const auto* pindex = m_chainstate.m_chain[Params().GetConsensus().DIP0003EnforcementHeight]; while (pindex != nullptr) { if (fPruneMode && ((pindex->nStatus & BLOCK_HAVE_DATA) == 0)) { // Too late, we already pruned blocks we needed to reprocess commitments @@ -390,7 +390,7 @@ bool CQuorumBlockProcessor::UpgradeDB() if (qc.IsNull()) { continue; } - const auto* pQuorumBaseBlockIndex = g_chainman.m_blockman.LookupBlockIndex(qc.quorumHash); + const auto* pQuorumBaseBlockIndex = m_chainstate.m_blockman.LookupBlockIndex(qc.quorumHash); m_evoDb.GetRawDB().Write(std::make_pair(DB_MINED_COMMITMENT, std::make_pair(qc.llmqType, qc.quorumHash)), std::make_pair(qc, pindex->GetBlockHash())); const auto& llmq_params_opt = GetLLMQParams(qc.llmqType); assert(llmq_params_opt.has_value()); @@ -403,7 +403,7 @@ bool CQuorumBlockProcessor::UpgradeDB() m_evoDb.GetRawDB().Write(DB_BEST_BLOCK_UPGRADE, pindex->GetBlockHash()); - pindex = ::ChainActive().Next(pindex); + pindex = m_chainstate.m_chain.Next(pindex); } } @@ -479,8 +479,8 @@ size_t CQuorumBlockProcessor::GetNumCommitmentsRequired(const Consensus::LLMQPar if (!IsMiningPhase(llmqParams, nHeight)) return 0; // Note: This function can be called for new blocks - assert(nHeight <= ::ChainActive().Height() + 1); - const auto *const pindex = ::ChainActive().Height() < nHeight ? ::ChainActive().Tip() : ::ChainActive().Tip()->GetAncestor(nHeight); + assert(nHeight <= m_chainstate.m_chain.Height() + 1); + const auto *const pindex = m_chainstate.m_chain.Height() < nHeight ? m_chainstate.m_chain.Tip() : m_chainstate.m_chain.Tip()->GetAncestor(nHeight); bool rotation_enabled = utils::IsQuorumRotationEnabled(llmqParams, pindex); size_t quorums_num = rotation_enabled ? llmqParams.signingActiveQuorumCount : 1; @@ -763,8 +763,8 @@ std::optional> CQuorumBlockProcessor::GetMineableC } // Note: This function can be called for new blocks - assert(nHeight <= ::ChainActive().Height() + 1); - const auto *const pindex = ::ChainActive().Height() < nHeight ? ::ChainActive().Tip() : ::ChainActive().Tip()->GetAncestor(nHeight); + assert(nHeight <= m_chainstate.m_chain.Height() + 1); + const auto *const pindex = m_chainstate.m_chain.Height() < nHeight ? m_chainstate.m_chain.Tip() : m_chainstate.m_chain.Tip()->GetAncestor(nHeight); bool rotation_enabled = utils::IsQuorumRotationEnabled(llmqParams, pindex); bool basic_bls_enabled = utils::IsV19Active(pindex); diff --git a/src/llmq/blockprocessor.h b/src/llmq/blockprocessor.h index 2e7aa73e97a19..95d88641fd42d 100644 --- a/src/llmq/blockprocessor.h +++ b/src/llmq/blockprocessor.h @@ -17,9 +17,10 @@ #include class BlockValidationState; -class CNode; +class CChainState; class CConnman; class CEvoDB; +class CNode; class PeerManager; extern RecursiveMutex cs_main; @@ -33,9 +34,9 @@ using CFinalCommitmentPtr = std::unique_ptr; class CQuorumBlockProcessor { private: - CEvoDB& m_evoDb; + CChainState& m_chainstate; CConnman& connman; - + CEvoDB& m_evoDb; const std::unique_ptr& m_peerman; // TODO cleanup @@ -46,7 +47,7 @@ class CQuorumBlockProcessor mutable std::map> mapHasMinedCommitmentCache GUARDED_BY(minableCommitmentsCs); public: - explicit CQuorumBlockProcessor(CEvoDB& _evoDb, CConnman& _connman, const std::unique_ptr& peerman); + explicit CQuorumBlockProcessor(CChainState& chainstate, CConnman& _connman, CEvoDB& evoDb, const std::unique_ptr& peerman); bool UpgradeDB(); diff --git a/src/llmq/chainlocks.cpp b/src/llmq/chainlocks.cpp index f6ce0e61d3033..acb1a998263ea 100644 --- a/src/llmq/chainlocks.cpp +++ b/src/llmq/chainlocks.cpp @@ -24,10 +24,10 @@ namespace llmq { std::unique_ptr chainLocksHandler; -CChainLocksHandler::CChainLocksHandler(CTxMemPool& _mempool, CConnman& _connman, CSporkManager& sporkManager, - CSigningManager& _sigman, CSigSharesManager& _shareman, CQuorumManager& _qman, - CMasternodeSync& mn_sync, - const std::unique_ptr& peerman) : +CChainLocksHandler::CChainLocksHandler(CChainState& chainstate, CConnman& _connman, CMasternodeSync& mn_sync, CQuorumManager& _qman, + CSigningManager& _sigman, CSigSharesManager& _shareman, CSporkManager& sporkManager, + CTxMemPool& _mempool, const std::unique_ptr& peerman) : + m_chainstate(chainstate), connman(_connman), mempool(_mempool), spork_manager(sporkManager), @@ -134,7 +134,7 @@ void CChainLocksHandler::ProcessNewChainLock(const NodeId from, const llmq::CCha return; } - CBlockIndex* pindex = WITH_LOCK(cs_main, return g_chainman.m_blockman.LookupBlockIndex(clsig.getBlockHash())); + CBlockIndex* pindex = WITH_LOCK(cs_main, return m_chainstate.m_blockman.LookupBlockIndex(clsig.getBlockHash())); { LOCK(cs); @@ -217,7 +217,7 @@ void CChainLocksHandler::UpdatedBlockTip() void CChainLocksHandler::CheckActiveState() { - const bool fDIP0008Active = WITH_LOCK(cs_main, return (::ChainActive().Tip() != nullptr) && (::ChainActive().Tip()->pprev != nullptr) && ::ChainActive().Tip()->pprev->nHeight >= Params().GetConsensus().DIP0008Height); + const bool fDIP0008Active = WITH_LOCK(cs_main, return (m_chainstate.m_chain.Tip() != nullptr) && (m_chainstate.m_chain.Tip()->pprev != nullptr) && m_chainstate.m_chain.Tip()->pprev->nHeight >= Params().GetConsensus().DIP0008Height); bool oldIsEnforced = isEnforced; isEnabled = AreChainLocksEnabled(spork_manager); @@ -254,7 +254,7 @@ void CChainLocksHandler::TrySignChainTip() return; } - const CBlockIndex* pindex = WITH_LOCK(cs_main, return ::ChainActive().Tip()); + const CBlockIndex* pindex = WITH_LOCK(cs_main, return m_chainstate.m_chain.Tip()); if (pindex->pprev == nullptr) { return; @@ -422,7 +422,7 @@ CChainLocksHandler::BlockTxs::mapped_type CChainLocksHandler::GetBlockTxs(const uint32_t blockTime; { LOCK(cs_main); - auto* pindex = g_chainman.m_blockman.LookupBlockIndex(blockHash); + auto* pindex = m_chainstate.m_blockman.LookupBlockIndex(blockHash); CBlock block; if (!ReadBlockFromDisk(block, pindex, Params().GetConsensus())) { return nullptr; @@ -494,17 +494,17 @@ void CChainLocksHandler::EnforceBestChainLock() // For each of these blocks, check if there are children that are NOT part of the chain referenced by clsig // and mark all of them as conflicting. LogPrint(BCLog::CHAINLOCKS, "CChainLocksHandler::%s -- enforcing block %s via CLSIG (%s)\n", __func__, pindex->GetBlockHash().ToString(), clsig->ToString()); - ::ChainstateActive().EnforceBlock(dummy_state, pindex); + m_chainstate.EnforceBlock(dummy_state, pindex); - bool activateNeeded = WITH_LOCK(::cs_main, return ::ChainActive().Tip()->GetAncestor(currentBestChainLockBlockIndex->nHeight)) != currentBestChainLockBlockIndex; + bool activateNeeded = WITH_LOCK(::cs_main, return m_chainstate.m_chain.Tip()->GetAncestor(currentBestChainLockBlockIndex->nHeight)) != currentBestChainLockBlockIndex; if (activateNeeded) { - if (!::ChainstateActive().ActivateBestChain(dummy_state)) { + if (!m_chainstate.ActivateBestChain(dummy_state)) { LogPrintf("CChainLocksHandler::%s -- ActivateBestChain failed: %s\n", __func__, dummy_state.ToString()); return; } LOCK(cs_main); - if (::ChainActive().Tip()->GetAncestor(currentBestChainLockBlockIndex->nHeight) != currentBestChainLockBlockIndex) { + if (m_chainstate.m_chain.Tip()->GetAncestor(currentBestChainLockBlockIndex->nHeight) != currentBestChainLockBlockIndex) { return; } } @@ -638,7 +638,7 @@ void CChainLocksHandler::Cleanup() } for (auto it = blockTxs.begin(); it != blockTxs.end(); ) { - auto* pindex = g_chainman.m_blockman.LookupBlockIndex(it->first); + auto* pindex = m_chainstate.m_blockman.LookupBlockIndex(it->first); if (InternalHasChainLock(pindex->nHeight, pindex->GetBlockHash())) { for (const auto& txid : *it->second) { txFirstSeenTime.erase(txid); @@ -657,8 +657,8 @@ void CChainLocksHandler::Cleanup() // tx has vanished, probably due to conflicts it = txFirstSeenTime.erase(it); } else if (!hashBlock.IsNull()) { - auto* pindex = g_chainman.m_blockman.LookupBlockIndex(hashBlock); - if (::ChainActive().Tip()->GetAncestor(pindex->nHeight) == pindex && ::ChainActive().Height() - pindex->nHeight >= 6) { + auto* pindex = m_chainstate.m_blockman.LookupBlockIndex(hashBlock); + if (m_chainstate.m_chain.Tip()->GetAncestor(pindex->nHeight) == pindex && m_chainstate.m_chain.Height() - pindex->nHeight >= 6) { // tx got confirmed >= 6 times, so we can stop keeping track of it it = txFirstSeenTime.erase(it); } else { diff --git a/src/llmq/chainlocks.h b/src/llmq/chainlocks.h index b62cb6ceda567..66234a77b33c9 100644 --- a/src/llmq/chainlocks.h +++ b/src/llmq/chainlocks.h @@ -19,6 +19,7 @@ #include #include +class CChainState; class CConnman; class CBlockIndex; class CMasternodeSync; @@ -41,14 +42,14 @@ class CChainLocksHandler : public CRecoveredSigsListener static constexpr int64_t WAIT_FOR_ISLOCK_TIMEOUT = 10 * 60; private: + CChainState& m_chainstate; CConnman& connman; - CTxMemPool& mempool; - CSporkManager& spork_manager; + CMasternodeSync& m_mn_sync; + CQuorumManager& qman; CSigningManager& sigman; CSigSharesManager& shareman; - CQuorumManager& qman; - - CMasternodeSync& m_mn_sync; + CSporkManager& spork_manager; + CTxMemPool& mempool; const std::unique_ptr& m_peerman; std::unique_ptr scheduler; @@ -83,10 +84,9 @@ class CChainLocksHandler : public CRecoveredSigsListener int64_t lastCleanupTime GUARDED_BY(cs) {0}; public: - explicit CChainLocksHandler(CTxMemPool& _mempool, CConnman& _connman, CSporkManager& sporkManager, - CSigningManager& _sigman, CSigSharesManager& _shareman, CQuorumManager& _qman, - CMasternodeSync& mn_sync, - const std::unique_ptr& peerman); + explicit CChainLocksHandler(CChainState& chainstate, CConnman& _connman, CMasternodeSync& mn_sync, CQuorumManager& _qman, + CSigningManager& _sigman, CSigSharesManager& _shareman, CSporkManager& sporkManager, + CTxMemPool& _mempool, const std::unique_ptr& peerman); ~CChainLocksHandler(); void Start(); diff --git a/src/llmq/context.cpp b/src/llmq/context.cpp index 2bff95a342539..5d322180b3cbb 100644 --- a/src/llmq/context.cpp +++ b/src/llmq/context.cpp @@ -19,31 +19,31 @@ #include #include -LLMQContext::LLMQContext(CEvoDB& evo_db, CTxMemPool& mempool, CConnman& connman, CSporkManager& sporkman, +LLMQContext::LLMQContext(CChainState& chainstate, CConnman& connman, CEvoDB& evo_db, CSporkManager& sporkman, CTxMemPool& mempool, 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 { assert(llmq::quorumBlockProcessor == nullptr); - llmq::quorumBlockProcessor = std::make_unique(evo_db, connman, peerman); + llmq::quorumBlockProcessor = std::make_unique(chainstate, connman, evo_db, peerman); return llmq::quorumBlockProcessor.get(); }()}, - qdkgsman{std::make_unique(connman, *bls_worker, *dkg_debugman, *quorum_block_processor, sporkman, peerman, unit_tests, wipe)}, + qdkgsman{std::make_unique(*bls_worker, chainstate, connman, *dkg_debugman, *quorum_block_processor, sporkman, peerman, unit_tests, wipe)}, qman{[&]() -> llmq::CQuorumManager* const { assert(llmq::quorumManager == nullptr); - llmq::quorumManager = std::make_unique(evo_db, connman, *bls_worker, *quorum_block_processor, *qdkgsman, ::masternodeSync, peerman); + llmq::quorumManager = std::make_unique(*bls_worker, chainstate, connman, *qdkgsman, evo_db, *quorum_block_processor, ::masternodeSync, peerman); return llmq::quorumManager.get(); }()}, sigman{std::make_unique(connman, *llmq::quorumManager, peerman, unit_tests, wipe)}, shareman{std::make_unique(connman, *llmq::quorumManager, *sigman, peerman)}, clhandler{[&]() -> llmq::CChainLocksHandler* const { assert(llmq::chainLocksHandler == nullptr); - llmq::chainLocksHandler = std::make_unique(mempool, connman, sporkman, *sigman, *shareman, *llmq::quorumManager, *::masternodeSync, peerman); + llmq::chainLocksHandler = std::make_unique(chainstate, connman, *::masternodeSync, *llmq::quorumManager, *sigman, *shareman, sporkman, mempool, peerman); return llmq::chainLocksHandler.get(); }()}, isman{[&]() -> llmq::CInstantSendManager* const { assert(llmq::quorumInstantSendManager == nullptr); - llmq::quorumInstantSendManager = std::make_unique(mempool, connman, sporkman, *llmq::quorumManager, *sigman, *shareman, *llmq::chainLocksHandler, *::masternodeSync, peerman, unit_tests, wipe); + llmq::quorumInstantSendManager = std::make_unique(*llmq::chainLocksHandler, chainstate, connman, *llmq::quorumManager, *sigman, *shareman, sporkman, mempool, *::masternodeSync, peerman, unit_tests, wipe); return llmq::quorumInstantSendManager.get(); }()} { diff --git a/src/llmq/context.h b/src/llmq/context.h index 8d7cf2295559e..f1639fc4b790f 100644 --- a/src/llmq/context.h +++ b/src/llmq/context.h @@ -8,6 +8,7 @@ #include class CBLSWorker; +class CChainState; class CConnman; class CDBWrapper; class CEvoDB; @@ -29,7 +30,7 @@ class CInstantSendManager; struct LLMQContext { LLMQContext() = delete; LLMQContext(const LLMQContext&) = delete; - LLMQContext(CEvoDB& evo_db, CTxMemPool& mempool, CConnman& connman, CSporkManager& sporkman, + LLMQContext(CChainState& chainstate, CConnman& connman, CEvoDB& evo_db, CSporkManager& sporkman, CTxMemPool& mempool, const std::unique_ptr& peerman, bool unit_tests, bool wipe); ~LLMQContext(); diff --git a/src/llmq/dkgsessionhandler.cpp b/src/llmq/dkgsessionhandler.cpp index 2329021474dd4..6fa5ae4ed8360 100644 --- a/src/llmq/dkgsessionhandler.cpp +++ b/src/llmq/dkgsessionhandler.cpp @@ -21,17 +21,18 @@ namespace llmq { -CDKGSessionHandler::CDKGSessionHandler(const Consensus::LLMQParams& _params, CBLSWorker& _blsWorker, CDKGSessionManager& _dkgManager, - CDKGDebugManager& _dkgDebugManager, CQuorumBlockProcessor& _quorumBlockProcessor, - CConnman& _connman, const std::unique_ptr& peerman, int _quorumIndex) : - params(_params), - connman(_connman), - quorumIndex(_quorumIndex), +CDKGSessionHandler::CDKGSessionHandler(CBLSWorker& _blsWorker, CChainState& chainstate, CConnman& _connman, CDKGDebugManager& _dkgDebugManager, + CDKGSessionManager& _dkgManager, CQuorumBlockProcessor& _quorumBlockProcessor, + const Consensus::LLMQParams& _params, const std::unique_ptr& peerman, int _quorumIndex) : blsWorker(_blsWorker), - dkgManager(_dkgManager), + m_chainstate(chainstate), + connman(_connman), dkgDebugManager(_dkgDebugManager), + dkgManager(_dkgManager), quorumBlockProcessor(_quorumBlockProcessor), + params(_params), m_peerman(peerman), + quorumIndex(_quorumIndex), curSession(std::make_unique(_params, _blsWorker, _dkgManager, _dkgDebugManager, _connman)), 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), @@ -493,7 +494,7 @@ void CDKGSessionHandler::HandleDKGRound() curQuorumHash = quorumHash; } - const CBlockIndex* pQuorumBaseBlockIndex = WITH_LOCK(cs_main, return g_chainman.m_blockman.LookupBlockIndex(curQuorumHash)); + const CBlockIndex* pQuorumBaseBlockIndex = WITH_LOCK(cs_main, return m_chainstate.m_blockman.LookupBlockIndex(curQuorumHash)); if (!InitNewQuorum(pQuorumBaseBlockIndex)) { // should actually never happen diff --git a/src/llmq/dkgsessionhandler.h b/src/llmq/dkgsessionhandler.h index 1021c08bee33d..78b2c3abc35ba 100644 --- a/src/llmq/dkgsessionhandler.h +++ b/src/llmq/dkgsessionhandler.h @@ -11,8 +11,9 @@ #include -class CBLSWorker; class CBlockIndex; +class CBLSWorker; +class CChainState; class PeerManager; namespace llmq @@ -110,15 +111,15 @@ class CDKGSessionHandler mutable RecursiveMutex cs; std::atomic stopRequested{false}; - const Consensus::LLMQParams params; - CConnman& connman; - const int quorumIndex; CBLSWorker& blsWorker; - CDKGSessionManager& dkgManager; + CChainState& m_chainstate; + CConnman& connman; CDKGDebugManager& dkgDebugManager; + CDKGSessionManager& dkgManager; CQuorumBlockProcessor& quorumBlockProcessor; - + const Consensus::LLMQParams params; const std::unique_ptr& m_peerman; + const int quorumIndex; QuorumPhase phase GUARDED_BY(cs) {QuorumPhase::Idle}; int currentHeight GUARDED_BY(cs) {-1}; @@ -134,9 +135,9 @@ class CDKGSessionHandler CDKGPendingMessages pendingPrematureCommitments; public: - CDKGSessionHandler(const Consensus::LLMQParams& _params, CBLSWorker& _blsWorker, CDKGSessionManager& _dkgManager, - CDKGDebugManager& _dkgDebugManager, CQuorumBlockProcessor& _quorumBlockProcessor, - CConnman& _connman, const std::unique_ptr& peerman, int _quorumIndex); + CDKGSessionHandler(CBLSWorker& _blsWorker, CChainState& chainstate, CConnman& _connman, CDKGDebugManager& _dkgDebugManager, + CDKGSessionManager& _dkgManager, CQuorumBlockProcessor& _quorumBlockProcessor, + const Consensus::LLMQParams& _params, const std::unique_ptr& peerman, int _quorumIndex); ~CDKGSessionHandler() = default; void UpdatedBlockTip(const CBlockIndex *pindexNew); diff --git a/src/llmq/dkgsessionmgr.cpp b/src/llmq/dkgsessionmgr.cpp index 83a24f8655c43..81b59dead2b2d 100644 --- a/src/llmq/dkgsessionmgr.cpp +++ b/src/llmq/dkgsessionmgr.cpp @@ -22,15 +22,16 @@ static const std::string DB_VVEC = "qdkg_V"; static const std::string DB_SKCONTRIB = "qdkg_S"; static const std::string DB_ENC_CONTRIB = "qdkg_E"; -CDKGSessionManager::CDKGSessionManager(CConnman& _connman, CBLSWorker& _blsWorker, CDKGDebugManager& _dkgDebugManager, +CDKGSessionManager::CDKGSessionManager(CBLSWorker& _blsWorker, CChainState& chainstate, CConnman& _connman, CDKGDebugManager& _dkgDebugManager, CQuorumBlockProcessor& _quorumBlockProcessor, CSporkManager& sporkManager, const std::unique_ptr& peerman, bool unitTests, bool fWipe) : db(std::make_unique(unitTests ? "" : (GetDataDir() / "llmq/dkgdb"), 1 << 20, unitTests, fWipe)), blsWorker(_blsWorker), + m_chainstate(chainstate), connman(_connman), - spork_manager(sporkManager), dkgDebugManager(_dkgDebugManager), quorumBlockProcessor(_quorumBlockProcessor), + spork_manager(sporkManager), m_peerman(peerman) { if (!fMasternodeMode && !utils::IsWatchQuorumsEnabled()) { @@ -46,7 +47,7 @@ CDKGSessionManager::CDKGSessionManager(CConnman& _connman, CBLSWorker& _blsWorke for (const auto i : irange::range(session_count)) { dkgSessionHandlers.emplace(std::piecewise_construct, std::forward_as_tuple(params.type, i), - std::forward_as_tuple(params, blsWorker, *this, dkgDebugManager, quorumBlockProcessor, connman, peerman, i)); + std::forward_as_tuple(blsWorker, m_chainstate, connman, dkgDebugManager, *this, quorumBlockProcessor, params, peerman, i)); } } } @@ -224,7 +225,7 @@ void CDKGSessionManager::ProcessMessage(CNode& pfrom, const CQuorumManager& quor // No luck, try to compute if (quorumIndex == -1) { - CBlockIndex* pQuorumBaseBlockIndex = WITH_LOCK(cs_main, return g_chainman.m_blockman.LookupBlockIndex(quorumHash)); + CBlockIndex* pQuorumBaseBlockIndex = WITH_LOCK(cs_main, return m_chainstate.m_blockman.LookupBlockIndex(quorumHash)); if (pQuorumBaseBlockIndex == nullptr) { LogPrintf("CDKGSessionManager -- unknown quorumHash %s\n", quorumHash.ToString()); // NOTE: do not insta-ban for this, we might be lagging behind @@ -483,8 +484,8 @@ void CDKGSessionManager::CleanupOldContributions() const break; } cnt_all++; - const CBlockIndex* pindexQuorum = g_chainman.m_blockman.LookupBlockIndex(std::get<2>(k)); - if (pindexQuorum == nullptr || ::ChainActive().Tip()->nHeight - pindexQuorum->nHeight > MAX_STORE_DEPTH) { + const CBlockIndex* pindexQuorum = m_chainstate.m_blockman.LookupBlockIndex(std::get<2>(k)); + if (pindexQuorum == nullptr || m_chainstate.m_chain.Tip()->nHeight - pindexQuorum->nHeight > MAX_STORE_DEPTH) { // not found or too old batch.Erase(k); cnt_old++; diff --git a/src/llmq/dkgsessionmgr.h b/src/llmq/dkgsessionmgr.h index 4cf940dadc209..df56d9a28682b 100644 --- a/src/llmq/dkgsessionmgr.h +++ b/src/llmq/dkgsessionmgr.h @@ -11,6 +11,7 @@ #include class CBlockIndex; +class CChainState; class CDKGDebugManager; class CSporkManager; class PeerManager; @@ -27,12 +28,13 @@ class CDKGSessionManager private: std::unique_ptr db{nullptr}; + CBLSWorker& blsWorker; + CChainState& m_chainstate; CConnman& connman; - CSporkManager& spork_manager; CDKGDebugManager& dkgDebugManager; CQuorumBlockProcessor& quorumBlockProcessor; - + CSporkManager& spork_manager; const std::unique_ptr& m_peerman; //TODO name struct instead of std::pair @@ -58,7 +60,7 @@ class CDKGSessionManager mutable std::map contributionsCache GUARDED_BY(contributionsCacheCs); public: - CDKGSessionManager(CConnman& _connman, CBLSWorker& _blsWorker, CDKGDebugManager& _dkgDebugManager, + CDKGSessionManager(CBLSWorker& _blsWorker, CChainState& chainstate, CConnman& _connman, CDKGDebugManager& _dkgDebugManager, CQuorumBlockProcessor& _quorumBlockProcessor, CSporkManager& sporkManager, const std::unique_ptr& peerman, bool unitTests, bool fWipe); ~CDKGSessionManager() = default; diff --git a/src/llmq/instantsend.cpp b/src/llmq/instantsend.cpp index c91de32d7d12e..99736d970e949 100644 --- a/src/llmq/instantsend.cpp +++ b/src/llmq/instantsend.cpp @@ -509,7 +509,7 @@ void CInstantSendManager::ProcessTx(const CTransaction& tx, bool fRetroactive, c // block after we retroactively locked all transactions. if (!IsInstantSendMempoolSigningEnabled() && !fRetroactive) return; - if (!TrySignInputLocks(tx, fRetroactive, utils::GetInstantSendLLMQType(qman, WITH_LOCK(cs_main, return ::ChainActive().Tip())), params)) { + if (!TrySignInputLocks(tx, fRetroactive, utils::GetInstantSendLLMQType(qman, WITH_LOCK(cs_main, return m_chainstate.m_chain.Tip())), params)) { return; } @@ -618,8 +618,8 @@ bool CInstantSendManager::CheckCanLock(const COutPoint& outpoint, bool printDebu int nTxAge; { LOCK(cs_main); - pindexMined = g_chainman.m_blockman.LookupBlockIndex(hashBlock); - nTxAge = ::ChainActive().Height() - pindexMined->nHeight + 1; + pindexMined = m_chainstate.m_blockman.LookupBlockIndex(hashBlock); + nTxAge = m_chainstate.m_chain.Height() - pindexMined->nHeight + 1; } if (nTxAge < nInstantSendConfirmationsRequired && !clhandler.HasChainLock(pindexMined->nHeight, pindexMined->GetBlockHash())) { @@ -683,7 +683,7 @@ void CInstantSendManager::HandleNewInputLockRecoveredSig(const CRecoveredSig& re void CInstantSendManager::TrySignInstantSendLock(const CTransaction& tx) { - const auto llmqType = utils::GetInstantSendLLMQType(qman, WITH_LOCK(cs_main, return ::ChainActive().Tip())); + const auto llmqType = utils::GetInstantSendLLMQType(qman, WITH_LOCK(cs_main, return m_chainstate.m_chain.Tip())); for (const auto& in : tx.vin) { auto id = ::SerializeHash(std::make_pair(INPUTLOCK_REQUESTID_PREFIX, in.prevout)); @@ -709,8 +709,8 @@ void CInstantSendManager::TrySignInstantSendLock(const CTransaction& tx) assert(llmq_params_opt); LOCK(cs_main); const auto dkgInterval = llmq_params_opt->dkgInterval; - const auto quorumHeight = ::ChainActive().Height() - (::ChainActive().Height() % dkgInterval); - islock.cycleHash = ::ChainActive()[quorumHeight]->GetBlockHash(); + const auto quorumHeight = m_chainstate.m_chain.Height() - (m_chainstate.m_chain.Height() % dkgInterval); + islock.cycleHash = m_chainstate.m_chain[quorumHeight]->GetBlockHash(); } auto id = islock.GetRequestId(); @@ -785,7 +785,7 @@ void CInstantSendManager::ProcessMessageInstantSendLock(const CNode& pfrom, cons { LOCK(cs_main); EraseObjectRequest(pfrom.GetId(), CInv(islock->IsDeterministic() ? MSG_ISDLOCK : MSG_ISLOCK, hash)); - fDIP0024IsActive = utils::IsDIP0024Active(::ChainActive().Tip()); + fDIP0024IsActive = utils::IsDIP0024Active(m_chainstate.m_chain.Tip()); } if (!islock->TriviallyValid()) { @@ -795,7 +795,7 @@ void CInstantSendManager::ProcessMessageInstantSendLock(const CNode& pfrom, cons // Deterministic ISLocks are only produced by rotation quorums, if we don't see DIP24 as active, then we won't be able to validate it anyway if (islock->IsDeterministic() && fDIP0024IsActive) { - const auto blockIndex = WITH_LOCK(cs_main, return g_chainman.m_blockman.LookupBlockIndex(islock->cycleHash)); + const auto blockIndex = WITH_LOCK(cs_main, return m_chainstate.m_blockman.LookupBlockIndex(islock->cycleHash)); if (blockIndex == nullptr) { // Maybe we don't have the block yet or maybe some peer spams invalid values for cycleHash m_peerman->Misbehaving(pfrom.GetId(), 1); @@ -813,7 +813,7 @@ void CInstantSendManager::ProcessMessageInstantSendLock(const CNode& pfrom, cons } // WE MUST STILL PROCESS OLD ISLOCKS? -// else if (utils::IsDIP0024Active(WITH_LOCK(cs_main, return ::ChainActive().Tip()))) { +// else if (utils::IsDIP0024Active(WITH_LOCK(cs_main, return m_chainstate.m_chain.Tip()))) { // // Ignore non-deterministic islocks once rotation is active // return; // } @@ -853,7 +853,7 @@ bool CInstantSendLock::TriviallyValid() const bool CInstantSendManager::ProcessPendingInstantSendLocks() { - const CBlockIndex* pBlockIndexTip = WITH_LOCK(cs_main, return ::ChainActive().Tip()); + const CBlockIndex* pBlockIndexTip = WITH_LOCK(cs_main, return m_chainstate.m_chain.Tip()); if (pBlockIndexTip && utils::GetInstantSendLLMQType(qman, pBlockIndexTip) == Params().GetConsensus().llmqTypeDIP0024InstantSend) { // Don't short circuit. Try to process both deterministic and not deterministic islocks independable bool deterministicRes = ProcessPendingInstantSendLocks(true); @@ -966,14 +966,14 @@ std::unordered_set CInstantSendManager::ProcessPend if (islock->IsDeterministic()) { LOCK(cs_main); - const auto blockIndex = g_chainman.m_blockman.LookupBlockIndex(islock->cycleHash); + const auto blockIndex = m_chainstate.m_blockman.LookupBlockIndex(islock->cycleHash); if (blockIndex == nullptr) { batchVerifier.badSources.emplace(nodeId); continue; } const auto dkgInterval = llmq_params.dkgInterval; - if (blockIndex->nHeight + dkgInterval < ::ChainActive().Height()) { + if (blockIndex->nHeight + dkgInterval < m_chainstate.m_chain.Height()) { nSignHeight = blockIndex->nHeight + dkgInterval - 1; } } @@ -1060,7 +1060,7 @@ void CInstantSendManager::ProcessInstantSendLock(NodeId from, const uint256& has const CBlockIndex* pindexMined{nullptr}; // we ignore failure here as we must be able to propagate the lock even if we don't have the TX locally if (tx && !hashBlock.IsNull()) { - pindexMined = WITH_LOCK(cs_main, return g_chainman.m_blockman.LookupBlockIndex(hashBlock)); + pindexMined = WITH_LOCK(cs_main, return m_chainstate.m_blockman.LookupBlockIndex(hashBlock)); // Let's see if the TX that was locked by this islock is already mined in a ChainLocked block. If yes, // we can simply ignore the islock, as the ChainLock implies locking of all TXs in that chain @@ -1083,7 +1083,7 @@ void CInstantSendManager::ProcessInstantSendLock(NodeId from, const uint256& has return; } else if (islock->IsDeterministic()) { // can happen, remove and archive the non-deterministic sameTxIsLock - db.RemoveAndArchiveInstantSendLock(sameTxIsLock, WITH_LOCK(::cs_main, return ::ChainActive().Height())); + db.RemoveAndArchiveInstantSendLock(sameTxIsLock, WITH_LOCK(::cs_main, return m_chainstate.m_chain.Height())); } } else { for (const auto& in : islock->inputs) { @@ -1478,8 +1478,8 @@ void CInstantSendManager::ResolveBlockConflicts(const uint256& islockHash, const BlockValidationState state; // need non-const pointer - auto pindex2 = WITH_LOCK(::cs_main, return g_chainman.m_blockman.LookupBlockIndex(pindex->GetBlockHash())); - if (!::ChainstateActive().InvalidateBlock(state, pindex2)) { + auto pindex2 = WITH_LOCK(::cs_main, return m_chainstate.m_blockman.LookupBlockIndex(pindex->GetBlockHash())); + if (!m_chainstate.InvalidateBlock(state, pindex2)) { LogPrintf("CInstantSendManager::%s -- InvalidateBlock failed: %s\n", __func__, state.ToString()); // This should not have happened and we are in a state were it's not safe to continue anymore assert(false); @@ -1489,13 +1489,13 @@ void CInstantSendManager::ResolveBlockConflicts(const uint256& islockHash, const } else { LogPrintf("CInstantSendManager::%s -- resetting block %s\n", __func__, pindex2->GetBlockHash().ToString()); LOCK(cs_main); - ::ChainstateActive().ResetBlockFailureFlags(pindex2); + m_chainstate.ResetBlockFailureFlags(pindex2); } } if (activateBestChain) { BlockValidationState state; - if (!::ChainstateActive().ActivateBestChain(state)) { + if (!m_chainstate.ActivateBestChain(state)) { LogPrintf("CChainLocksHandler::%s -- ActivateBestChain failed: %s\n", __func__, state.ToString()); // This should not have happened and we are in a state were it's not safe to continue anymore assert(false); @@ -1507,7 +1507,7 @@ void CInstantSendManager::RemoveConflictingLock(const uint256& islockHash, const { LogPrintf("CInstantSendManager::%s -- txid=%s, islock=%s: Removing ISLOCK and its chained children\n", __func__, islock.txid.ToString(), islockHash.ToString()); - int tipHeight = WITH_LOCK(cs_main, return ::ChainActive().Height()); + int tipHeight = WITH_LOCK(cs_main, return m_chainstate.m_chain.Height()); auto removedIslocks = db.RemoveChainedInstantSendLocks(islockHash, islock.txid, tipHeight); for (const auto& h : removedIslocks) { diff --git a/src/llmq/instantsend.h b/src/llmq/instantsend.h index 1bdc2dbe3170a..5764daff32512 100644 --- a/src/llmq/instantsend.h +++ b/src/llmq/instantsend.h @@ -18,6 +18,7 @@ #include #include +class CChainState; class CMasternodeSync; class CSporkManager; class PeerManager; @@ -203,14 +204,15 @@ class CInstantSendManager : public CRecoveredSigsListener { private: CInstantSendDb db; + + CChainLocksHandler& clhandler; + CChainState& m_chainstate; CConnman& connman; - CTxMemPool& mempool; - CSporkManager& spork_manager; CQuorumManager& qman; CSigningManager& sigman; CSigSharesManager& shareman; - CChainLocksHandler& clhandler; - + CSporkManager& spork_manager; + CTxMemPool& mempool; const CMasternodeSync& m_mn_sync; const std::unique_ptr& m_peerman; @@ -260,12 +262,13 @@ class CInstantSendManager : public CRecoveredSigsListener std::unordered_set pendingRetryTxs GUARDED_BY(cs_pendingRetry); public: - explicit CInstantSendManager(CTxMemPool& _mempool, CConnman& _connman, CSporkManager& sporkManager, + explicit CInstantSendManager(CChainLocksHandler& _clhandler, CChainState& chainstate, CConnman& _connman, CQuorumManager& _qman, CSigningManager& _sigman, CSigSharesManager& _shareman, - CChainLocksHandler& _clhandler, CMasternodeSync& mn_sync, + CSporkManager& sporkManager, CTxMemPool& _mempool, const CMasternodeSync& mn_sync, const std::unique_ptr& peerman, bool unitTests, bool fWipe) : - db(unitTests, fWipe), connman(_connman), mempool(_mempool), spork_manager(sporkManager), qman(_qman), sigman(_sigman), shareman(_shareman), - clhandler(_clhandler), m_mn_sync(mn_sync), m_peerman(peerman) + db(unitTests, fWipe), + clhandler(_clhandler), m_chainstate(chainstate), connman(_connman), qman(_qman), sigman(_sigman), + shareman(_shareman), spork_manager(sporkManager), mempool(_mempool), m_mn_sync(mn_sync), m_peerman(peerman) { workInterrupt.reset(); } diff --git a/src/llmq/quorums.cpp b/src/llmq/quorums.cpp index db402d26b73f0..ec2f1a636b475 100644 --- a/src/llmq/quorums.cpp +++ b/src/llmq/quorums.cpp @@ -187,13 +187,14 @@ bool CQuorum::ReadContributions(CEvoDB& evoDb) return true; } -CQuorumManager::CQuorumManager(CEvoDB& _evoDb, CConnman& _connman, CBLSWorker& _blsWorker, CQuorumBlockProcessor& _quorumBlockProcessor, - CDKGSessionManager& _dkgManager, const std::unique_ptr& mn_sync, +CQuorumManager::CQuorumManager(CBLSWorker& _blsWorker, CChainState& chainstate, CConnman& _connman, CDKGSessionManager& _dkgManager, + CEvoDB& _evoDb, CQuorumBlockProcessor& _quorumBlockProcessor, const std::unique_ptr& mn_sync, const std::unique_ptr& peerman) : - m_evoDb(_evoDb), - connman(_connman), blsWorker(_blsWorker), + m_chainstate(chainstate), + connman(_connman), dkgManager(_dkgManager), + m_evoDb(_evoDb), quorumBlockProcessor(_quorumBlockProcessor), m_mn_sync(mn_sync), m_peerman(peerman) @@ -492,7 +493,7 @@ bool CQuorumManager::RequestQuorumData(CNode* pfrom, Consensus::LLMQType llmqTyp std::vector CQuorumManager::ScanQuorums(Consensus::LLMQType llmqType, size_t nCountRequested) const { - const CBlockIndex* pindex = WITH_LOCK(cs_main, return ::ChainActive().Tip()); + const CBlockIndex* pindex = WITH_LOCK(cs_main, return m_chainstate.m_chain.Tip()); return ScanQuorums(llmqType, pindex, nCountRequested); } @@ -562,7 +563,7 @@ std::vector CQuorumManager::ScanQuorums(Consensus::LLMQType llmqTyp CQuorumCPtr CQuorumManager::GetQuorum(Consensus::LLMQType llmqType, const uint256& quorumHash) const { - const CBlockIndex* pQuorumBaseBlockIndex = WITH_LOCK(cs_main, return g_chainman.m_blockman.LookupBlockIndex(quorumHash)); + const CBlockIndex* pQuorumBaseBlockIndex = WITH_LOCK(cs_main, return m_chainstate.m_blockman.LookupBlockIndex(quorumHash)); if (!pQuorumBaseBlockIndex) { LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- block %s not found\n", __func__, quorumHash.ToString()); return nullptr; @@ -674,7 +675,7 @@ void CQuorumManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, C return; } - const CBlockIndex* pQuorumBaseBlockIndex = WITH_LOCK(cs_main, return g_chainman.m_blockman.LookupBlockIndex(request.GetQuorumHash())); + const CBlockIndex* pQuorumBaseBlockIndex = WITH_LOCK(cs_main, return m_chainstate.m_blockman.LookupBlockIndex(request.GetQuorumHash())); if (pQuorumBaseBlockIndex == nullptr) { sendQDATA(CQuorumDataRequest::Errors::QUORUM_BLOCK_NOT_FOUND, request_limit_exceeded); return; diff --git a/src/llmq/quorums.h b/src/llmq/quorums.h index 61e13d9a3e2a3..7f64e598532a4 100644 --- a/src/llmq/quorums.h +++ b/src/llmq/quorums.h @@ -16,8 +16,9 @@ #include -class CConnman; class CBlockIndex; +class CChainState; +class CConnman; class CDeterministicMN; class CMasternodeSync; class CNode; @@ -212,12 +213,12 @@ class CQuorum class CQuorumManager { private: - CEvoDB& m_evoDb; - CConnman& connman; CBLSWorker& blsWorker; + CChainState& m_chainstate; + CConnman& connman; CDKGSessionManager& dkgManager; + CEvoDB& m_evoDb; CQuorumBlockProcessor& quorumBlockProcessor; - const std::unique_ptr& m_mn_sync; const std::unique_ptr& m_peerman; @@ -230,8 +231,8 @@ class CQuorumManager mutable CThreadInterrupt quorumThreadInterrupt; public: - CQuorumManager(CEvoDB& _evoDb, CConnman& _connman, CBLSWorker& _blsWorker, CQuorumBlockProcessor& _quorumBlockProcessor, - CDKGSessionManager& _dkgManager, const std::unique_ptr& mnSync, + CQuorumManager(CBLSWorker& _blsWorker, CChainState& chainstate, CConnman& _connman, CDKGSessionManager& _dkgManager, + CEvoDB& _evoDb, CQuorumBlockProcessor& _quorumBlockProcessor, const std::unique_ptr& mn_sync, const std::unique_ptr& peerman); ~CQuorumManager() { Stop(); }; diff --git a/src/test/policyestimator_tests.cpp b/src/test/policyestimator_tests.cpp index d69e473c02c68..e61dd3e865ab1 100644 --- a/src/test/policyestimator_tests.cpp +++ b/src/test/policyestimator_tests.cpp @@ -12,7 +12,7 @@ #include -BOOST_FIXTURE_TEST_SUITE(policyestimator_tests, BasicTestingSetup) +BOOST_FIXTURE_TEST_SUITE(policyestimator_tests, TestingSetup) BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) { diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 7f7100d3e5927..11a0defcffdac 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -95,6 +95,24 @@ std::ostream& operator<<(std::ostream& os, const uint256& num) return os; } +void DashTestSetup(NodeContext& node) +{ + CChainState& chainstate = Assert(node.chainman)->ActiveChainstate(); + + ::coinJoinServer = std::make_unique(chainstate, *node.connman, *node.mempool, *::masternodeSync); + ::deterministicMNManager = std::make_unique(chainstate, *node.connman, *node.evodb); + node.llmq_ctx = std::make_unique(chainstate, *node.connman, *node.evodb, *sporkManager, *node.mempool, node.peerman, true, false); +} + +void DashTestSetupClose(NodeContext& node) +{ + node.llmq_ctx->Interrupt(); + node.llmq_ctx->Stop(); + node.llmq_ctx.reset(); + ::deterministicMNManager.reset(); + ::coinJoinServer.reset(); +} + BasicTestingSetup::BasicTestingSetup(const std::string& chainName, const std::vector& extra_args) : m_path_root{fs::temp_directory_path() / "test_common_" PACKAGE_NAME / g_insecure_rand_ctx_temp_path.rand256().ToString()} { @@ -139,7 +157,6 @@ BasicTestingSetup::BasicTestingSetup(const std::string& chainName, const std::ve fCheckBlockIndex = true; m_node.evodb = std::make_unique(1 << 20, true, true); connman = std::make_unique(0x1337, 0x1337, *m_node.addrman); - deterministicMNManager.reset(new CDeterministicMNManager(*m_node.evodb, *connman)); llmq::quorumSnapshotManager.reset(new llmq::CQuorumSnapshotManager(*m_node.evodb)); creditPoolManager = std::make_unique(*m_node.evodb); static bool noui_connected = false; @@ -154,7 +171,6 @@ BasicTestingSetup::~BasicTestingSetup() { connman.reset(); llmq::quorumSnapshotManager.reset(); - deterministicMNManager.reset(); creditPoolManager.reset(); m_node.evodb.reset(); @@ -185,13 +201,10 @@ ChainTestingSetup::ChainTestingSetup(const std::string& chainName, const std::ve ::sporkManager = std::make_unique(); ::governance = std::make_unique(); ::masternodeSync = std::make_unique(*m_node.connman); - ::coinJoinServer = std::make_unique(*m_node.mempool, *m_node.connman, *::masternodeSync); #ifdef ENABLE_WALLET ::coinJoinClientQueueManager = std::make_unique(*m_node.connman, *::masternodeSync); #endif // ENABLE_WALLET - deterministicMNManager.reset(new CDeterministicMNManager(*m_node.evodb, *m_node.connman)); - m_node.llmq_ctx = std::make_unique(*m_node.evodb, *m_node.mempool, *m_node.connman, *sporkManager, m_node.peerman, true, false); m_node.creditPoolManager = std::make_unique(*m_node.evodb); // Start script-checking threads. Set g_parallel_script_checks to true so they are used. @@ -203,9 +216,6 @@ ChainTestingSetup::ChainTestingSetup(const std::string& chainName, const std::ve ChainTestingSetup::~ChainTestingSetup() { m_node.scheduler->stop(); - deterministicMNManager.reset(); - m_node.llmq_ctx->Interrupt(); - m_node.llmq_ctx->Stop(); m_node.creditPoolManager.reset(); StopScriptCheckWorkerThreads(); GetMainSignals().FlushBackgroundCallbacks(); @@ -213,18 +223,15 @@ ChainTestingSetup::~ChainTestingSetup() #ifdef ENABLE_WALLET ::coinJoinClientQueueManager.reset(); #endif // ENABLE_WALLET - ::coinJoinServer.reset(); ::masternodeSync.reset(); ::governance.reset(); ::sporkManager.reset(); m_node.connman.reset(); m_node.addrman.reset(); m_node.args = nullptr; - m_node.banman.reset(); UnloadBlockIndex(m_node.mempool.get(), *m_node.chainman); m_node.mempool.reset(); m_node.scheduler.reset(); - m_node.llmq_ctx.reset(); m_node.chainman->Reset(); m_node.chainman = nullptr; pblocktree.reset(); @@ -258,12 +265,22 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vectorInit(options); } + DashTestSetup(m_node); + BlockValidationState state; if (!::ChainstateActive().ActivateBestChain(state)) { throw std::runtime_error(strprintf("ActivateBestChain failed. (%s)", state.ToString())); } } +TestingSetup::~TestingSetup() +{ + DashTestSetupClose(m_node); + m_node.connman->Stop(); + m_node.peerman.reset(); + m_node.banman.reset(); +} + TestChainSetup::TestChainSetup(int num_blocks, const std::vector& extra_args) : RegTestingSetup(extra_args) { diff --git a/src/test/util/setup_common.h b/src/test/util/setup_common.h index 8880cf3c024cf..14b49ea2e8ca0 100644 --- a/src/test/util/setup_common.h +++ b/src/test/util/setup_common.h @@ -69,6 +69,10 @@ static inline bool InsecureRandBool() { return g_insecure_rand_ctx.randbool(); } static constexpr CAmount CENT{1000000}; +/* Initialize Dash-specific components after chainstate initialization */ +void DashTestSetup(NodeContext& node); +void DashTestSetupClose(NodeContext& node); + /** Basic testing setup. * This just configures logging, data dir and chain parameters. */ @@ -88,7 +92,6 @@ struct BasicTestingSetup { * initialization behaviour. */ struct ChainTestingSetup : public BasicTestingSetup { - explicit ChainTestingSetup(const std::string& chainName = CBaseChainParams::MAIN, const std::vector& extra_args = {}); ~ChainTestingSetup(); }; @@ -97,6 +100,7 @@ struct ChainTestingSetup : public BasicTestingSetup { */ struct TestingSetup : public ChainTestingSetup { explicit TestingSetup(const std::string& chainName = CBaseChainParams::MAIN, const std::vector& extra_args = {}); + ~TestingSetup(); }; /** Identical to TestingSetup, but chain set to regtest */ diff --git a/src/test/validation_chainstatemanager_tests.cpp b/src/test/validation_chainstatemanager_tests.cpp index 6893162bf4963..c57aaf95d54c9 100644 --- a/src/test/validation_chainstatemanager_tests.cpp +++ b/src/test/validation_chainstatemanager_tests.cpp @@ -4,6 +4,7 @@ // #include #include +#include #include #include #include @@ -12,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +49,8 @@ BOOST_AUTO_TEST_CASE(chainstatemanager) /* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false); WITH_LOCK(::cs_main, c1.InitCoinsCache(1 << 23)); + DashTestSetup(m_node); + BOOST_CHECK(!manager.IsSnapshotActive()); BOOST_CHECK(!manager.IsSnapshotValidated()); BOOST_CHECK(!manager.IsBackgroundIBD(&c1)); @@ -67,6 +71,8 @@ BOOST_AUTO_TEST_CASE(chainstatemanager) BOOST_CHECK(!manager.SnapshotBlockhash().has_value()); + DashTestSetupClose(m_node); + // Create a snapshot-based chainstate. // const uint256 snapshot_blockhash = GetRandHash(); @@ -76,6 +82,8 @@ BOOST_AUTO_TEST_CASE(chainstatemanager) ); chainstates.push_back(&c2); + DashTestSetup(m_node); + BOOST_CHECK_EQUAL(manager.SnapshotBlockhash().value(), snapshot_blockhash); c2.InitCoinsDB( @@ -119,6 +127,8 @@ BOOST_AUTO_TEST_CASE(chainstatemanager) // Let scheduler events finish running to avoid accessing memory that is going to be unloaded SyncWithValidationInterfaceQueue(); + DashTestSetupClose(m_node); + WITH_LOCK(::cs_main, manager.Unload()); }