diff --git a/src/evo/assetlocktx.cpp b/src/evo/assetlocktx.cpp index 37a41ece982bd..df67e459ebece 100644 --- a/src/evo/assetlocktx.cpp +++ b/src/evo/assetlocktx.cpp @@ -22,13 +22,13 @@ /** * Common code for Asset Lock and Asset Unlock */ -bool CheckAssetLockUnlockTx(const CTransaction& tx, gsl::not_null pindexPrev, const std::optional& indexes, TxValidationState& state) +bool CheckAssetLockUnlockTx(const llmq::CQuorumManager& qman, const CTransaction& tx, gsl::not_null pindexPrev, const std::optional& indexes, TxValidationState& state) { switch (tx.nType) { case TRANSACTION_ASSET_LOCK: return CheckAssetLockTx(tx, state); case TRANSACTION_ASSET_UNLOCK: - return CheckAssetUnlockTx(tx, pindexPrev, indexes, state); + return CheckAssetUnlockTx(qman, tx, pindexPrev, indexes, state); default: return state.Invalid(TxValidationResult::TX_BAD_SPECIAL, "bad-not-asset-locks-at-all"); } @@ -107,7 +107,7 @@ std::string CAssetLockPayload::ToString() const const std::string ASSETUNLOCK_REQUESTID_PREFIX = "plwdtx"; -bool CAssetUnlockPayload::VerifySig(const uint256& msgHash, gsl::not_null pindexTip, TxValidationState& state) const +bool CAssetUnlockPayload::VerifySig(const llmq::CQuorumManager& qman, const uint256& msgHash, gsl::not_null pindexTip, TxValidationState& state) const { // That quourm hash must be active at `requestHeight`, // and at the quorumHash must be active in either the current or previous quorum cycle @@ -116,7 +116,7 @@ bool CAssetUnlockPayload::VerifySig(const uint256& msgHash, gsl::not_nullScanQuorums(llmqType, pindexTip, 2); + const auto quorums = qman.ScanQuorums(llmqType, pindexTip, 2); if (bool isActive = std::any_of(quorums.begin(), quorums.end(), [&](const auto &q) { return q->qc->quorumHash == quorumHash; }); !isActive) { return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-assetunlock-not-active-quorum"); @@ -128,7 +128,7 @@ bool CAssetUnlockPayload::VerifySig(const uint256& msgHash, gsl::not_nullGetQuorum(llmqType, quorumHash); + const auto quorum = qman.GetQuorum(llmqType, quorumHash); assert(quorum); const uint256 requestId = ::SerializeHash(std::make_pair(ASSETUNLOCK_REQUESTID_PREFIX, index)); @@ -141,7 +141,7 @@ bool CAssetUnlockPayload::VerifySig(const uint256& msgHash, gsl::not_null pindexPrev, const std::optional& indexes, TxValidationState& state) +bool CheckAssetUnlockTx(const llmq::CQuorumManager& qman, const CTransaction& tx, gsl::not_null pindexPrev, const std::optional& indexes, TxValidationState& state) { // Some checks depends from blockchain status also, such as `known indexes` and `withdrawal limits` // They are omitted here and done by CCreditPool @@ -182,7 +182,7 @@ bool CheckAssetUnlockTx(const CTransaction& tx, gsl::not_null pindexTip, TxValidationState& state) const; + bool VerifySig(const llmq::CQuorumManager& qman, const uint256& msgHash, gsl::not_null pindexTip, TxValidationState& state) const; // getters uint8_t getVersion() const @@ -169,8 +172,8 @@ class CAssetUnlockPayload }; bool CheckAssetLockTx(const CTransaction& tx, TxValidationState& state); -bool CheckAssetUnlockTx(const CTransaction& tx, gsl::not_null pindexPrev, const std::optional& indexes, TxValidationState& state); -bool CheckAssetLockUnlockTx(const CTransaction& tx, gsl::not_null pindexPrev, const std::optional& indexes, TxValidationState& state); +bool CheckAssetUnlockTx(const llmq::CQuorumManager& qman, const CTransaction& tx, gsl::not_null pindexPrev, const std::optional& indexes, TxValidationState& state); +bool CheckAssetLockUnlockTx(const llmq::CQuorumManager& qman, const CTransaction& tx, gsl::not_null pindexPrev, const std::optional& indexes, TxValidationState& state); bool GetAssetUnlockFee(const CTransaction& tx, CAmount& txfee, TxValidationState& state); #endif // BITCOIN_EVO_ASSETLOCKTX_H diff --git a/src/evo/chainhelper.cpp b/src/evo/chainhelper.cpp index fe6bfdf192ccc..519983b84697d 100644 --- a/src/evo/chainhelper.cpp +++ b/src/evo/chainhelper.cpp @@ -10,9 +10,10 @@ CChainstateHelper::CChainstateHelper(CCreditPoolManager& cpoolman, CDeterministicMNManager& dmnman, CMNHFManager& mnhfman, CGovernanceManager& govman, llmq::CQuorumBlockProcessor& qblockman, const Consensus::Params& consensus_params, - const CMasternodeSync& mn_sync, const CSporkManager& sporkman, const llmq::CChainLocksHandler& clhandler) + const CMasternodeSync& mn_sync, const CSporkManager& sporkman, const llmq::CChainLocksHandler& clhandler, + const llmq::CQuorumManager& qman) : mn_payments{std::make_unique(dmnman, govman, consensus_params, mn_sync, sporkman)}, - special_tx{std::make_unique(cpoolman, dmnman, mnhfman, qblockman, consensus_params, clhandler)} + special_tx{std::make_unique(cpoolman, dmnman, mnhfman, qblockman, consensus_params, clhandler, qman)} {} CChainstateHelper::~CChainstateHelper() = default; diff --git a/src/evo/chainhelper.h b/src/evo/chainhelper.h index 06dded2af3575..4e687b3f28079 100644 --- a/src/evo/chainhelper.h +++ b/src/evo/chainhelper.h @@ -20,6 +20,7 @@ namespace Consensus { struct Params; } namespace llmq { class CChainLocksHandler; class CQuorumBlockProcessor; +class CQuorumManager; } class CChainstateHelper @@ -27,7 +28,8 @@ class CChainstateHelper public: explicit CChainstateHelper(CCreditPoolManager& cpoolman, CDeterministicMNManager& dmnman, CMNHFManager& mnhfman, CGovernanceManager& govman, llmq::CQuorumBlockProcessor& qblockman, const Consensus::Params& consensus_params, - const CMasternodeSync& mn_sync, const CSporkManager& sporkman, const llmq::CChainLocksHandler& clhandler); + const CMasternodeSync& mn_sync, const CSporkManager& sporkman, const llmq::CChainLocksHandler& clhandler, + const llmq::CQuorumManager& qman); ~CChainstateHelper(); CChainstateHelper() = delete; diff --git a/src/evo/creditpool.cpp b/src/evo/creditpool.cpp index 2e2648df4963a..fbea65f5ef1b1 100644 --- a/src/evo/creditpool.cpp +++ b/src/evo/creditpool.cpp @@ -267,12 +267,12 @@ bool CCreditPoolDiff::Unlock(const CTransaction& tx, TxValidationState& state) return true; } -bool CCreditPoolDiff::ProcessLockUnlockTransaction(const CTransaction& tx, TxValidationState& state) +bool CCreditPoolDiff::ProcessLockUnlockTransaction(const llmq::CQuorumManager& qman, const CTransaction& tx, TxValidationState& state) { if (!tx.IsSpecialTxVersion()) return true; if (tx.nType != TRANSACTION_ASSET_LOCK && tx.nType != TRANSACTION_ASSET_UNLOCK) return true; - if (!CheckAssetLockUnlockTx(tx, pindexPrev, pool.indexes, state)) { + if (!CheckAssetLockUnlockTx(qman, tx, pindexPrev, pool.indexes, state)) { // pass the state returned by the function above return false; } @@ -292,7 +292,7 @@ bool CCreditPoolDiff::ProcessLockUnlockTransaction(const CTransaction& tx, TxVal } } -std::optional GetCreditPoolDiffForBlock(CCreditPoolManager& cpoolman, const CBlock& block, const CBlockIndex* pindexPrev, +std::optional GetCreditPoolDiffForBlock(CCreditPoolManager& cpoolman, const llmq::CQuorumManager& qman, const CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams, const CAmount blockSubsidy, BlockValidationState& state) { try { @@ -302,7 +302,7 @@ std::optional GetCreditPoolDiffForBlock(CCreditPoolManager& cpo for (size_t i = 1; i < block.vtx.size(); ++i) { const auto& tx = *block.vtx[i]; TxValidationState tx_state; - if (!creditPoolDiff.ProcessLockUnlockTransaction(tx, tx_state)) { + if (!creditPoolDiff.ProcessLockUnlockTransaction(qman, tx, tx_state)) { assert(tx_state.GetResult() == TxValidationResult::TX_CONSENSUS); state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, tx_state.GetRejectReason(), strprintf("Process Lock/Unlock Transaction failed at Credit Pool (tx hash %s) %s", tx.GetHash().ToString(), tx_state.GetDebugMessage())); diff --git a/src/evo/creditpool.h b/src/evo/creditpool.h index 85ca170fc20b6..13b113f31b5f0 100644 --- a/src/evo/creditpool.h +++ b/src/evo/creditpool.h @@ -23,11 +23,12 @@ class CBlockIndex; class BlockValidationState; class TxValidationState; - -namespace Consensus -{ - struct Params; -} +namespace Consensus { +struct Params; +} // namespace Consensus +namespace llmq { +class CQuorumManager; +} // namespace llmq struct CCreditPool { CAmount locked{0}; @@ -82,7 +83,7 @@ class CCreditPoolDiff { * to change amount of credit pool * @return true if transaction can be included in this block */ - bool ProcessLockUnlockTransaction(const CTransaction& tx, TxValidationState& state); + bool ProcessLockUnlockTransaction(const llmq::CQuorumManager& qman, const CTransaction& tx, TxValidationState& state); /** * this function returns total amount of credits for the next block @@ -134,7 +135,7 @@ class CCreditPoolManager CCreditPool ConstructCreditPool(const CBlockIndex* block_index, CCreditPool prev, const Consensus::Params& consensusParams); }; -std::optional GetCreditPoolDiffForBlock(CCreditPoolManager& cpoolman, const CBlock& block, const CBlockIndex* pindexPrev, +std::optional GetCreditPoolDiffForBlock(CCreditPoolManager& cpoolman, const llmq::CQuorumManager& qman, const CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams, const CAmount blockSubsidy, BlockValidationState& state); #endif diff --git a/src/evo/mnhftx.cpp b/src/evo/mnhftx.cpp index 003f753e1ec11..8f1a14d92bb53 100644 --- a/src/evo/mnhftx.cpp +++ b/src/evo/mnhftx.cpp @@ -84,14 +84,14 @@ CMNHFManager::Signals CMNHFManager::GetSignalsStage(const CBlockIndex* const pin return signals; } -bool MNHFTx::Verify(const uint256& quorumHash, const uint256& requestId, const uint256& msgHash, TxValidationState& state) const +bool MNHFTx::Verify(const llmq::CQuorumManager& qman, const uint256& quorumHash, const uint256& requestId, const uint256& msgHash, TxValidationState& state) const { if (versionBit >= VERSIONBITS_NUM_BITS) { return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-mnhf-nbit-out-of-bounds"); } const Consensus::LLMQType& llmqType = Params().GetConsensus().llmqTypeMnhf; - const auto quorum = llmq::quorumManager->GetQuorum(llmqType, quorumHash); + const auto quorum = qman.GetQuorum(llmqType, quorumHash); const uint256 signHash = llmq::BuildSignHash(llmqType, quorum->qc->quorumHash, requestId, msgHash); if (!sig.VerifyInsecure(quorum->qc->quorumPublicKey, signHash)) { @@ -101,7 +101,7 @@ bool MNHFTx::Verify(const uint256& quorumHash, const uint256& requestId, const u return true; } -bool CheckMNHFTx(const CTransaction& tx, const CBlockIndex* pindexPrev, TxValidationState& state) +bool CheckMNHFTx(const llmq::CQuorumManager& qman, const CTransaction& tx, const CBlockIndex* pindexPrev, TxValidationState& state) { if (!tx.IsSpecialTxVersion() || tx.nType != TRANSACTION_MNHF_SIGNAL) { return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-mnhf-type"); @@ -134,7 +134,7 @@ bool CheckMNHFTx(const CTransaction& tx, const CBlockIndex* pindexPrev, TxValida uint256 msgHash = tx_copy.GetHash(); - if (!mnhfTx.signal.Verify(mnhfTx.signal.quorumHash, mnhfTx.GetRequestId(), msgHash, state)) { + if (!mnhfTx.signal.Verify(qman, mnhfTx.signal.quorumHash, mnhfTx.GetRequestId(), msgHash, state)) { // set up inside Verify return false; } @@ -160,7 +160,7 @@ std::optional extractEHFSignal(const CTransaction& tx) return opt_mnhfTx->signal.versionBit; } -static bool extractSignals(const CBlock& block, const CBlockIndex* const pindex, std::vector& new_signals, BlockValidationState& state) +static bool extractSignals(const llmq::CQuorumManager& qman, const CBlock& block, const CBlockIndex* const pindex, std::vector& new_signals, BlockValidationState& state) { // we skip the coinbase for (size_t i = 1; i < block.vtx.size(); ++i) { @@ -172,7 +172,7 @@ static bool extractSignals(const CBlock& block, const CBlockIndex* const pindex, } TxValidationState tx_state; - if (!CheckMNHFTx(tx, pindex, tx_state)) { + if (!CheckMNHFTx(qman, tx, pindex, tx_state)) { return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, tx_state.GetRejectReason(), tx_state.GetDebugMessage()); } @@ -192,9 +192,11 @@ static bool extractSignals(const CBlock& block, const CBlockIndex* const pindex, std::optional CMNHFManager::ProcessBlock(const CBlock& block, const CBlockIndex* const pindex, bool fJustCheck, BlockValidationState& state) { + assert(m_qman); + try { std::vector new_signals; - if (!extractSignals(block, pindex, new_signals, state)) { + if (!extractSignals(*m_qman, block, pindex, new_signals, state)) { // state is set inside extractSignals return std::nullopt; } @@ -244,9 +246,11 @@ std::optional CMNHFManager::ProcessBlock(const CBlock& bl bool CMNHFManager::UndoBlock(const CBlock& block, const CBlockIndex* const pindex) { + assert(m_qman); + std::vector excluded_signals; BlockValidationState state; - if (!extractSignals(block, pindex, excluded_signals, state)) { + if (!extractSignals(*m_qman, block, pindex, excluded_signals, state)) { LogPrintf("CMNHFManager::%s: failed to extract signals\n", __func__); return false; } @@ -350,6 +354,13 @@ void CMNHFManager::AddSignal(const CBlockIndex* const pindex, int bit) AddToCache(signals, pindex); } +void CMNHFManager::ConnectManagers(gsl::not_null qman) +{ + // Do not allow double-initialization + assert(m_qman == nullptr); + m_qman = qman; +} + std::string MNHFTx::ToString() const { return strprintf("MNHFTx(versionBit=%d, quorumHash=%s, sig=%s)", diff --git a/src/evo/mnhftx.h b/src/evo/mnhftx.h index 63d8f07cca15a..53425d60ab288 100644 --- a/src/evo/mnhftx.h +++ b/src/evo/mnhftx.h @@ -6,6 +6,7 @@ #define BITCOIN_EVO_MNHFTX_H #include +#include #include #include #include @@ -22,6 +23,9 @@ class CBlock; class CBlockIndex; class CEvoDB; class TxValidationState; +namespace llmq { +class CQuorumManager; +} // mnhf signal special transaction class MNHFTx @@ -32,7 +36,8 @@ class MNHFTx CBLSSignature sig{}; MNHFTx() = default; - bool Verify(const uint256& quorumHash, const uint256& requestId, const uint256& msgHash, TxValidationState& state) const; + bool Verify(const llmq::CQuorumManager& qman, const uint256& quorumHash, const uint256& requestId, const uint256& msgHash, + TxValidationState& state) const; SERIALIZE_METHODS(MNHFTx, obj) { @@ -95,6 +100,7 @@ class CMNHFManager : public AbstractEHFManager { private: CEvoDB& m_evoDb; + llmq::CQuorumManager* m_qman{nullptr}; static constexpr size_t MNHFCacheSize = 1000; Mutex cs_cache; @@ -111,17 +117,22 @@ class CMNHFManager : public AbstractEHFManager /** * Every new block should be processed when Tip() is updated by calling of CMNHFManager::ProcessBlock. * This function actually does only validate EHF transaction for this block and update internal caches/evodb state + * + * @pre Caller must ensure that LLMQContext has been initialized and the llmq::CQuorumManager pointer has been + * set by calling ConnectManagers() for this CMNHFManager instance */ std::optional ProcessBlock(const CBlock& block, const CBlockIndex* const pindex, bool fJustCheck, BlockValidationState& state); /** * Every undo block should be processed when Tip() is updated by calling of CMNHFManager::UndoBlock - * This function actually does nothing at the moment, because status of ancestor block is already know. + * This function actually does nothing at the moment, because status of ancestor block is already known. * Although it should be still called to do some sanity checks + * + * @pre Caller must ensure that LLMQContext has been initialized and the llmq::CQuorumManager pointer has been + * set by calling ConnectManagers() for this CMNHFManager instance */ bool UndoBlock(const CBlock& block, const CBlockIndex* const pindex); - // Implements interface Signals GetSignalsStage(const CBlockIndex* const pindexPrev) override; @@ -129,6 +140,22 @@ class CMNHFManager : public AbstractEHFManager * Helper that used in Unit Test to forcely setup EHF signal for specific block */ void AddSignal(const CBlockIndex* const pindex, int bit) EXCLUSIVE_LOCKS_REQUIRED(!cs_cache); + + /** + * Set llmq::CQuorumManager pointer. + * + * Separated from constructor to allow LLMQContext to use CMNHFManager in read-only capacity. + * Required to mutate state. + */ + void ConnectManagers(gsl::not_null qman); + + /** + * Reset llmq::CQuorumManager pointer. + * + * @pre Must be called before LLMQContext (containing llmq::CQuorumManager) is destroyed. + */ + void DisconnectManagers() { m_qman = nullptr; }; + private: void AddToCache(const Signals& signals, const CBlockIndex* const pindex); @@ -148,6 +175,6 @@ class CMNHFManager : public AbstractEHFManager }; std::optional extractEHFSignal(const CTransaction& tx); -bool CheckMNHFTx(const CTransaction& tx, const CBlockIndex* pindexPrev, TxValidationState& state); +bool CheckMNHFTx(const llmq::CQuorumManager& qman, const CTransaction& tx, const CBlockIndex* pindexPrev, TxValidationState& state); #endif // BITCOIN_EVO_MNHFTX_H diff --git a/src/evo/simplifiedmns.cpp b/src/evo/simplifiedmns.cpp index 08b0f7757eeff..bc80c1dd68341 100644 --- a/src/evo/simplifiedmns.cpp +++ b/src/evo/simplifiedmns.cpp @@ -183,14 +183,14 @@ bool CSimplifiedMNListDiff::BuildQuorumsDiff(const CBlockIndex* baseBlockIndex, return true; } -void CSimplifiedMNListDiff::BuildQuorumChainlockInfo(const CBlockIndex* blockIndex) +void CSimplifiedMNListDiff::BuildQuorumChainlockInfo(const llmq::CQuorumManager& qman, const CBlockIndex* blockIndex) { // Group quorums (indexes corresponding to entries of newQuorums) per CBlockIndex containing the expected CL signature in CbTx. // We want to avoid to load CbTx now, as more than one quorum will target the same block: hence we want to load CbTxs once per block (heavy operation). std::multimap workBaseBlockIndexMap; for (const auto [idx, e] : enumerate(newQuorums)) { - auto quorum = llmq::quorumManager->GetQuorum(e.llmqType, e.quorumHash); + auto quorum = qman.GetQuorum(e.llmqType, e.quorumHash); // In case of rotation, all rotated quorums rely on the CL sig expected in the cycleBlock (the block of the first DKG) - 8 // In case of non-rotation, quorums rely on the CL sig expected in the block of the DKG - 8 const CBlockIndex* pWorkBaseBlockIndex = @@ -317,7 +317,7 @@ CSimplifiedMNListDiff BuildSimplifiedDiff(const CDeterministicMNList& from, cons } bool BuildSimplifiedMNListDiff(const uint256& baseBlockHash, const uint256& blockHash, CSimplifiedMNListDiff& mnListDiffRet, - CDeterministicMNManager& dmnman, const llmq::CQuorumBlockProcessor& quorum_block_processor, + CDeterministicMNManager& dmnman, const llmq::CQuorumBlockProcessor& quorum_block_processor, const llmq::CQuorumManager& qman, std::string& errorRet, bool extended) { AssertLockHeld(cs_main); @@ -362,7 +362,7 @@ bool BuildSimplifiedMNListDiff(const uint256& baseBlockHash, const uint256& bloc } if (DeploymentActiveAfter(blockIndex, Params().GetConsensus(), Consensus::DEPLOYMENT_V20)) { - mnListDiffRet.BuildQuorumChainlockInfo(blockIndex); + mnListDiffRet.BuildQuorumChainlockInfo(qman, blockIndex); } // TODO store coinbase TX in CBlockIndex diff --git a/src/evo/simplifiedmns.h b/src/evo/simplifiedmns.h index 7768183932fdc..47e4c105f9547 100644 --- a/src/evo/simplifiedmns.h +++ b/src/evo/simplifiedmns.h @@ -20,6 +20,7 @@ class CDeterministicMN; namespace llmq { class CFinalCommitment; class CQuorumBlockProcessor; +class CQuorumManager; } // namespace llmq class CSimplifiedMNListEntry @@ -164,13 +165,13 @@ class CSimplifiedMNListDiff bool BuildQuorumsDiff(const CBlockIndex* baseBlockIndex, const CBlockIndex* blockIndex, const llmq::CQuorumBlockProcessor& quorum_block_processor); - void BuildQuorumChainlockInfo(const CBlockIndex* blockIndex); + void BuildQuorumChainlockInfo(const llmq::CQuorumManager& qman, const CBlockIndex* blockIndex); [[nodiscard]] UniValue ToJson(bool extended = false) const; }; bool BuildSimplifiedMNListDiff(const uint256& baseBlockHash, const uint256& blockHash, CSimplifiedMNListDiff& mnListDiffRet, - CDeterministicMNManager& dmnman, const llmq::CQuorumBlockProcessor& quorum_block_processor, + CDeterministicMNManager& dmnman, const llmq::CQuorumBlockProcessor& quorum_block_processor, const llmq::CQuorumManager& qman, std::string& errorRet, bool extended = false); #endif // BITCOIN_EVO_SIMPLIFIEDMNS_H diff --git a/src/evo/specialtxman.cpp b/src/evo/specialtxman.cpp index 8e71a0e68aafd..3c4739d6efcf1 100644 --- a/src/evo/specialtxman.cpp +++ b/src/evo/specialtxman.cpp @@ -18,7 +18,8 @@ #include #include -static bool CheckSpecialTxInner(CDeterministicMNManager& dmnman, const CTransaction& tx, const CBlockIndex* pindexPrev, const CCoinsViewCache& view, const std::optional& indexes, bool check_sigs, TxValidationState& state) +static bool CheckSpecialTxInner(CDeterministicMNManager& dmnman, const llmq::CQuorumManager& qman, const CTransaction& tx, const CBlockIndex* pindexPrev, + const CCoinsViewCache& view, const std::optional& indexes, bool check_sigs, TxValidationState& state) { AssertLockHeld(cs_main); @@ -48,12 +49,12 @@ static bool CheckSpecialTxInner(CDeterministicMNManager& dmnman, const CTransact if (!DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_V20)) { return state.Invalid(TxValidationResult::TX_CONSENSUS, "mnhf-before-v20"); } - return CheckMNHFTx(tx, pindexPrev, state); + return CheckMNHFTx(qman, tx, pindexPrev, state); case TRANSACTION_ASSET_LOCK: if (!DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_V20)) { return state.Invalid(TxValidationResult::TX_CONSENSUS, "assetlocks-before-v20"); } - return CheckAssetLockUnlockTx(tx, pindexPrev, indexes, state); + return CheckAssetLockUnlockTx(qman, tx, pindexPrev, indexes, state); case TRANSACTION_ASSET_UNLOCK: if (Params().NetworkIDString() == CBaseChainParams::REGTEST && !DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_V20)) { // TODO: adjust functional tests to make it activated by MN_RR on regtest too @@ -62,7 +63,7 @@ static bool CheckSpecialTxInner(CDeterministicMNManager& dmnman, const CTransact if (Params().NetworkIDString() != CBaseChainParams::REGTEST && !DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_MN_RR)) { return state.Invalid(TxValidationResult::TX_CONSENSUS, "assetunlocks-before-mn_rr"); } - return CheckAssetLockUnlockTx(tx, pindexPrev, indexes, state); + return CheckAssetLockUnlockTx(qman, tx, pindexPrev, indexes, state); } } catch (const std::exception& e) { LogPrintf("%s -- failed: %s\n", __func__, e.what()); @@ -75,7 +76,7 @@ static bool CheckSpecialTxInner(CDeterministicMNManager& dmnman, const CTransact bool CSpecialTxProcessor::CheckSpecialTx(const CTransaction& tx, const CBlockIndex* pindexPrev, const CCoinsViewCache& view, bool check_sigs, TxValidationState& state) { AssertLockHeld(cs_main); - return CheckSpecialTxInner(m_dmnman, tx, pindexPrev, view, std::nullopt, check_sigs, state); + return CheckSpecialTxInner(m_dmnman, m_qman, tx, pindexPrev, view, std::nullopt, check_sigs, state); } [[nodiscard]] bool CSpecialTxProcessor::ProcessSpecialTx(const CTransaction& tx, const CBlockIndex* pindex, TxValidationState& state) @@ -154,7 +155,7 @@ bool CSpecialTxProcessor::ProcessSpecialTxsInBlock(const CBlock& block, const CB TxValidationState tx_state; // At this moment CheckSpecialTx() and ProcessSpecialTx() may fail by 2 possible ways: // consensus failures and "TX_BAD_SPECIAL" - if (!CheckSpecialTxInner(m_dmnman, *ptr_tx, pindex->pprev, view, creditPool.indexes, fCheckCbTxMerkleRoots, tx_state)) { + if (!CheckSpecialTxInner(m_dmnman, m_qman, *ptr_tx, pindex->pprev, view, creditPool.indexes, fCheckCbTxMerkleRoots, tx_state)) { assert(tx_state.GetResult() == TxValidationResult::TX_CONSENSUS || tx_state.GetResult() == TxValidationResult::TX_BAD_SPECIAL); return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, tx_state.GetRejectReason(), strprintf("Special Transaction check failed (tx hash %s) %s", ptr_tx->GetHash().ToString(), tx_state.GetDebugMessage())); @@ -275,7 +276,7 @@ bool CSpecialTxProcessor::CheckCreditPoolDiffForBlock(const CBlock& block, const try { if (!DeploymentActiveAt(*pindex, m_consensus_params, Consensus::DEPLOYMENT_V20)) return true; - auto creditPoolDiff = GetCreditPoolDiffForBlock(m_cpoolman, block, pindex->pprev, m_consensus_params, blockSubsidy, state); + auto creditPoolDiff = GetCreditPoolDiffForBlock(m_cpoolman, m_qman, block, pindex->pprev, m_consensus_params, blockSubsidy, state); if (!creditPoolDiff.has_value()) return false; // If we get there we have v20 activated and credit pool amount must be included in block CbTx diff --git a/src/evo/specialtxman.h b/src/evo/specialtxman.h index f8464fc64e57c..cddc978961291 100644 --- a/src/evo/specialtxman.h +++ b/src/evo/specialtxman.h @@ -24,6 +24,7 @@ struct MNListUpdates; namespace Consensus { struct Params; } namespace llmq { class CQuorumBlockProcessor; +class CQuorumManager; class CChainLocksHandler; } // namespace llmq @@ -38,6 +39,7 @@ class CSpecialTxProcessor llmq::CQuorumBlockProcessor& m_qblockman; const Consensus::Params& m_consensus_params; const llmq::CChainLocksHandler& m_clhandler; + const llmq::CQuorumManager& m_qman; private: [[nodiscard]] bool ProcessSpecialTx(const CTransaction& tx, const CBlockIndex* pindex, TxValidationState& state); @@ -45,8 +47,9 @@ class CSpecialTxProcessor public: explicit CSpecialTxProcessor(CCreditPoolManager& cpoolman, CDeterministicMNManager& dmnman, CMNHFManager& mnhfman, llmq::CQuorumBlockProcessor& qblockman, - const Consensus::Params& consensus_params, const llmq::CChainLocksHandler& clhandler) : - m_cpoolman(cpoolman), m_dmnman{dmnman}, m_mnhfman{mnhfman}, m_qblockman{qblockman}, m_consensus_params{consensus_params}, m_clhandler{clhandler} {} + const Consensus::Params& consensus_params, const llmq::CChainLocksHandler& clhandler, const llmq::CQuorumManager& qman) : + m_cpoolman(cpoolman), m_dmnman{dmnman}, m_mnhfman{mnhfman}, m_qblockman{qblockman}, m_consensus_params{consensus_params}, m_clhandler{clhandler}, + m_qman{qman} {} bool CheckSpecialTx(const CTransaction& tx, const CBlockIndex* pindexPrev, const CCoinsViewCache& view, bool check_sigs, TxValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(cs_main); diff --git a/src/init.cpp b/src/init.cpp index d600e54a856fe..d90d891601a73 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -340,9 +340,10 @@ void PrepareShutdown(NodeContext& node) } pblocktree.reset(); node.chain_helper.reset(); - if (node.llmq_ctx) { - node.llmq_ctx.reset(); + if (node.mnhf_manager) { + node.mnhf_manager->DisconnectManagers(); } + node.llmq_ctx.reset(); llmq::quorumSnapshotManager.reset(); node.mempool->DisconnectManagers(); node.dmnman.reset(); @@ -1974,12 +1975,14 @@ 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.mn_metaman, *node.mnhf_manager, *node.sporkman, *node.mempool, node.mn_activeman.get(), *node.mn_sync, node.peerman, /* unit_tests = */ false, /* wipe = */ fReset || fReindexChainState); + // Enable CMNHFManager::{Process, Undo}Block + node.mnhf_manager->ConnectManagers(node.llmq_ctx->qman.get()); // Have to start it early to let VerifyDB check ChainLock signatures in coinbase node.llmq_ctx->Start(); node.chain_helper.reset(); 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)); + chainparams.GetConsensus(), *node.mn_sync, *node.sporkman, *(node.llmq_ctx->clhandler), *(node.llmq_ctx->qman)); if (fReset) { pblocktree->WriteReindexing(true); diff --git a/src/llmq/blockprocessor.cpp b/src/llmq/blockprocessor.cpp index f3c6c9f9709bb..ac4ca6eb43027 100644 --- a/src/llmq/blockprocessor.cpp +++ b/src/llmq/blockprocessor.cpp @@ -38,9 +38,6 @@ static void PreComputeQuorumMembers(CDeterministicMNManager& dmnman, const CBloc namespace llmq { - -std::unique_ptr quorumBlockProcessor; - static const std::string DB_MINED_COMMITMENT = "q_mc"; static const std::string DB_MINED_COMMITMENT_BY_INVERSED_HEIGHT = "q_mcih"; static const std::string DB_MINED_COMMITMENT_BY_INVERSED_HEIGHT_Q_INDEXED = "q_mcihi"; diff --git a/src/llmq/blockprocessor.h b/src/llmq/blockprocessor.h index b77f125233a3f..a1131a9a19698 100644 --- a/src/llmq/blockprocessor.h +++ b/src/llmq/blockprocessor.h @@ -79,9 +79,6 @@ class CQuorumBlockProcessor size_t GetNumCommitmentsRequired(const Consensus::LLMQParams& llmqParams, int nHeight) const EXCLUSIVE_LOCKS_REQUIRED(cs_main); static uint256 GetQuorumBlockHash(const Consensus::LLMQParams& llmqParams, int nHeight, int quorumIndex) EXCLUSIVE_LOCKS_REQUIRED(cs_main); }; - -extern std::unique_ptr quorumBlockProcessor; - } // namespace llmq #endif // BITCOIN_LLMQ_BLOCKPROCESSOR_H diff --git a/src/llmq/context.cpp b/src/llmq/context.cpp index 220cd2de11562..9890475ce7cf1 100644 --- a/src/llmq/context.cpp +++ b/src/llmq/context.cpp @@ -24,30 +24,22 @@ LLMQContext::LLMQContext(CChainState& chainstate, CConnman& connman, CDeterminis is_masternode{mn_activeman != nullptr}, 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(chainstate, dmnman, evo_db, peerman); - return llmq::quorumBlockProcessor.get(); - }()}, + quorum_block_processor{std::make_unique(chainstate, dmnman, evo_db, peerman)}, qdkgsman{std::make_unique(*bls_worker, chainstate, connman, dmnman, *dkg_debugman, mn_metaman, *quorum_block_processor, mn_activeman, sporkman, peerman, 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); - return llmq::quorumManager.get(); - }()}, - sigman{std::make_unique(connman, mn_activeman, *llmq::quorumManager, peerman, unit_tests, wipe)}, - shareman{std::make_unique(connman, *sigman, mn_activeman, *llmq::quorumManager, sporkman, peerman)}, + qman{std::make_unique(*bls_worker, chainstate, connman, dmnman, *qdkgsman, evo_db, *quorum_block_processor, mn_activeman, mn_sync, sporkman)}, + sigman{std::make_unique(connman, mn_activeman, *qman, peerman, unit_tests, wipe)}, + shareman{std::make_unique(connman, *sigman, mn_activeman, *qman, sporkman, peerman)}, clhandler{[&]() -> llmq::CChainLocksHandler* const { assert(llmq::chainLocksHandler == nullptr); - llmq::chainLocksHandler = std::make_unique(chainstate, *llmq::quorumManager, *sigman, *shareman, sporkman, mempool, mn_sync, peerman, is_masternode); + llmq::chainLocksHandler = std::make_unique(chainstate, *qman, *sigman, *shareman, sporkman, mempool, mn_sync, peerman, is_masternode); 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, mn_sync, peerman, is_masternode, unit_tests, wipe); + llmq::quorumInstantSendManager = std::make_unique(*llmq::chainLocksHandler, chainstate, connman, *qman, *sigman, *shareman, sporkman, mempool, mn_sync, peerman, is_masternode, unit_tests, wipe); return llmq::quorumInstantSendManager.get(); }()}, - ehfSignalsHandler{std::make_unique(chainstate, mnhfman, *sigman, *shareman, mempool, *llmq::quorumManager, sporkman, peerman)} + ehfSignalsHandler{std::make_unique(chainstate, mnhfman, *sigman, *shareman, mempool, *qman, sporkman, peerman)} { // NOTE: we use this only to wipe the old db, do NOT use it for anything else // TODO: remove it in some future version @@ -58,8 +50,6 @@ LLMQContext::~LLMQContext() { // LLMQContext doesn't own these objects, but still need to care of them for consistency: llmq::quorumInstantSendManager.reset(); llmq::chainLocksHandler.reset(); - llmq::quorumManager.reset(); - llmq::quorumBlockProcessor.reset(); } void LLMQContext::Interrupt() { @@ -71,8 +61,6 @@ void LLMQContext::Interrupt() { } void LLMQContext::Start() { - assert(quorum_block_processor == llmq::quorumBlockProcessor.get()); - assert(qman == llmq::quorumManager.get()); assert(clhandler == llmq::chainLocksHandler.get()); assert(isman == llmq::quorumInstantSendManager.get()); @@ -90,8 +78,6 @@ void LLMQContext::Start() { } void LLMQContext::Stop() { - assert(quorum_block_processor == llmq::quorumBlockProcessor.get()); - assert(qman == llmq::quorumManager.get()); assert(clhandler == llmq::chainLocksHandler.get()); assert(isman == llmq::quorumInstantSendManager.get()); diff --git a/src/llmq/context.h b/src/llmq/context.h index 99c73c84cb742..7d41111c4a3df 100644 --- a/src/llmq/context.h +++ b/src/llmq/context.h @@ -54,7 +54,7 @@ struct LLMQContext { * * Please note, that members here should not be re-ordered, because initialization * some of them requires other member initialized. - * For example, constructor `quorumManager` requires `bls_worker`. + * For example, constructor `qman` requires `bls_worker`. * * Some objects are still global variables and their de-globalization is not trivial * at this point. LLMQContext keeps just a pointer to them and doesn't own these objects, @@ -62,9 +62,9 @@ struct LLMQContext { */ const std::shared_ptr bls_worker; const std::unique_ptr dkg_debugman; - llmq::CQuorumBlockProcessor* const quorum_block_processor; + const std::unique_ptr quorum_block_processor; const std::unique_ptr qdkgsman; - llmq::CQuorumManager* const qman; + const std::unique_ptr qman; const std::unique_ptr sigman; const std::unique_ptr shareman; llmq::CChainLocksHandler* const clhandler; diff --git a/src/llmq/quorums.cpp b/src/llmq/quorums.cpp index d6915b279e3cf..1790438b9c042 100644 --- a/src/llmq/quorums.cpp +++ b/src/llmq/quorums.cpp @@ -33,8 +33,6 @@ namespace llmq static const std::string DB_QUORUM_SK_SHARE = "q_Qsk"; static const std::string DB_QUORUM_QUORUM_VVEC = "q_Qqvvec"; -std::unique_ptr quorumManager; - RecursiveMutex cs_data_requests; static std::unordered_map mapQuorumDataRequests GUARDED_BY(cs_data_requests); diff --git a/src/llmq/quorums.h b/src/llmq/quorums.h index b006152a4a9f5..cff5f87aa01a0 100644 --- a/src/llmq/quorums.h +++ b/src/llmq/quorums.h @@ -289,8 +289,6 @@ class CQuorumManager void StartCleanupOldQuorumDataThread(const CBlockIndex* pIndex) const; }; -extern std::unique_ptr quorumManager; - // when selecting a quorum for signing and verification, we use CQuorumManager::SelectQuorum with this offset as // starting height for scanning. This is because otherwise the resulting signatures would not be verifiable by nodes // which are not 100% at the chain tip. diff --git a/src/llmq/snapshot.cpp b/src/llmq/snapshot.cpp index 1abe3e77e37af..38f588671db4c 100644 --- a/src/llmq/snapshot.cpp +++ b/src/llmq/snapshot.cpp @@ -87,7 +87,7 @@ UniValue CQuorumRotationInfo::ToJson() const bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotationInfo& response, CDeterministicMNManager& dmnman, const CQuorumManager& qman, - const CQuorumBlockProcessor& quorumBlockProcessor, std::string& errorRet) + const CQuorumBlockProcessor& quorum_block_processor, std::string& errorRet) { AssertLockHeld(cs_main); @@ -123,7 +123,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat return false; } //Build MN list Diff always with highest baseblock - if (!BuildSimplifiedMNListDiff(baseBlockIndexes.back()->GetBlockHash(), tipBlockIndex->GetBlockHash(), response.mnListDiffTip, dmnman, quorumBlockProcessor, errorRet)) { + if (!BuildSimplifiedMNListDiff(baseBlockIndexes.back()->GetBlockHash(), tipBlockIndex->GetBlockHash(), response.mnListDiffTip, dmnman, quorum_block_processor, qman, errorRet)) { return false; } @@ -156,7 +156,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat } //Build MN list Diff always with highest baseblock - if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockIndex), pWorkBlockIndex->GetBlockHash(), response.mnListDiffH, dmnman, quorumBlockProcessor, errorRet)) { + if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockIndex), pWorkBlockIndex->GetBlockHash(), response.mnListDiffH, dmnman, quorum_block_processor, qman, errorRet)) { return false; } @@ -202,7 +202,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat const CBlockIndex* pWorkBlockHMinus4CIndex = pBlockHMinus4CIndex->GetAncestor(pBlockHMinus4CIndex->nHeight - workDiff); //Checked later if extraShare is on - if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockHMinusCIndex), pWorkBlockHMinusCIndex->GetBlockHash(), response.mnListDiffAtHMinusC, dmnman, quorumBlockProcessor, errorRet)) { + if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockHMinusCIndex), pWorkBlockHMinusCIndex->GetBlockHash(), response.mnListDiffAtHMinusC, dmnman, quorum_block_processor, qman, errorRet)) { return false; } @@ -214,7 +214,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat response.quorumSnapshotAtHMinusC = std::move(snapshotHMinusC.value()); } - if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockHMinus2CIndex), pWorkBlockHMinus2CIndex->GetBlockHash(), response.mnListDiffAtHMinus2C, dmnman, quorumBlockProcessor, errorRet)) { + if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockHMinus2CIndex), pWorkBlockHMinus2CIndex->GetBlockHash(), response.mnListDiffAtHMinus2C, dmnman, quorum_block_processor, qman, errorRet)) { return false; } @@ -226,7 +226,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat response.quorumSnapshotAtHMinus2C = std::move(snapshotHMinus2C.value()); } - if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockHMinus3CIndex), pWorkBlockHMinus3CIndex->GetBlockHash(), response.mnListDiffAtHMinus3C, dmnman, quorumBlockProcessor, errorRet)) { + if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockHMinus3CIndex), pWorkBlockHMinus3CIndex->GetBlockHash(), response.mnListDiffAtHMinus3C, dmnman, quorum_block_processor, qman, errorRet)) { return false; } @@ -255,7 +255,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat } CSimplifiedMNListDiff mn4c; - if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockHMinus4CIndex), pWorkBlockHMinus4CIndex->GetBlockHash(), mn4c, dmnman, quorumBlockProcessor, errorRet)) { + if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockHMinus4CIndex), pWorkBlockHMinus4CIndex->GetBlockHash(), mn4c, dmnman, quorum_block_processor, qman, errorRet)) { return false; } @@ -268,11 +268,11 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat std::set snapshotHeightsNeeded; - std::vector> qdata = quorumBlockProcessor.GetLastMinedCommitmentsPerQuorumIndexUntilBlock(llmqType, blockIndex, 0); + std::vector> qdata = quorum_block_processor.GetLastMinedCommitmentsPerQuorumIndexUntilBlock(llmqType, blockIndex, 0); for (const auto& obj : qdata) { uint256 minedBlockHash; - llmq::CFinalCommitmentPtr qc = quorumBlockProcessor.GetMinedCommitment(llmqType, obj.second->GetBlockHash(), minedBlockHash); + llmq::CFinalCommitmentPtr qc = quorum_block_processor.GetMinedCommitment(llmqType, obj.second->GetBlockHash(), minedBlockHash); if (qc == nullptr) { return false; } @@ -311,7 +311,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat } CSimplifiedMNListDiff mnhneeded; - if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pNeededWorkBlockIndex), pNeededWorkBlockIndex->GetBlockHash(), mnhneeded, dmnman, quorumBlockProcessor, errorRet)) { + if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pNeededWorkBlockIndex), pNeededWorkBlockIndex->GetBlockHash(), mnhneeded, dmnman, quorum_block_processor, qman, errorRet)) { return false; } diff --git a/src/miner.cpp b/src/miner.cpp index 155fbcd47ef03..a27d08bef716d 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -70,7 +70,8 @@ BlockAssembler::BlockAssembler(CChainState& chainstate, const NodeContext& node, m_cpoolman(*Assert(node.cpoolman)), m_chain_helper(*Assert(node.chain_helper)), m_mnhfman(*Assert(node.mnhf_manager)), - quorum_block_processor(*Assert(Assert(node.llmq_ctx)->quorum_block_processor)), + m_quorum_block_processor(*Assert(Assert(node.llmq_ctx)->quorum_block_processor)), + m_qman(*Assert(Assert(node.llmq_ctx)->qman)), m_clhandler(*Assert(Assert(node.llmq_ctx)->clhandler)), m_isman(*Assert(Assert(node.llmq_ctx)->isman)), m_evoDb(*Assert(node.evodb)) @@ -160,9 +161,9 @@ std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& sc if (fDIP0003Active_context) { for (const Consensus::LLMQParams& params : llmq::GetEnabledQuorumParams(pindexPrev)) { std::vector vqcTx; - if (quorum_block_processor.GetMineableCommitmentsTx(params, - nHeight, - vqcTx)) { + if (m_quorum_block_processor.GetMineableCommitmentsTx(params, + nHeight, + vqcTx)) { for (const auto& qcTx : vqcTx) { pblock->vtx.emplace_back(qcTx); pblocktemplate->vTxFees.emplace_back(0); @@ -224,7 +225,7 @@ std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& sc throw std::runtime_error(strprintf("%s: CalcCbTxMerkleRootMNList failed: %s", __func__, state.ToString())); } if (fDIP0008Active_context) { - if (!CalcCbTxMerkleRootQuorums(*pblock, pindexPrev, quorum_block_processor, cbTx.merkleRootQuorums, state)) { + if (!CalcCbTxMerkleRootQuorums(*pblock, pindexPrev, m_quorum_block_processor, cbTx.merkleRootQuorums, state)) { throw std::runtime_error(strprintf("%s: CalcCbTxMerkleRootQuorums failed: %s", __func__, state.ToString())); } if (fV20Active_context) { @@ -235,7 +236,7 @@ std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& sc LogPrintf("CreateNewBlock() h[%d] CbTx failed to find best CL. Inserting null CL\n", nHeight); } BlockValidationState state; - const auto creditPoolDiff = GetCreditPoolDiffForBlock(m_cpoolman, *pblock, pindexPrev, chainparams.GetConsensus(), blockSubsidy, state); + const auto creditPoolDiff = GetCreditPoolDiffForBlock(m_cpoolman, m_qman, *pblock, pindexPrev, chainparams.GetConsensus(), blockSubsidy, state); if (creditPoolDiff == std::nullopt) { throw std::runtime_error(strprintf("%s: GetCreditPoolDiffForBlock failed: %s", __func__, state.ToString())); } @@ -471,7 +472,7 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda // `state` is local here because used only to log info about this specific tx TxValidationState state; - if (!creditPoolDiff->ProcessLockUnlockTransaction(iter->GetTx(), state)) { + if (!creditPoolDiff->ProcessLockUnlockTransaction(m_qman, iter->GetTx(), state)) { if (fUsingModified) { mapModifiedTx.get().erase(modit); failedTx.insert(iter); diff --git a/src/miner.h b/src/miner.h index 5efe21d461924..ccc3e2fa67006 100644 --- a/src/miner.h +++ b/src/miner.h @@ -33,6 +33,7 @@ namespace llmq { class CChainLocksHandler; class CInstantSendManager; class CQuorumBlockProcessor; +class CQuorumManager; } // namespace llmq static const bool DEFAULT_PRINTPRIORITY = false; @@ -165,7 +166,8 @@ class BlockAssembler CCreditPoolManager& m_cpoolman; CChainstateHelper& m_chain_helper; CMNHFManager& m_mnhfman; - const llmq::CQuorumBlockProcessor& quorum_block_processor; + const llmq::CQuorumBlockProcessor& m_quorum_block_processor; + const llmq::CQuorumManager& m_qman; llmq::CChainLocksHandler& m_clhandler; llmq::CInstantSendManager& m_isman; CEvoDB& m_evoDb; diff --git a/src/net_processing.cpp b/src/net_processing.cpp index c35a125a2b4ed..c809e8231fdfc 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -4770,7 +4770,7 @@ void PeerManagerImpl::ProcessMessage( CSimplifiedMNListDiff mnListDiff; std::string strError; - if (BuildSimplifiedMNListDiff(cmd.baseBlockHash, cmd.blockHash, mnListDiff, *m_dmnman, *m_llmq_ctx->quorum_block_processor, strError)) { + if (BuildSimplifiedMNListDiff(cmd.baseBlockHash, cmd.blockHash, mnListDiff, *m_dmnman, *m_llmq_ctx->quorum_block_processor, *m_llmq_ctx->qman, strError)) { m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::MNLISTDIFF, mnListDiff)); } else { strError = strprintf("getmnlistdiff failed for baseBlockHash=%s, blockHash=%s. error=%s", cmd.baseBlockHash.ToString(), cmd.blockHash.ToString(), strError); diff --git a/src/rpc/evo.cpp b/src/rpc/evo.cpp index d5fa516875640..7b1da41f69422 100644 --- a/src/rpc/evo.cpp +++ b/src/rpc/evo.cpp @@ -1527,7 +1527,7 @@ static UniValue protx_diff(const JSONRPCRequest& request, CDeterministicMNManage CSimplifiedMNListDiff mnListDiff; std::string strError; - if (!BuildSimplifiedMNListDiff(baseBlockHash, blockHash, mnListDiff, dmnman, *llmq_ctx.quorum_block_processor, strError, extended)) { + if (!BuildSimplifiedMNListDiff(baseBlockHash, blockHash, mnListDiff, dmnman, *llmq_ctx.quorum_block_processor, *llmq_ctx.qman, strError, extended)) { throw std::runtime_error(strError); } diff --git a/src/test/evo_assetlocks_tests.cpp b/src/test/evo_assetlocks_tests.cpp index 5d1ac8622ccd6..835a39b9dcd2b 100644 --- a/src/test/evo_assetlocks_tests.cpp +++ b/src/test/evo_assetlocks_tests.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include