From a35245653c15bc8d0abc161f214cf0f25e533713 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com> Date: Thu, 22 Sep 2022 16:44:48 +0530 Subject: [PATCH] refactor: pass references to objects instead of using global definitions (#4988) * fix: move chain activation logic downward to succeed LLMQ initialization * fix: change order of initialization to reflect dependency * llmq: pass all global pointers invoked as CDSNotificationInterface arguments * llmq: pass reference to quorumDKGDebugManager instead of invoking global * llmq: pass reference to quorumBlockProcessor instead of invoking global * llmq: pass reference to quorumDKGSessionManager instead of invoking global * llmq: pass reference to quorumManager instead of invoking global Co-authored-by: "UdjinM6 " * llmq: pass reference to quorumSigSharesManager within CSigningManager and networking * llmq: pass reference to quorumSigSharesManager instead of invoking global * llmq: pass reference to chainLocksHandler instead of querying global * llmq: pass reference to quorumInstantSendManager instead of querying global * trivial: accept argument as const where possible * style: remove an unneeded const_cast and instead pass by const reference * style: use const where possible Co-authored-by: pasta --- src/coinjoin/coinjoin.cpp | 16 +-- src/coinjoin/coinjoin.h | 12 +- src/dsnotificationinterface.cpp | 51 ++++---- src/dsnotificationinterface.h | 27 ++++- src/evo/cbtx.cpp | 14 +-- src/evo/cbtx.h | 8 +- src/evo/mnhftx.cpp | 5 +- src/evo/simplifiedmns.cpp | 14 ++- src/evo/simplifiedmns.h | 12 +- src/evo/specialtxman.cpp | 11 +- src/evo/specialtxman.h | 5 +- src/init.cpp | 16 ++- src/llmq/chainlocks.cpp | 23 ++-- src/llmq/chainlocks.h | 9 +- src/llmq/dkgsession.cpp | 26 ++-- src/llmq/dkgsession.h | 6 +- src/llmq/dkgsessionhandler.cpp | 12 +- src/llmq/dkgsessionhandler.h | 12 +- src/llmq/dkgsessionmgr.cpp | 10 +- src/llmq/dkgsessionmgr.h | 8 +- src/llmq/init.cpp | 14 +-- src/llmq/instantsend.cpp | 51 ++++---- src/llmq/instantsend.h | 16 ++- src/llmq/quorums.cpp | 22 ++-- src/llmq/quorums.h | 8 +- src/llmq/signing.cpp | 38 +++--- src/llmq/signing.h | 15 +-- src/llmq/signing_shares.cpp | 50 ++++---- src/llmq/signing_shares.h | 8 +- src/llmq/snapshot.cpp | 23 ++-- src/llmq/snapshot.h | 6 +- src/llmq/utils.cpp | 24 ++-- src/llmq/utils.h | 9 +- src/miner.cpp | 26 ++-- src/miner.h | 14 ++- src/net_processing.cpp | 111 +++++++++++------- src/net_processing.h | 23 +++- src/rpc/mining.cpp | 13 +- src/rpc/rpcevo.cpp | 3 +- src/rpc/rpcquorums.cpp | 20 ++-- src/test/block_reward_reallocation_tests.cpp | 17 +-- src/test/blockfilter_index_tests.cpp | 5 +- src/test/denialofservice_tests.cpp | 37 +++++- .../dynamic_activation_thresholds_tests.cpp | 5 +- src/test/evo_utils_tests.cpp | 34 +++--- src/test/fuzz/process_message.cpp | 12 +- src/test/miner_tests.cpp | 5 +- src/test/util.cpp | 5 +- src/test/util/setup_common.cpp | 40 ++++--- src/test/validation_block_tests.cpp | 5 +- src/test/validation_chainstate_tests.cpp | 5 +- .../validation_chainstatemanager_tests.cpp | 13 +- src/test/validation_flush_tests.cpp | 5 +- src/validation.cpp | 42 +++++-- src/validation.h | 25 +++- 55 files changed, 660 insertions(+), 386 deletions(-) diff --git a/src/coinjoin/coinjoin.cpp b/src/coinjoin/coinjoin.cpp index 68e21d5374..8a61863751 100644 --- a/src/coinjoin/coinjoin.cpp +++ b/src/coinjoin/coinjoin.cpp @@ -117,12 +117,12 @@ bool CCoinJoinBroadcastTx::CheckSignature(const CBLSPublicKey& blsPubKey) const return true; } -bool CCoinJoinBroadcastTx::IsExpired(const CBlockIndex* pindex) const +bool CCoinJoinBroadcastTx::IsExpired(const CBlockIndex* pindex, const llmq::CChainLocksHandler& clhandler) const { // expire confirmed DSTXes after ~1h since confirmation or chainlocked confirmation if (nConfirmedHeight == -1 || pindex->nHeight < nConfirmedHeight) return false; // not mined yet if (pindex->nHeight - nConfirmedHeight > 24) return true; // mined more than an hour ago - return llmq::chainLocksHandler->HasChainLock(pindex->nHeight, *pindex->phashBlock); + return clhandler.HasChainLock(pindex->nHeight, *pindex->phashBlock); } bool CCoinJoinBroadcastTx::IsValidStructure() const @@ -440,13 +440,13 @@ CCoinJoinBroadcastTx CCoinJoin::GetDSTX(const uint256& hash) return (it == mapDSTX.end()) ? CCoinJoinBroadcastTx() : it->second; } -void CCoinJoin::CheckDSTXes(const CBlockIndex* pindex) +void CCoinJoin::CheckDSTXes(const CBlockIndex* pindex, const llmq::CChainLocksHandler& clhandler) { AssertLockNotHeld(cs_mapdstx); LOCK(cs_mapdstx); auto it = mapDSTX.begin(); while (it != mapDSTX.end()) { - if (it->second.IsExpired(pindex)) { + if (it->second.IsExpired(pindex, clhandler)) { mapDSTX.erase(it++); } else { ++it; @@ -455,17 +455,17 @@ void CCoinJoin::CheckDSTXes(const CBlockIndex* pindex) LogPrint(BCLog::COINJOIN, "CCoinJoin::CheckDSTXes -- mapDSTX.size()=%llu\n", mapDSTX.size()); } -void CCoinJoin::UpdatedBlockTip(const CBlockIndex* pindex) +void CCoinJoin::UpdatedBlockTip(const CBlockIndex* pindex, const llmq::CChainLocksHandler& clhandler) { if (pindex && masternodeSync->IsBlockchainSynced()) { - CheckDSTXes(pindex); + CheckDSTXes(pindex, clhandler); } } -void CCoinJoin::NotifyChainLock(const CBlockIndex* pindex) +void CCoinJoin::NotifyChainLock(const CBlockIndex* pindex, const llmq::CChainLocksHandler& clhandler) { if (pindex && masternodeSync->IsBlockchainSynced()) { - CheckDSTXes(pindex); + CheckDSTXes(pindex, clhandler); } } diff --git a/src/coinjoin/coinjoin.h b/src/coinjoin/coinjoin.h index 648339adf9..5dea250cfa 100644 --- a/src/coinjoin/coinjoin.h +++ b/src/coinjoin/coinjoin.h @@ -23,6 +23,10 @@ class CConnman; class CBLSPublicKey; class CBlockIndex; +namespace llmq { +class CChainLocksHandler; +} // namespace llmq + // timeouts static constexpr int COINJOIN_AUTO_TIMEOUT_MIN = 5; static constexpr int COINJOIN_AUTO_TIMEOUT_MAX = 15; @@ -298,7 +302,7 @@ public: bool CheckSignature(const CBLSPublicKey& blsPubKey) const; void SetConfirmedHeight(int nConfirmedHeightIn) { nConfirmedHeight = nConfirmedHeightIn; } - bool IsExpired(const CBlockIndex* pindex) const; + bool IsExpired(const CBlockIndex* pindex, const llmq::CChainLocksHandler& clhandler) const; bool IsValidStructure() const; }; @@ -374,7 +378,7 @@ private: static Mutex cs_mapdstx; static std::map mapDSTX GUARDED_BY(cs_mapdstx); - static void CheckDSTXes(const CBlockIndex* pindex) LOCKS_EXCLUDED(cs_mapdstx); + static void CheckDSTXes(const CBlockIndex* pindex, const llmq::CChainLocksHandler& clhandler) LOCKS_EXCLUDED(cs_mapdstx); public: static constexpr std::array GetStandardDenominations() { return vecStandardDenominations; } @@ -477,8 +481,8 @@ public: static void AddDSTX(const CCoinJoinBroadcastTx& dstx) LOCKS_EXCLUDED(cs_mapdstx); static CCoinJoinBroadcastTx GetDSTX(const uint256& hash) LOCKS_EXCLUDED(cs_mapdstx); - static void UpdatedBlockTip(const CBlockIndex* pindex); - static void NotifyChainLock(const CBlockIndex* pindex); + static void UpdatedBlockTip(const CBlockIndex* pindex, const llmq::CChainLocksHandler& clhandler); + static void NotifyChainLock(const CBlockIndex* pindex, const llmq::CChainLocksHandler& clhandler); static void UpdateDSTXConfirmedHeight(const CTransactionRef& tx, int nHeight); static void TransactionAddedToMempool(const CTransactionRef& tx) LOCKS_EXCLUDED(cs_mapdstx); diff --git a/src/dsnotificationinterface.cpp b/src/dsnotificationinterface.cpp index 9efd509bed..0160293c61 100644 --- a/src/dsnotificationinterface.cpp +++ b/src/dsnotificationinterface.cpp @@ -20,6 +20,13 @@ #include #include +CDSNotificationInterface::CDSNotificationInterface(CConnman& _connman, + std::unique_ptr& _mnsync, std::unique_ptr& _dmnman, + std::unique_ptr& _govman, std::unique_ptr& _clhandler, + std::unique_ptr& _isman, std::unique_ptr& _qman, + std::unique_ptr& _qdkgsman +) : connman(_connman), mnsync(_mnsync), dmnman(_dmnman), govman(_govman), clhandler(_clhandler), isman(_isman), qman(_qman), qdkgsman(_qdkgsman) {} + void CDSNotificationInterface::InitializeCurrentBlockTip() { SynchronousUpdatedBlockTip(::ChainActive().Tip(), nullptr, ::ChainstateActive().IsInitialBlockDownload()); @@ -28,15 +35,15 @@ void CDSNotificationInterface::InitializeCurrentBlockTip() void CDSNotificationInterface::AcceptedBlockHeader(const CBlockIndex *pindexNew) { - llmq::chainLocksHandler->AcceptedBlockHeader(pindexNew); - if (masternodeSync != nullptr) { - masternodeSync->AcceptedBlockHeader(pindexNew); + clhandler->AcceptedBlockHeader(pindexNew); + if (mnsync != nullptr) { + mnsync->AcceptedBlockHeader(pindexNew); } } void CDSNotificationInterface::NotifyHeaderTip(const CBlockIndex *pindexNew, bool fInitialDownload) { - masternodeSync->NotifyHeaderTip(pindexNew, fInitialDownload); + mnsync->NotifyHeaderTip(pindexNew, fInitialDownload); } void CDSNotificationInterface::SynchronousUpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) @@ -44,7 +51,7 @@ void CDSNotificationInterface::SynchronousUpdatedBlockTip(const CBlockIndex *pin if (pindexNew == pindexFork) // blocks were disconnected without any new ones return; - deterministicMNManager->UpdatedBlockTip(pindexNew); + dmnman->UpdatedBlockTip(pindexNew); } void CDSNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) @@ -52,7 +59,7 @@ void CDSNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, con if (pindexNew == pindexFork) // blocks were disconnected without any new ones return; - masternodeSync->UpdatedBlockTip(pindexNew, fInitialDownload); + mnsync->UpdatedBlockTip(pindexNew, fInitialDownload); // Update global DIP0001 activation status fDIP0001ActiveAtTip = pindexNew->nHeight >= Params().GetConsensus().DIP0001Height; @@ -60,32 +67,32 @@ void CDSNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, con if (fInitialDownload) return; - CCoinJoin::UpdatedBlockTip(pindexNew); + CCoinJoin::UpdatedBlockTip(pindexNew, *clhandler); #ifdef ENABLE_WALLET for (auto& pair : coinJoinClientManagers) { pair.second->UpdatedBlockTip(pindexNew); } #endif // ENABLE_WALLET - llmq::quorumInstantSendManager->UpdatedBlockTip(pindexNew); - llmq::chainLocksHandler->UpdatedBlockTip(); + isman->UpdatedBlockTip(pindexNew); + clhandler->UpdatedBlockTip(); - llmq::quorumManager->UpdatedBlockTip(pindexNew, fInitialDownload); - llmq::quorumDKGSessionManager->UpdatedBlockTip(pindexNew, fInitialDownload); + qman->UpdatedBlockTip(pindexNew, fInitialDownload); + qdkgsman->UpdatedBlockTip(pindexNew, fInitialDownload); - if (!fDisableGovernance) governance->UpdatedBlockTip(pindexNew, connman); + if (!fDisableGovernance) govman->UpdatedBlockTip(pindexNew, connman); } void CDSNotificationInterface::TransactionAddedToMempool(const CTransactionRef& ptx, int64_t nAcceptTime) { - llmq::quorumInstantSendManager->TransactionAddedToMempool(ptx); - llmq::chainLocksHandler->TransactionAddedToMempool(ptx, nAcceptTime); + isman->TransactionAddedToMempool(ptx); + clhandler->TransactionAddedToMempool(ptx, nAcceptTime); CCoinJoin::TransactionAddedToMempool(ptx); } void CDSNotificationInterface::TransactionRemovedFromMempool(const CTransactionRef& ptx, MemPoolRemovalReason reason) { - llmq::quorumInstantSendManager->TransactionRemovedFromMempool(ptx); + isman->TransactionRemovedFromMempool(ptx); } void CDSNotificationInterface::BlockConnected(const std::shared_ptr& pblock, const CBlockIndex* pindex, const std::vector& vtxConflicted) @@ -98,26 +105,26 @@ void CDSNotificationInterface::BlockConnected(const std::shared_ptrBlockConnected(pblock, pindex, vtxConflicted); - llmq::chainLocksHandler->BlockConnected(pblock, pindex, vtxConflicted); + isman->BlockConnected(pblock, pindex, vtxConflicted); + clhandler->BlockConnected(pblock, pindex, vtxConflicted); CCoinJoin::BlockConnected(pblock, pindex, vtxConflicted); } void CDSNotificationInterface::BlockDisconnected(const std::shared_ptr& pblock, const CBlockIndex* pindexDisconnected) { - llmq::quorumInstantSendManager->BlockDisconnected(pblock, pindexDisconnected); - llmq::chainLocksHandler->BlockDisconnected(pblock, pindexDisconnected); + isman->BlockDisconnected(pblock, pindexDisconnected); + clhandler->BlockDisconnected(pblock, pindexDisconnected); CCoinJoin::BlockDisconnected(pblock, pindexDisconnected); } void CDSNotificationInterface::NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff, CConnman& connman) { CMNAuth::NotifyMasternodeListChanged(undo, oldMNList, diff, connman); - governance->UpdateCachesAndClean(); + govman->UpdateCachesAndClean(); } void CDSNotificationInterface::NotifyChainLock(const CBlockIndex* pindex, const std::shared_ptr& clsig) { - llmq::quorumInstantSendManager->NotifyChainLock(pindex); - CCoinJoin::NotifyChainLock(pindex); + isman->NotifyChainLock(pindex); + CCoinJoin::NotifyChainLock(pindex, *clhandler); } diff --git a/src/dsnotificationinterface.h b/src/dsnotificationinterface.h index 913bf827bb..3ba6209f41 100644 --- a/src/dsnotificationinterface.h +++ b/src/dsnotificationinterface.h @@ -7,10 +7,26 @@ #include +class CConnman; +class CDeterministicMNManager; +class CGovernanceManager; +class CMasternodeSync; + +namespace llmq { +class CChainLocksHandler; +class CDKGSessionManager; +class CInstantSendManager; +class CQuorumManager; +} // namespace llmq + class CDSNotificationInterface : public CValidationInterface { public: - explicit CDSNotificationInterface(CConnman& connmanIn): connman(connmanIn) {} + explicit CDSNotificationInterface(CConnman& _connman, + std::unique_ptr& _mnsync, std::unique_ptr& _dmnman, + std::unique_ptr& _govman, std::unique_ptr& _clhandler, + std::unique_ptr& _isman, std::unique_ptr& _qman, + std::unique_ptr& _qdkgsman); virtual ~CDSNotificationInterface() = default; // a small helper to initialize current block height in sub-modules on startup @@ -31,6 +47,15 @@ protected: private: CConnman& connman; + + std::unique_ptr& mnsync; + std::unique_ptr& dmnman; + std::unique_ptr& govman; + + std::unique_ptr& clhandler; + std::unique_ptr& isman; + std::unique_ptr& qman; + std::unique_ptr& qdkgsman; }; #endif // BITCOIN_DSNOTIFICATIONINTERFACE_H diff --git a/src/evo/cbtx.cpp b/src/evo/cbtx.cpp index 35ecf2c43e..b32d71554a 100644 --- a/src/evo/cbtx.cpp +++ b/src/evo/cbtx.cpp @@ -49,7 +49,7 @@ bool CheckCbTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidatio } // This can only be done after the block has been fully processed, as otherwise we won't have the finished MN list -bool CheckCbTxMerkleRoots(const CBlock& block, const CBlockIndex* pindex, CValidationState& state, const CCoinsViewCache& view) +bool CheckCbTxMerkleRoots(const CBlock& block, const CBlockIndex* pindex, const llmq::CQuorumBlockProcessor& quorum_block_processor, CValidationState& state, const CCoinsViewCache& view) { if (block.vtx[0]->nType != TRANSACTION_COINBASE) { return true; @@ -84,7 +84,7 @@ bool CheckCbTxMerkleRoots(const CBlock& block, const CBlockIndex* pindex, CValid LogPrint(BCLog::BENCHMARK, " - CalcCbTxMerkleRootMNList: %.2fms [%.2fs]\n", 0.001 * (nTime3 - nTime2), nTimeMerkleMNL * 0.000001); if (cbTx.nVersion >= 2) { - if (!CalcCbTxMerkleRootQuorums(block, pindex->pprev, calculatedMerkleRoot, state)) { + if (!CalcCbTxMerkleRootQuorums(block, pindex->pprev, quorum_block_processor, calculatedMerkleRoot, state)) { // pass the state returned by the function above return false; } @@ -167,9 +167,9 @@ using QcIndexedHashMap = std::map +auto CachedGetQcHashesQcIndexedHashes(const CBlockIndex* pindexPrev, const llmq::CQuorumBlockProcessor& quorum_block_processor) -> std::optional> { - auto quorums = llmq::quorumBlockProcessor->GetMinedAndActiveCommitmentsUntilBlock(pindexPrev); + auto quorums = quorum_block_processor.GetMinedAndActiveCommitmentsUntilBlock(pindexPrev); static Mutex cs_cache; static std::map> quorums_cached GUARDED_BY(cs_cache); @@ -194,7 +194,7 @@ auto CachedGetQcHashesQcIndexedHashes(const CBlockIndex* pindexPrev) -> auto& map_indexed_hashes = qcIndexedHashes_cached[llmqType]; for (const auto& blockIndex : vecBlockIndexes) { uint256 dummyHash; - llmq::CFinalCommitmentPtr pqc = llmq::quorumBlockProcessor->GetMinedCommitment(llmqType, blockIndex->GetBlockHash(), dummyHash); + llmq::CFinalCommitmentPtr pqc = quorum_block_processor.GetMinedCommitment(llmqType, blockIndex->GetBlockHash(), dummyHash); if (pqc == nullptr) { // this should never happen return std::nullopt; @@ -220,7 +220,7 @@ auto CalcHashCountFromQCHashes(const QcHashMap& qcHashes) return hash_count; } -bool CalcCbTxMerkleRootQuorums(const CBlock& block, const CBlockIndex* pindexPrev, uint256& merkleRootRet, CValidationState& state) +bool CalcCbTxMerkleRootQuorums(const CBlock& block, const CBlockIndex* pindexPrev, const llmq::CQuorumBlockProcessor& quorum_block_processor, uint256& merkleRootRet, CValidationState& state) { static int64_t nTimeMined = 0; static int64_t nTimeLoop = 0; @@ -228,7 +228,7 @@ bool CalcCbTxMerkleRootQuorums(const CBlock& block, const CBlockIndex* pindexPre int64_t nTime1 = GetTimeMicros(); - auto retVal = CachedGetQcHashesQcIndexedHashes(pindexPrev); + auto retVal = CachedGetQcHashesQcIndexedHashes(pindexPrev, quorum_block_processor); if (retVal == std::nullopt) { return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "commitment-not-found"); } diff --git a/src/evo/cbtx.h b/src/evo/cbtx.h index 947c4565c5..90f42bf321 100644 --- a/src/evo/cbtx.h +++ b/src/evo/cbtx.h @@ -13,6 +13,10 @@ class CBlockIndex; class CCoinsViewCache; class CValidationState; +namespace llmq { +class CQuorumBlockProcessor; +}// namespace llmq + // coinbase transaction class CCbTx { @@ -51,8 +55,8 @@ public: bool CheckCbTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state); -bool CheckCbTxMerkleRoots(const CBlock& block, const CBlockIndex* pindex, CValidationState& state, const CCoinsViewCache& view); +bool CheckCbTxMerkleRoots(const CBlock& block, const CBlockIndex* pindex, const llmq::CQuorumBlockProcessor& quorum_block_processor, CValidationState& state, const CCoinsViewCache& view); bool CalcCbTxMerkleRootMNList(const CBlock& block, const CBlockIndex* pindexPrev, uint256& merkleRootRet, CValidationState& state, const CCoinsViewCache& view); -bool CalcCbTxMerkleRootQuorums(const CBlock& block, const CBlockIndex* pindexPrev, uint256& merkleRootRet, CValidationState& state); +bool CalcCbTxMerkleRootQuorums(const CBlock& block, const CBlockIndex* pindexPrev, const llmq::CQuorumBlockProcessor& quorum_block_processor, uint256& merkleRootRet, CValidationState& state); #endif // BITCOIN_EVO_CBTX_H diff --git a/src/evo/mnhftx.cpp b/src/evo/mnhftx.cpp index 2052d1c9da..68817c8eb4 100644 --- a/src/evo/mnhftx.cpp +++ b/src/evo/mnhftx.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -27,8 +28,8 @@ bool MNHFTx::Verify(const CBlockIndex* pQuorumIndex) const int signOffset{llmq::GetLLMQParams(llmqType).dkgInterval}; const uint256 requestId = ::SerializeHash(std::make_pair(CBLSIG_REQUESTID_PREFIX, pQuorumIndex->nHeight)); - return llmq::CSigningManager::VerifyRecoveredSig(llmqType, pQuorumIndex->nHeight, requestId, pQuorumIndex->GetBlockHash(), sig, 0) || - llmq::CSigningManager::VerifyRecoveredSig(llmqType, pQuorumIndex->nHeight, requestId, pQuorumIndex->GetBlockHash(), sig, signOffset); + return llmq::CSigningManager::VerifyRecoveredSig(llmqType, *llmq::quorumManager, pQuorumIndex->nHeight, requestId, pQuorumIndex->GetBlockHash(), sig, 0) || + llmq::CSigningManager::VerifyRecoveredSig(llmqType, *llmq::quorumManager, pQuorumIndex->nHeight, requestId, pQuorumIndex->GetBlockHash(), sig, signOffset); } bool CheckMNHFTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(cs_main) diff --git a/src/evo/simplifiedmns.cpp b/src/evo/simplifiedmns.cpp index 7db5e88f38..136987849b 100644 --- a/src/evo/simplifiedmns.cpp +++ b/src/evo/simplifiedmns.cpp @@ -130,10 +130,11 @@ CSimplifiedMNListDiff::CSimplifiedMNListDiff() = default; CSimplifiedMNListDiff::~CSimplifiedMNListDiff() = default; -bool CSimplifiedMNListDiff::BuildQuorumsDiff(const CBlockIndex* baseBlockIndex, const CBlockIndex* blockIndex) +bool CSimplifiedMNListDiff::BuildQuorumsDiff(const CBlockIndex* baseBlockIndex, const CBlockIndex* blockIndex, + const llmq::CQuorumBlockProcessor& quorum_block_processor) { - auto baseQuorums = llmq::quorumBlockProcessor->GetMinedAndActiveCommitmentsUntilBlock(baseBlockIndex); - auto quorums = llmq::quorumBlockProcessor->GetMinedAndActiveCommitmentsUntilBlock(blockIndex); + auto baseQuorums = quorum_block_processor.GetMinedAndActiveCommitmentsUntilBlock(baseBlockIndex); + auto quorums = quorum_block_processor.GetMinedAndActiveCommitmentsUntilBlock(blockIndex); std::set> baseQuorumHashes; std::set> quorumHashes; @@ -156,7 +157,7 @@ bool CSimplifiedMNListDiff::BuildQuorumsDiff(const CBlockIndex* baseBlockIndex, for (auto& p : quorumHashes) { if (!baseQuorumHashes.count(p)) { uint256 minedBlockHash; - llmq::CFinalCommitmentPtr qc = llmq::quorumBlockProcessor->GetMinedCommitment(p.first, p.second, minedBlockHash); + llmq::CFinalCommitmentPtr qc = quorum_block_processor.GetMinedCommitment(p.first, p.second, minedBlockHash); if (qc == nullptr) { return false; } @@ -219,7 +220,8 @@ void CSimplifiedMNListDiff::ToJson(UniValue& obj, bool extended) const } } -bool BuildSimplifiedMNListDiff(const uint256& baseBlockHash, const uint256& blockHash, CSimplifiedMNListDiff& mnListDiffRet, std::string& errorRet, bool extended) +bool BuildSimplifiedMNListDiff(const uint256& baseBlockHash, const uint256& blockHash, CSimplifiedMNListDiff& mnListDiffRet, + const llmq::CQuorumBlockProcessor& quorum_block_processor, std::string& errorRet, bool extended) { AssertLockHeld(cs_main); mnListDiffRet = CSimplifiedMNListDiff(); @@ -259,7 +261,7 @@ bool BuildSimplifiedMNListDiff(const uint256& baseBlockHash, const uint256& bloc // null block hash was provided to get the diff from the genesis block. mnListDiffRet.baseBlockHash = baseBlockHash; - if (!mnListDiffRet.BuildQuorumsDiff(baseBlockIndex, blockIndex)) { + if (!mnListDiffRet.BuildQuorumsDiff(baseBlockIndex, blockIndex, quorum_block_processor)) { errorRet = strprintf("failed to build quorums diff"); return false; } diff --git a/src/evo/simplifiedmns.h b/src/evo/simplifiedmns.h index 1e714ca326..4384ed20a7 100644 --- a/src/evo/simplifiedmns.h +++ b/src/evo/simplifiedmns.h @@ -15,9 +15,9 @@ class CBlockIndex; class CDeterministicMNList; class CDeterministicMN; -namespace llmq -{ - class CFinalCommitment; +namespace llmq { +class CFinalCommitment; +class CQuorumBlockProcessor; } // namespace llmq class CSimplifiedMNListEntry @@ -117,11 +117,13 @@ public: CSimplifiedMNListDiff(); ~CSimplifiedMNListDiff(); - bool BuildQuorumsDiff(const CBlockIndex* baseBlockIndex, const CBlockIndex* blockIndex); + bool BuildQuorumsDiff(const CBlockIndex* baseBlockIndex, const CBlockIndex* blockIndex, + const llmq::CQuorumBlockProcessor& quorum_block_processor); void ToJson(UniValue& obj, bool extended = false) const; }; -bool BuildSimplifiedMNListDiff(const uint256& baseBlockHash, const uint256& blockHash, CSimplifiedMNListDiff& mnListDiffRet, std::string& errorRet, bool extended = false); +bool BuildSimplifiedMNListDiff(const uint256& baseBlockHash, const uint256& blockHash, CSimplifiedMNListDiff& mnListDiffRet, + const llmq::CQuorumBlockProcessor& quorum_block_processor, std::string& errorRet, bool extended = false); #endif // BITCOIN_EVO_SIMPLIFIEDMNS_H diff --git a/src/evo/specialtxman.cpp b/src/evo/specialtxman.cpp index b291db80f8..6f61303472 100644 --- a/src/evo/specialtxman.cpp +++ b/src/evo/specialtxman.cpp @@ -98,7 +98,8 @@ bool UndoSpecialTx(const CTransaction& tx, const CBlockIndex* pindex) return false; } -bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CValidationState& state, const CCoinsViewCache& view, bool fJustCheck, bool fCheckCbTxMerleRoots) +bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, llmq::CQuorumBlockProcessor& quorum_block_processor, + CValidationState& state, const CCoinsViewCache& view, bool fJustCheck, bool fCheckCbTxMerleRoots) { AssertLockHeld(cs_main); @@ -125,7 +126,7 @@ bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CV nTimeLoop += nTime2 - nTime1; LogPrint(BCLog::BENCHMARK, " - Loop: %.2fms [%.2fs]\n", 0.001 * (nTime2 - nTime1), nTimeLoop * 0.000001); - if (!llmq::quorumBlockProcessor->ProcessBlock(block, pindex, state, fJustCheck, fCheckCbTxMerleRoots)) { + if (!quorum_block_processor.ProcessBlock(block, pindex, state, fJustCheck, fCheckCbTxMerleRoots)) { // pass the state returned by the function above return false; } @@ -143,7 +144,7 @@ bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CV nTimeDMN += nTime4 - nTime3; LogPrint(BCLog::BENCHMARK, " - deterministicMNManager: %.2fms [%.2fs]\n", 0.001 * (nTime4 - nTime3), nTimeDMN * 0.000001); - if (fCheckCbTxMerleRoots && !CheckCbTxMerkleRoots(block, pindex, state, view)) { + if (fCheckCbTxMerleRoots && !CheckCbTxMerkleRoots(block, pindex, quorum_block_processor, state, view)) { // pass the state returned by the function above return false; } @@ -159,7 +160,7 @@ bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CV return true; } -bool UndoSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex) +bool UndoSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, llmq::CQuorumBlockProcessor& quorum_block_processor) { AssertLockHeld(cs_main); @@ -175,7 +176,7 @@ bool UndoSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex) return false; } - if (!llmq::quorumBlockProcessor->UndoBlock(block, pindex)) { + if (!quorum_block_processor.UndoBlock(block, pindex)) { return false; } } catch (const std::exception& e) { diff --git a/src/evo/specialtxman.h b/src/evo/specialtxman.h index bb3d16f486..2980f6dad1 100644 --- a/src/evo/specialtxman.h +++ b/src/evo/specialtxman.h @@ -17,7 +17,8 @@ class CValidationState; extern CCriticalSection cs_main; bool CheckSpecialTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state, const CCoinsViewCache& view, bool check_sigs) EXCLUSIVE_LOCKS_REQUIRED(cs_main); -bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CValidationState& state, const CCoinsViewCache& view, bool fJustCheck, bool fCheckCbTxMerleRoots) EXCLUSIVE_LOCKS_REQUIRED(cs_main); -bool UndoSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main); +bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, llmq::CQuorumBlockProcessor& quorum_block_processor, + CValidationState& state, const CCoinsViewCache& view, bool fJustCheck, bool fCheckCbTxMerleRoots) EXCLUSIVE_LOCKS_REQUIRED(cs_main); +bool UndoSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, llmq::CQuorumBlockProcessor& quorum_block_processor) EXCLUSIVE_LOCKS_REQUIRED(cs_main); #endif // BITCOIN_EVO_SPECIALTXMAN_H diff --git a/src/init.cpp b/src/init.cpp index 2cc019eee9..654a919745 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -82,12 +82,15 @@ #include #include +#include #include +#include #include #include #include #include #include +#include #include @@ -1777,7 +1780,11 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA node.chainman = &g_chainman; ChainstateManager& chainman = *Assert(node.chainman); - node.peer_logic.reset(new PeerLogicValidation(node.connman.get(), node.banman.get(), *node.scheduler, chainman, *node.mempool, args.GetBoolArg("-enablebip61", DEFAULT_ENABLE_BIP61))); + node.peer_logic.reset(new PeerLogicValidation( + node.connman.get(), node.banman.get(), *node.scheduler, chainman, *node.mempool, llmq::quorumBlockProcessor, + llmq::quorumDKGSessionManager, llmq::quorumManager, llmq::quorumSigSharesManager, llmq::quorumSigningManager, + llmq::chainLocksHandler, llmq::quorumInstantSendManager, args.GetBoolArg("-enablebip61", DEFAULT_ENABLE_BIP61)) + ); RegisterValidationInterface(node.peer_logic.get()); ::governance = std::make_unique(); @@ -1933,7 +1940,10 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA } #endif - pdsNotificationInterface = new CDSNotificationInterface(*node.connman); + pdsNotificationInterface = new CDSNotificationInterface( + *node.connman, ::masternodeSync, ::deterministicMNManager, ::governance, llmq::chainLocksHandler, + llmq::quorumInstantSendManager, llmq::quorumManager, llmq::quorumDKGSessionManager + ); RegisterValidationInterface(pdsNotificationInterface); if (fMasternodeMode) { @@ -2012,7 +2022,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA try { LOCK(cs_main); - chainman.InitializeChainstate(); + chainman.InitializeChainstate(llmq::chainLocksHandler, llmq::quorumInstantSendManager, llmq::quorumBlockProcessor); chainman.m_total_coinstip_cache = nCoinCacheUsage; chainman.m_total_coinsdb_cache = nCoinDBCache; diff --git a/src/llmq/chainlocks.cpp b/src/llmq/chainlocks.cpp index 45e6dcffce..0672ca7227 100644 --- a/src/llmq/chainlocks.cpp +++ b/src/llmq/chainlocks.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -23,10 +24,8 @@ namespace llmq { std::unique_ptr chainLocksHandler; -CChainLocksHandler::CChainLocksHandler(CTxMemPool& _mempool, CConnman& _connman, CSporkManager& sporkManager) : - scheduler(std::make_unique()), - mempool(_mempool), connman(_connman), - spork_manager(sporkManager), +CChainLocksHandler::CChainLocksHandler(CTxMemPool& _mempool, CConnman& _connman, CSporkManager& sporkManager, CSigningManager& _sigman, CSigSharesManager& _shareman) : + scheduler(std::make_unique()), mempool(_mempool), connman(_connman), spork_manager(sporkManager), sigman(_sigman), shareman(_shareman), scheduler_thread(std::make_unique([&] { TraceThread("cl-schdlr", [&] { scheduler->serviceQueue(); }); })) { } @@ -39,7 +38,7 @@ CChainLocksHandler::~CChainLocksHandler() void CChainLocksHandler::Start() { - quorumSigningManager->RegisterRecoveredSigsListener(this); + sigman.RegisterRecoveredSigsListener(this); scheduler->scheduleEvery([&]() { CheckActiveState(); EnforceBestChainLock(); @@ -51,7 +50,7 @@ void CChainLocksHandler::Start() void CChainLocksHandler::Stop() { scheduler->stop(); - quorumSigningManager->UnregisterRecoveredSigsListener(this); + sigman.UnregisterRecoveredSigsListener(this); } bool CChainLocksHandler::AlreadyHave(const CInv& inv) const @@ -117,7 +116,7 @@ void CChainLocksHandler::ProcessNewChainLock(const NodeId from, const llmq::CCha } const uint256 requestId = ::SerializeHash(std::make_pair(CLSIG_REQUESTID_PREFIX, clsig.getHeight())); - if (!llmq::CSigningManager::VerifyRecoveredSig(Params().GetConsensus().llmqTypeChainLocks, clsig.getHeight(), requestId, clsig.getBlockHash(), clsig.getSig())) { + if (!llmq::CSigningManager::VerifyRecoveredSig(Params().GetConsensus().llmqTypeChainLocks, *llmq::quorumManager, clsig.getHeight(), requestId, clsig.getBlockHash(), clsig.getSig())) { LogPrint(BCLog::CHAINLOCKS, "CChainLocksHandler::%s -- invalid CLSIG (%s), peer=%d\n", __func__, clsig.ToString(), from); if (from != -1) { LOCK(cs_main); @@ -335,7 +334,7 @@ void CChainLocksHandler::TrySignChainTip() lastSignedMsgHash = msgHash; } - quorumSigningManager->AsyncSignIfMember(Params().GetConsensus().llmqTypeChainLocks, requestId, msgHash); + sigman.AsyncSignIfMember(Params().GetConsensus().llmqTypeChainLocks, shareman, requestId, msgHash); } void CChainLocksHandler::TransactionAddedToMempool(const CTransactionRef& tx, int64_t nAcceptTime) @@ -436,19 +435,19 @@ CChainLocksHandler::BlockTxs::mapped_type CChainLocksHandler::GetBlockTxs(const return ret; } -bool CChainLocksHandler::IsTxSafeForMining(const uint256& txid) const +bool CChainLocksHandler::IsTxSafeForMining(const CInstantSendManager& isman, const uint256& txid) const { - if (!quorumInstantSendManager->RejectConflictingBlocks()) { + if (!isman.RejectConflictingBlocks()) { return true; } if (!isEnabled || !isEnforced) { return true; } - if (!quorumInstantSendManager->IsInstantSendEnabled()) { + if (!isman.IsInstantSendEnabled()) { return true; } - if (quorumInstantSendManager->IsLocked(txid)) { + if (isman.IsLocked(txid)) { return true; } diff --git a/src/llmq/chainlocks.h b/src/llmq/chainlocks.h index 61fb981ace..910657d4a0 100644 --- a/src/llmq/chainlocks.h +++ b/src/llmq/chainlocks.h @@ -27,6 +27,9 @@ class CSporkManager; namespace llmq { +class CInstantSendManager; +class CSigningManager; +class CSigSharesManager; class CChainLocksHandler : public CRecoveredSigsListener { @@ -40,6 +43,8 @@ private: CConnman& connman; CTxMemPool& mempool; CSporkManager& spork_manager; + CSigningManager& sigman; + CSigSharesManager& shareman; std::unique_ptr scheduler; std::unique_ptr scheduler_thread; mutable CCriticalSection cs; @@ -72,7 +77,7 @@ private: int64_t lastCleanupTime GUARDED_BY(cs) {0}; public: - explicit CChainLocksHandler(CTxMemPool& _mempool, CConnman& _connman, CSporkManager& sporkManager); + explicit CChainLocksHandler(CTxMemPool& _mempool, CConnman& _connman, CSporkManager& sporkManager, CSigningManager& _sigman, CSigSharesManager& _shareman); ~CChainLocksHandler(); void Start(); @@ -97,7 +102,7 @@ public: bool HasChainLock(int nHeight, const uint256& blockHash) const; bool HasConflictingChainLock(int nHeight, const uint256& blockHash) const; - bool IsTxSafeForMining(const uint256& txid) const; + bool IsTxSafeForMining(const CInstantSendManager& isman, const uint256& txid) const; private: // these require locks to be held already diff --git a/src/llmq/dkgsession.cpp b/src/llmq/dkgsession.cpp index 8495e5fe0f..a82e5d09e3 100644 --- a/src/llmq/dkgsession.cpp +++ b/src/llmq/dkgsession.cpp @@ -101,7 +101,7 @@ bool CDKGSession::Init(const CBlockIndex* _pQuorumBaseBlockIndex, const std::vec } if (!myProTxHash.IsNull()) { - quorumDKGDebugManager->InitLocalSessionStatus(params, quorumIndex, m_quorum_base_block_index->GetBlockHash(), m_quorum_base_block_index->nHeight); + dkgDebugManager.InitLocalSessionStatus(params, quorumIndex, m_quorum_base_block_index->GetBlockHash(), m_quorum_base_block_index->nHeight); relayMembers = utils::GetQuorumRelayMembers(params, m_quorum_base_block_index, myProTxHash, true); std::stringstream ss; for (const auto& r : relayMembers) { @@ -183,7 +183,7 @@ void CDKGSession::SendContributions(CDKGPendingMessages& pendingMessages) logger.Flush(); - quorumDKGDebugManager->UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) { + dkgDebugManager.UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) { status.sentContributions = true; return true; }); @@ -266,7 +266,7 @@ void CDKGSession::ReceiveMessage(const CDKGContribution& qc, bool& retBan) CInv inv(MSG_QUORUM_CONTRIB, hash); RelayInvToParticipants(inv); - quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) { + dkgDebugManager.UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) { status.receivedContribution = true; return true; }); @@ -306,7 +306,7 @@ void CDKGSession::ReceiveMessage(const CDKGContribution& qc, bool& retBan) if (complain) { member->weComplain = true; - quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) { + dkgDebugManager.UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) { status.weComplain = true; return true; }); @@ -374,7 +374,7 @@ void CDKGSession::VerifyPendingContributions() const auto& m = members[memberIndexes[i]]; logger.Batch("invalid contribution from %s. will complain later", m->dmn->proTxHash.ToString()); m->weComplain = true; - quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, quorumIndex, m->idx, [&](CDKGDebugMemberStatus& status) { + dkgDebugManager.UpdateLocalMemberStatus(params.type, quorumIndex, m->idx, [&](CDKGDebugMemberStatus& status) { status.weComplain = true; return true; }); @@ -499,7 +499,7 @@ void CDKGSession::SendComplaint(CDKGPendingMessages& pendingMessages) logger.Flush(); - quorumDKGDebugManager->UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) { + dkgDebugManager.UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) { status.sentComplaint = true; return true; }); @@ -572,7 +572,7 @@ void CDKGSession::ReceiveMessage(const CDKGComplaint& qc, bool& retBan) CInv inv(MSG_QUORUM_COMPLAINT, hash); RelayInvToParticipants(inv); - quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) { + dkgDebugManager.UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) { status.receivedComplaint = true; return true; }); @@ -598,7 +598,7 @@ void CDKGSession::ReceiveMessage(const CDKGComplaint& qc, bool& retBan) if (qc.complainForMembers[i]) { m->complaintsFromOthers.emplace(qc.proTxHash); m->someoneComplain = true; - quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, quorumIndex, m->idx, [&](CDKGDebugMemberStatus& status) { + dkgDebugManager.UpdateLocalMemberStatus(params.type, quorumIndex, m->idx, [&](CDKGDebugMemberStatus& status) { return status.complaintsFromMembers.emplace(member->idx).second; }); if (AreWeMember() && i == myIdx) { @@ -693,7 +693,7 @@ void CDKGSession::SendJustification(CDKGPendingMessages& pendingMessages, const logger.Flush(); - quorumDKGDebugManager->UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) { + dkgDebugManager.UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) { status.sentJustification = true; return true; }); @@ -783,7 +783,7 @@ void CDKGSession::ReceiveMessage(const CDKGJustification& qj, bool& retBan) CInv inv(MSG_QUORUM_JUSTIFICATION, hash); RelayInvToParticipants(inv); - quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) { + dkgDebugManager.UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) { status.receivedJustification = true; return true; }); @@ -1005,7 +1005,7 @@ void CDKGSession::SendCommitment(CDKGPendingMessages& pendingMessages) logger.Flush(); - quorumDKGDebugManager->UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) { + dkgDebugManager.UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) { status.sentPrematureCommitment = true; return true; }); @@ -1142,7 +1142,7 @@ void CDKGSession::ReceiveMessage(const CDKGPrematureCommitment& qc, bool& retBan CInv inv(MSG_QUORUM_PREMATURE_COMMITMENT, hash); RelayInvToParticipants(inv); - quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) { + dkgDebugManager.UpdateLocalMemberStatus(params.type, quorumIndex, member->idx, [&](CDKGDebugMemberStatus& status) { status.receivedPrematureCommitment = true; return true; }); @@ -1280,7 +1280,7 @@ void CDKGSession::MarkBadMember(size_t idx) if (member->bad) { return; } - quorumDKGDebugManager->UpdateLocalMemberStatus(params.type, quorumIndex, idx, [&](CDKGDebugMemberStatus& status) { + dkgDebugManager.UpdateLocalMemberStatus(params.type, quorumIndex, idx, [&](CDKGDebugMemberStatus& status) { status.bad = true; return true; }); diff --git a/src/llmq/dkgsession.h b/src/llmq/dkgsession.h index f95e2d0e6c..9c1e2a6a83 100644 --- a/src/llmq/dkgsession.h +++ b/src/llmq/dkgsession.h @@ -23,6 +23,7 @@ namespace llmq { class CFinalCommitment; +class CDKGDebugManager; class CDKGSession; class CDKGSessionManager; class CDKGPendingMessages; @@ -260,6 +261,7 @@ private: CBLSWorker& blsWorker; CBLSWorkerCache cache; CDKGSessionManager& dkgManager; + CDKGDebugManager& dkgDebugManager; const CBlockIndex* m_quorum_base_block_index{nullptr}; int quorumIndex{0}; @@ -300,8 +302,8 @@ private: std::set validCommitments GUARDED_BY(invCs); public: - CDKGSession(const Consensus::LLMQParams& _params, CBLSWorker& _blsWorker, CDKGSessionManager& _dkgManager, CConnman& _connman) : - params(_params), blsWorker(_blsWorker), cache(_blsWorker), dkgManager(_dkgManager), connman(_connman) {} + CDKGSession(const Consensus::LLMQParams& _params, CBLSWorker& _blsWorker, CDKGSessionManager& _dkgManager, CDKGDebugManager& _dkgDebugManager, CConnman& _connman) : + params(_params), blsWorker(_blsWorker), cache(_blsWorker), dkgManager(_dkgManager), dkgDebugManager(_dkgDebugManager), connman(_connman) {} bool Init(const CBlockIndex* pQuorumBaseBlockIndex, const std::vector& mns, const uint256& _myProTxHash, int _quorumIndex); diff --git a/src/llmq/dkgsessionhandler.cpp b/src/llmq/dkgsessionhandler.cpp index 6d56aa2268..a81fb8635a 100644 --- a/src/llmq/dkgsessionhandler.cpp +++ b/src/llmq/dkgsessionhandler.cpp @@ -141,7 +141,7 @@ void CDKGSessionHandler::StopThread() bool CDKGSessionHandler::InitNewQuorum(const CBlockIndex* pQuorumBaseBlockIndex) { - curSession = std::make_unique(params, blsWorker, dkgManager, connman); + curSession = std::make_unique(params, blsWorker, dkgManager, dkgDebugManager, connman); if (!deterministicMNManager->IsDIP3Enforced(pQuorumBaseBlockIndex->nHeight)) { return false; @@ -198,9 +198,9 @@ void CDKGSessionHandler::WaitForNextPhase(std::optional curPhase, LogPrint(BCLog::LLMQ_DKG, "CDKGSessionManager::%s -- %s qi[%d] - done, curPhase=%d, nextPhase=%d\n", __func__, params.name, quorumIndex, curPhase.has_value() ? int(*curPhase) : -1, int(nextPhase)); if (nextPhase == QuorumPhase::Initialized) { - quorumDKGDebugManager->ResetLocalSessionStatus(params.type, quorumIndex); + dkgDebugManager.ResetLocalSessionStatus(params.type, quorumIndex); } else { - quorumDKGDebugManager->UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) { + dkgDebugManager.UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) { bool changed = status.phase != (uint8_t) nextPhase; status.phase = (uint8_t) nextPhase; return changed; @@ -481,7 +481,7 @@ void CDKGSessionHandler::HandleDKGRound() throw AbortPhaseException(); } - quorumDKGDebugManager->UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) { + dkgDebugManager.UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) { bool changed = status.phase != (uint8_t) QuorumPhase::Initialized; status.phase = (uint8_t) QuorumPhase::Initialized; return changed; @@ -532,7 +532,7 @@ void CDKGSessionHandler::HandleDKGRound() auto finalCommitments = curSession->FinalizeCommitments(); for (const auto& fqc : finalCommitments) { - quorumBlockProcessor->AddMineableCommitment(fqc); + quorumBlockProcessor.AddMineableCommitment(fqc); } } @@ -543,7 +543,7 @@ void CDKGSessionHandler::PhaseHandlerThread() LogPrint(BCLog::LLMQ_DKG, "CDKGSessionHandler::%s -- %s qi[%d] - starting HandleDKGRound\n", __func__, params.name, quorumIndex); HandleDKGRound(); } catch (AbortPhaseException& e) { - quorumDKGDebugManager->UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) { + dkgDebugManager.UpdateLocalSessionStatus(params.type, quorumIndex, [&](CDKGDebugSessionStatus& status) { status.aborted = true; return true; }); diff --git a/src/llmq/dkgsessionhandler.h b/src/llmq/dkgsessionhandler.h index bad2c82b10..3b7b337049 100644 --- a/src/llmq/dkgsessionhandler.h +++ b/src/llmq/dkgsessionhandler.h @@ -16,9 +16,10 @@ class CBlockIndex; namespace llmq { - +class CDKGDebugManager; class CDKGSession; class CDKGSessionManager; +class CQuorumBlockProcessor; enum class QuorumPhase { Initialized = 1, @@ -113,6 +114,8 @@ private: const int quorumIndex; CBLSWorker& blsWorker; CDKGSessionManager& dkgManager; + CDKGDebugManager& dkgDebugManager; + CQuorumBlockProcessor& quorumBlockProcessor; QuorumPhase phase GUARDED_BY(cs) {QuorumPhase::Idle}; int currentHeight GUARDED_BY(cs) {-1}; @@ -128,13 +131,16 @@ private: CDKGPendingMessages pendingPrematureCommitments; public: - CDKGSessionHandler(const Consensus::LLMQParams& _params, CBLSWorker& _blsWorker, CDKGSessionManager& _dkgManager, CConnman& _connman, int _quorumIndex) : + CDKGSessionHandler(const Consensus::LLMQParams& _params, CBLSWorker& _blsWorker, CDKGSessionManager& _dkgManager, + CDKGDebugManager& _dkgDebugManager, CQuorumBlockProcessor& _quorumBlockProcessor, CConnman& _connman, int _quorumIndex) : params(_params), blsWorker(_blsWorker), dkgManager(_dkgManager), + dkgDebugManager(_dkgDebugManager), + quorumBlockProcessor(_quorumBlockProcessor), connman(_connman), quorumIndex(_quorumIndex), - curSession(std::make_unique(_params, _blsWorker, _dkgManager, _connman)), + 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), pendingJustifications((size_t)_params.size * 2, MSG_QUORUM_JUSTIFICATION), diff --git a/src/llmq/dkgsessionmgr.cpp b/src/llmq/dkgsessionmgr.cpp index 67982cc597..89d373be01 100644 --- a/src/llmq/dkgsessionmgr.cpp +++ b/src/llmq/dkgsessionmgr.cpp @@ -24,9 +24,9 @@ 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, CSporkManager& sporkManager, bool unitTests, bool fWipe) : +CDKGSessionManager::CDKGSessionManager(CConnman& _connman, CBLSWorker& _blsWorker, CDKGDebugManager& _dkgDebugManager, CQuorumBlockProcessor& _quorumBlockProcessor, CSporkManager& sporkManager, bool unitTests, bool fWipe) : db(std::make_unique(unitTests ? "" : (GetDataDir() / "llmq/dkgdb"), 1 << 20, unitTests, fWipe)), - blsWorker(_blsWorker), connman(_connman), spork_manager(sporkManager) + blsWorker(_blsWorker), connman(_connman), dkgDebugManager(_dkgDebugManager), quorumBlockProcessor(_quorumBlockProcessor),spork_manager(sporkManager) { if (!fMasternodeMode && !utils::IsWatchQuorumsEnabled()) { // Regular nodes do not care about any DKG internals, bail out @@ -41,7 +41,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, connman, i)); + std::forward_as_tuple(params, blsWorker, *this, dkgDebugManager, quorumBlockProcessor, connman, i)); } } } @@ -165,7 +165,7 @@ void CDKGSessionManager::UpdatedBlockTip(const CBlockIndex* pindexNew, bool fIni } } -void CDKGSessionManager::ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRecv) +void CDKGSessionManager::ProcessMessage(CNode* pfrom, const CQuorumManager& quorum_manager, const std::string& msg_type, CDataStream& vRecv) { static Mutex cs_indexedQuorumsCache; static std::map> indexedQuorumsCache GUARDED_BY(cs_indexedQuorumsCache); @@ -228,7 +228,7 @@ void CDKGSessionManager::ProcessMessage(CNode* pfrom, const std::string& msg_typ return; } - if (!utils::IsQuorumTypeEnabled(llmqType, pQuorumBaseBlockIndex->pprev)) { + if (!utils::IsQuorumTypeEnabled(llmqType, quorum_manager, pQuorumBaseBlockIndex->pprev)) { LOCK(cs_main); LogPrintf("CDKGSessionManager -- llmqType [%d] quorums aren't active\n", uint8_t(llmqType)); Misbehaving(pfrom->GetId(), 100); diff --git a/src/llmq/dkgsessionmgr.h b/src/llmq/dkgsessionmgr.h index 1607508b76..423c61122e 100644 --- a/src/llmq/dkgsessionmgr.h +++ b/src/llmq/dkgsessionmgr.h @@ -12,10 +12,12 @@ class UniValue; class CBlockIndex; +class CDKGDebugManager; class CSporkManager; namespace llmq { +class CQuorumManager; class CDKGSessionManager { @@ -26,6 +28,8 @@ private: CBLSWorker& blsWorker; CConnman& connman; CSporkManager& spork_manager; + CDKGDebugManager& dkgDebugManager; + CQuorumBlockProcessor& quorumBlockProcessor; //TODO name struct instead of std::pair std::map, CDKGSessionHandler> dkgSessionHandlers; @@ -50,7 +54,7 @@ private: mutable std::map contributionsCache GUARDED_BY(contributionsCacheCs); public: - CDKGSessionManager(CConnman& _connman, CBLSWorker& _blsWorker, CSporkManager& sporkManager, bool unitTests, bool fWipe); + CDKGSessionManager(CConnman& _connman, CBLSWorker& _blsWorker, CDKGDebugManager& _dkgDebugManager, CQuorumBlockProcessor& _quorumBlockProcessor, CSporkManager& sporkManager, bool unitTests, bool fWipe); ~CDKGSessionManager() = default; void StartThreads(); @@ -58,7 +62,7 @@ public: void UpdatedBlockTip(const CBlockIndex *pindexNew, bool fInitialDownload); - void ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRecv); + void ProcessMessage(CNode* pfrom, const CQuorumManager& quorum_manager, const std::string& msg_type, CDataStream& vRecv); bool AlreadyHave(const CInv& inv) const; bool GetContribution(const uint256& hash, CDKGContribution& ret) const; bool GetComplaint(const uint256& hash, CDKGComplaint& ret) const; diff --git a/src/llmq/init.cpp b/src/llmq/init.cpp index 41c30df420..e69d25acc1 100644 --- a/src/llmq/init.cpp +++ b/src/llmq/init.cpp @@ -29,12 +29,12 @@ void InitLLMQSystem(CEvoDB& evoDb, CTxMemPool& mempool, CConnman& connman, CSpor quorumDKGDebugManager = std::make_unique(); quorumBlockProcessor = std::make_unique(evoDb, connman); - quorumDKGSessionManager = std::make_unique(connman, *blsWorker, sporkManager, unitTests, fWipe); - quorumManager = std::make_unique(evoDb, connman, *blsWorker, *quorumDKGSessionManager); - quorumSigSharesManager = std::make_unique(connman); - quorumSigningManager = std::make_unique(connman, unitTests, fWipe); - chainLocksHandler = std::make_unique(mempool, connman, sporkManager); - quorumInstantSendManager = std::make_unique(mempool, connman, sporkManager, unitTests, fWipe); + quorumDKGSessionManager = std::make_unique(connman, *blsWorker, *quorumDKGDebugManager, *quorumBlockProcessor, sporkManager, unitTests, fWipe); + quorumManager = std::make_unique(evoDb, connman, *blsWorker, *quorumBlockProcessor, *quorumDKGSessionManager); + quorumSigningManager = std::make_unique(connman, *quorumManager, unitTests, fWipe); + quorumSigSharesManager = std::make_unique(connman, *quorumManager, *quorumSigningManager); + chainLocksHandler = std::make_unique(mempool, connman, sporkManager, *quorumSigningManager, *quorumSigSharesManager); + quorumInstantSendManager = std::make_unique(mempool, connman, sporkManager, *quorumManager, *quorumSigningManager, *quorumSigSharesManager, *chainLocksHandler, unitTests, fWipe); // NOTE: we use this only to wipe the old db, do NOT use it for anything else // TODO: remove it in some future version @@ -45,8 +45,8 @@ void DestroyLLMQSystem() { quorumInstantSendManager.reset(); chainLocksHandler.reset(); - quorumSigningManager.reset(); quorumSigSharesManager.reset(); + quorumSigningManager.reset(); quorumManager.reset(); quorumDKGSessionManager.reset(); quorumBlockProcessor.reset(); diff --git a/src/llmq/instantsend.cpp b/src/llmq/instantsend.cpp index 4486fc8f96..9648786c59 100644 --- a/src/llmq/instantsend.cpp +++ b/src/llmq/instantsend.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -461,12 +462,12 @@ void CInstantSendManager::Start() workThread = std::thread(&TraceThread >, "isman", std::function(std::bind(&CInstantSendManager::WorkThreadMain, this))); - quorumSigningManager->RegisterRecoveredSigsListener(this); + sigman.RegisterRecoveredSigsListener(this); } void CInstantSendManager::Stop() { - quorumSigningManager->UnregisterRecoveredSigsListener(this); + sigman.UnregisterRecoveredSigsListener(this); // make sure to call InterruptWorkerThread() first if (!workInterrupt) { @@ -509,7 +510,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(WITH_LOCK(cs_main, return ::ChainActive().Tip())), params)) { + if (!TrySignInputLocks(tx, fRetroactive, utils::GetInstantSendLLMQType(qman, WITH_LOCK(cs_main, return ::ChainActive().Tip())), params)) { return; } @@ -530,8 +531,8 @@ bool CInstantSendManager::TrySignInputLocks(const CTransaction& tx, bool fRetroa uint256 otherTxHash; // TODO check that we didn't vote for the other IS type also - if (quorumSigningManager->GetVoteForId(params.llmqTypeDIP0024InstantSend, id, otherTxHash) || - quorumSigningManager->GetVoteForId(params.llmqTypeInstantSend, id, otherTxHash)) { + if (sigman.GetVoteForId(params.llmqTypeDIP0024InstantSend, id, otherTxHash) || + sigman.GetVoteForId(params.llmqTypeInstantSend, id, otherTxHash)) { if (otherTxHash != tx.GetHash()) { LogPrintf("CInstantSendManager::%s -- txid=%s: input %s is conflicting with previous vote for tx %s\n", __func__, tx.GetHash().ToString(), in.prevout.ToStringShort(), otherTxHash.ToString()); @@ -542,10 +543,10 @@ bool CInstantSendManager::TrySignInputLocks(const CTransaction& tx, bool fRetroa // don't even try the actual signing if any input is conflicting if (auto llmqs = {params.llmqTypeDIP0024InstantSend, params.llmqTypeInstantSend}; - ranges::any_of(llmqs, [&id, &tx](const auto& llmqType){ - return quorumSigningManager->IsConflicting(llmqType, id, tx.GetHash());}) + ranges::any_of(llmqs, [&id, &tx, this](const auto& llmqType){ + return sigman.IsConflicting(llmqType, id, tx.GetHash());}) ) { - LogPrintf("CInstantSendManager::%s -- txid=%s: quorumSigningManager->IsConflicting returned true. id=%s\n", __func__, + LogPrintf("CInstantSendManager::%s -- txid=%s: sigman.IsConflicting returned true. id=%s\n", __func__, tx.GetHash().ToString(), id.ToString()); return false; } @@ -565,7 +566,7 @@ bool CInstantSendManager::TrySignInputLocks(const CTransaction& tx, bool fRetroa WITH_LOCK(cs_inputReqests, inputRequestIds.emplace(id)); LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s: trying to vote on input %s with id %s. fRetroactive=%d\n", __func__, tx.GetHash().ToString(), in.prevout.ToStringShort(), id.ToString(), fRetroactive); - if (quorumSigningManager->AsyncSignIfMember(llmqType, id, tx.GetHash(), {}, fRetroactive)) { + if (sigman.AsyncSignIfMember(llmqType, shareman, id, tx.GetHash(), {}, fRetroactive)) { LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s: voted on input %s with id %s\n", __func__, tx.GetHash().ToString(), in.prevout.ToStringShort(), id.ToString()); } @@ -622,7 +623,7 @@ bool CInstantSendManager::CheckCanLock(const COutPoint& outpoint, bool printDebu nTxAge = ::ChainActive().Height() - pindexMined->nHeight + 1; } - if (nTxAge < nInstantSendConfirmationsRequired && !llmq::chainLocksHandler->HasChainLock(pindexMined->nHeight, pindexMined->GetBlockHash())) { + if (nTxAge < nInstantSendConfirmationsRequired && !clhandler.HasChainLock(pindexMined->nHeight, pindexMined->GetBlockHash())) { if (printDebug) { LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s: outpoint %s too new and not ChainLocked. nTxAge=%d, nInstantSendConfirmationsRequired=%d\n", __func__, txHash.ToString(), outpoint.ToStringShort(), nTxAge, nInstantSendConfirmationsRequired); @@ -683,11 +684,11 @@ void CInstantSendManager::HandleNewInputLockRecoveredSig(const CRecoveredSig& re void CInstantSendManager::TrySignInstantSendLock(const CTransaction& tx) { - const auto llmqType = utils::GetInstantSendLLMQType(WITH_LOCK(cs_main, return ::ChainActive().Tip())); + const auto llmqType = utils::GetInstantSendLLMQType(qman, WITH_LOCK(cs_main, return ::ChainActive().Tip())); for (const auto& in : tx.vin) { auto id = ::SerializeHash(std::make_pair(INPUTLOCK_REQUESTID_PREFIX, in.prevout)); - if (!quorumSigningManager->HasRecoveredSig(llmqType, id, tx.GetHash())) { + if (!sigman.HasRecoveredSig(llmqType, id, tx.GetHash())) { return; } } @@ -713,7 +714,7 @@ void CInstantSendManager::TrySignInstantSendLock(const CTransaction& tx) auto id = islock.GetRequestId(); - if (quorumSigningManager->HasRecoveredSigForId(llmqType, id)) { + if (sigman.HasRecoveredSigForId(llmqType, id)) { return; } @@ -726,7 +727,7 @@ void CInstantSendManager::TrySignInstantSendLock(const CTransaction& tx) txToCreatingInstantSendLocks.emplace(tx.GetHash(), &e.first->second); } - quorumSigningManager->AsyncSignIfMember(llmqType, id, tx.GetHash()); + sigman.AsyncSignIfMember(llmqType, shareman, id, tx.GetHash()); } void CInstantSendManager::HandleNewInstantSendLockRecoveredSig(const llmq::CRecoveredSig& recoveredSig) @@ -852,7 +853,7 @@ bool CInstantSendManager::PreVerifyInstantSendLock(const llmq::CInstantSendLock& bool CInstantSendManager::ProcessPendingInstantSendLocks() { const CBlockIndex* pBlockIndexTip = WITH_LOCK(cs_main, return ::ChainActive().Tip()); - if (pBlockIndexTip && utils::GetInstantSendLLMQType(pBlockIndexTip) == Params().GetConsensus().llmqTypeDIP0024InstantSend) { + if (pBlockIndexTip && utils::GetInstantSendLLMQType(qman, pBlockIndexTip) == Params().GetConsensus().llmqTypeDIP0024InstantSend) { // Don't short circuit. Try to process deterministic and not deterministic islocks return ProcessPendingInstantSendLocks(true) & ProcessPendingInstantSendLocks(false); } else { @@ -950,7 +951,7 @@ std::unordered_set CInstantSendManager::ProcessPend auto id = islock->GetRequestId(); // no need to verify an ISLOCK if we already have verified the recovered sig that belongs to it - if (quorumSigningManager->HasRecoveredSig(llmqType, id, islock->txid)) { + if (sigman.HasRecoveredSig(llmqType, id, islock->txid)) { alreadyVerified++; continue; } @@ -971,7 +972,7 @@ std::unordered_set CInstantSendManager::ProcessPend } } - auto quorum = llmq::CSigningManager::SelectQuorumForSigning(llmqType, id, nSignHeight, signOffset); + auto quorum = llmq::CSigningManager::SelectQuorumForSigning(llmqType, qman, id, nSignHeight, signOffset); if (!quorum) { // should not happen, but if one fails to select, all others will also fail to select return {}; @@ -983,7 +984,7 @@ std::unordered_set CInstantSendManager::ProcessPend // We can reconstruct the CRecoveredSig objects from the islock and pass it to the signing manager, which // avoids unnecessary double-verification of the signature. We however only do this when verification here // turns out to be good (which is checked further down) - if (!quorumSigningManager->HasRecoveredSigForId(llmqType, id)) { + if (!sigman.HasRecoveredSigForId(llmqType, id)) { recSigs.try_emplace(hash, CRecoveredSig(llmqType, quorum->qc->quorumHash, id, islock->txid, islock->sig)); } } @@ -1024,10 +1025,10 @@ std::unordered_set CInstantSendManager::ProcessPend auto it = recSigs.find(hash); if (it != recSigs.end()) { auto recSig = std::make_shared(std::move(it->second)); - if (!quorumSigningManager->HasRecoveredSigForId(llmqType, recSig->getId())) { + if (!sigman.HasRecoveredSigForId(llmqType, recSig->getId())) { LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s, islock=%s: passing reconstructed recSig to signing mgr, peer=%d\n", __func__, islock->txid.ToString(), hash.ToString(), nodeId); - quorumSigningManager->PushReconstructedRecoveredSig(recSig); + sigman.PushReconstructedRecoveredSig(recSig); } } } @@ -1057,7 +1058,7 @@ void CInstantSendManager::ProcessInstantSendLock(NodeId from, const uint256& has // 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 - if (pindexMined != nullptr && llmq::chainLocksHandler->HasChainLock(pindexMined->nHeight, pindexMined->GetBlockHash())) { + if (pindexMined != nullptr && clhandler.HasChainLock(pindexMined->nHeight, pindexMined->GetBlockHash())) { LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txlock=%s, islock=%s: dropping islock as it already got a ChainLock in block %s, peer=%d\n", __func__, islock->txid.ToString(), hash.ToString(), hashBlock.ToString(), from); return; @@ -1197,7 +1198,7 @@ void CInstantSendManager::BlockConnected(const std::shared_ptr& pb continue; } - if (!IsLocked(tx->GetHash()) && !chainLocksHandler->HasChainLock(pindex->nHeight, pindex->GetBlockHash())) { + if (!IsLocked(tx->GetHash()) && !clhandler.HasChainLock(pindex->nHeight, pindex->GetBlockHash())) { ProcessTx(*tx, true, Params().GetConsensus()); // TX is not locked, so make sure it is tracked AddNonLockedTx(tx, pindex); @@ -1306,7 +1307,7 @@ void CInstantSendManager::TruncateRecoveredSigsForInputs(const llmq::CInstantSen for (const auto& in : islock.inputs) { auto inputRequestId = ::SerializeHash(std::make_pair(INPUTLOCK_REQUESTID_PREFIX, in)); WITH_LOCK(cs_inputReqests, inputRequestIds.erase(inputRequestId)); - quorumSigningManager->TruncateRecoveredSig(utils::GetInstantSendLLMQType(islock.IsDeterministic()), inputRequestId); + sigman.TruncateRecoveredSig(utils::GetInstantSendLLMQType(islock.IsDeterministic()), inputRequestId); } } @@ -1357,7 +1358,7 @@ void CInstantSendManager::HandleFullyConfirmedBlock(const CBlockIndex* pindex) // And we don't need the recovered sig for the ISLOCK anymore, as the block in which it got mined is considered // fully confirmed now - quorumSigningManager->TruncateRecoveredSig(utils::GetInstantSendLLMQType(islock->IsDeterministic()), islock->GetRequestId()); + sigman.TruncateRecoveredSig(utils::GetInstantSendLLMQType(islock->IsDeterministic()), islock->GetRequestId()); } db.RemoveArchivedInstantSendLocks(pindex->nHeight - 100); @@ -1446,7 +1447,7 @@ void CInstantSendManager::ResolveBlockConflicts(const uint256& islockHash, const bool hasChainLockedConflict = false; for (const auto& p : conflicts) { const auto* pindex = p.first; - if (chainLocksHandler->HasChainLock(pindex->nHeight, pindex->GetBlockHash())) { + if (clhandler.HasChainLock(pindex->nHeight, pindex->GetBlockHash())) { hasChainLockedConflict = true; break; } diff --git a/src/llmq/instantsend.h b/src/llmq/instantsend.h index 9e1efe56d0..f6d040a786 100644 --- a/src/llmq/instantsend.h +++ b/src/llmq/instantsend.h @@ -22,6 +22,10 @@ class CSporkManager; namespace llmq { +class CChainLocksHandler; +class CQuorumManager; +class CSigningManager; +class CSigSharesManager; struct CInstantSendLock { @@ -199,6 +203,10 @@ private: CConnman& connman; CTxMemPool& mempool; CSporkManager& spork_manager; + CQuorumManager& qman; + CSigningManager& sigman; + CSigSharesManager& shareman; + CChainLocksHandler& clhandler; std::atomic fUpgradedDB{false}; @@ -246,7 +254,13 @@ private: std::unordered_set pendingRetryTxs GUARDED_BY(cs_pendingRetry); public: - explicit CInstantSendManager(CTxMemPool& _mempool, CConnman& _connman, CSporkManager& sporkManager, bool unitTests, bool fWipe) : db(unitTests, fWipe), mempool(_mempool), connman(_connman), spork_manager(sporkManager) { workInterrupt.reset(); } + explicit CInstantSendManager(CTxMemPool& _mempool, CConnman& _connman, CSporkManager& sporkManager, CQuorumManager& _qman, + CSigningManager& _sigman, CSigSharesManager& _shareman, CChainLocksHandler& _clhandler, bool unitTests, bool fWipe) : + db(unitTests, fWipe), mempool(_mempool), connman(_connman), spork_manager(sporkManager), qman(_qman), sigman(_sigman), shareman(_shareman), + clhandler(_clhandler) + { + workInterrupt.reset(); + } ~CInstantSendManager() = default; void Start(); diff --git a/src/llmq/quorums.cpp b/src/llmq/quorums.cpp index c45ecf433f..70ff54cd8f 100644 --- a/src/llmq/quorums.cpp +++ b/src/llmq/quorums.cpp @@ -186,10 +186,12 @@ bool CQuorum::ReadContributions(CEvoDB& evoDb) return true; } -CQuorumManager::CQuorumManager(CEvoDB& _evoDb, CConnman& _connman, CBLSWorker& _blsWorker, CDKGSessionManager& _dkgManager) : +CQuorumManager::CQuorumManager(CEvoDB& _evoDb, CConnman& _connman, CBLSWorker& _blsWorker, CQuorumBlockProcessor& _quorumBlockProcessor, + CDKGSessionManager& _dkgManager) : connman(_connman), evoDb(_evoDb), blsWorker(_blsWorker), + quorumBlockProcessor(_quorumBlockProcessor), dkgManager(_dkgManager) { utils::InitQuorumsCache(mapQuorumsCache); @@ -362,7 +364,7 @@ CQuorumPtr CQuorumManager::BuildQuorumFromCommitment(const Consensus::LLMQType l const uint256& quorumHash{pQuorumBaseBlockIndex->GetBlockHash()}; uint256 minedBlockHash; - CFinalCommitmentPtr qc = quorumBlockProcessor->GetMinedCommitment(llmqType, quorumHash, minedBlockHash); + CFinalCommitmentPtr qc = quorumBlockProcessor.GetMinedCommitment(llmqType, quorumHash, minedBlockHash); if (qc == nullptr) { LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- No mined commitment for llmqType[%d] nHeight[%d] quorumHash[%s]\n", __func__, uint8_t(llmqType), pQuorumBaseBlockIndex->nHeight, pQuorumBaseBlockIndex->GetBlockHash().ToString()); return nullptr; @@ -429,9 +431,9 @@ bool CQuorumManager::BuildQuorumContributions(const CFinalCommitmentPtr& fqc, co return true; } -bool CQuorumManager::HasQuorum(Consensus::LLMQType llmqType, const uint256& quorumHash) +bool CQuorumManager::HasQuorum(Consensus::LLMQType llmqType, const CQuorumBlockProcessor& quorum_block_processor, const uint256& quorumHash) { - return quorumBlockProcessor->HasMinedCommitment(llmqType, quorumHash); + return quorum_block_processor.HasMinedCommitment(llmqType, quorumHash); } bool CQuorumManager::RequestQuorumData(CNode* pFrom, Consensus::LLMQType llmqType, const CBlockIndex* pQuorumBaseBlockIndex, uint16_t nDataMask, const uint256& proTxHash) const @@ -487,7 +489,7 @@ std::vector CQuorumManager::ScanQuorums(Consensus::LLMQType llmqTyp std::vector CQuorumManager::ScanQuorums(Consensus::LLMQType llmqType, const CBlockIndex* pindexStart, size_t nCountRequested) const { - if (pindexStart == nullptr || nCountRequested == 0 || !utils::IsQuorumTypeEnabled(llmqType, pindexStart)) { + if (pindexStart == nullptr || nCountRequested == 0 || !utils::IsQuorumTypeEnabled(llmqType, *this, pindexStart)) { return {}; } @@ -522,8 +524,8 @@ std::vector CQuorumManager::ScanQuorums(Consensus::LLMQType llmqTyp // Get the block indexes of the mined commitments to build the required quorums from std::vector pQuorumBaseBlockIndexes{ GetLLMQParams(llmqType).useRotation ? - quorumBlockProcessor->GetMinedCommitmentsIndexedUntilBlock(llmqType, pIndexScanCommitments, nScanCommitments) : - quorumBlockProcessor->GetMinedCommitmentsUntilBlock(llmqType, pIndexScanCommitments, nScanCommitments) + quorumBlockProcessor.GetMinedCommitmentsIndexedUntilBlock(llmqType, pIndexScanCommitments, nScanCommitments) : + quorumBlockProcessor.GetMinedCommitmentsUntilBlock(llmqType, pIndexScanCommitments, nScanCommitments) }; vecResultQuorums.reserve(vecResultQuorums.size() + pQuorumBaseBlockIndexes.size()); @@ -565,7 +567,7 @@ CQuorumCPtr CQuorumManager::GetQuorum(Consensus::LLMQType llmqType, const CBlock // we must check this before we look into the cache. Reorgs might have happened which would mean we might have // cached quorums which are not in the active chain anymore - if (!HasQuorum(llmqType, quorumHash)) { + if (!HasQuorum(llmqType, quorumBlockProcessor, quorumHash)) { return nullptr; } @@ -685,7 +687,7 @@ void CQuorumManager::ProcessMessage(CNode* pFrom, const std::string& msg_type, C } std::vector> vecEncrypted; - if (!quorumDKGSessionManager->GetEncryptedContributions(request.GetLLMQType(), pQuorumBaseBlockIndex, pQuorum->qc->validMembers, request.GetProTxHash(), vecEncrypted)) { + if (!dkgManager.GetEncryptedContributions(request.GetLLMQType(), pQuorumBaseBlockIndex, pQuorum->qc->validMembers, request.GetProTxHash(), vecEncrypted)) { sendQDATA(CQuorumDataRequest::Errors::ENCRYPTED_CONTRIBUTIONS_MISSING); return; } @@ -913,7 +915,7 @@ void CQuorumManager::StartQuorumDataRecoveryThread(const CQuorumCPtr pQuorum, co return; } - if (quorumManager->RequestQuorumData(pNode, pQuorum->qc->llmqType, pQuorum->m_quorum_base_block_index, nDataMask, proTxHash)) { + if (RequestQuorumData(pNode, pQuorum->qc->llmqType, pQuorum->m_quorum_base_block_index, nDataMask, proTxHash)) { nTimeLastSuccess = GetAdjustedTime(); printLog("Requested"); } else { diff --git a/src/llmq/quorums.h b/src/llmq/quorums.h index 65093d68c2..697caa533f 100644 --- a/src/llmq/quorums.h +++ b/src/llmq/quorums.h @@ -27,8 +27,8 @@ using CDeterministicMNCPtr = std::shared_ptr; namespace llmq { - class CDKGSessionManager; +class CQuorumBlockProcessor; // If true, we will connect to all new quorums and watch their communication static constexpr bool DEFAULT_WATCH_QUORUMS{false}; @@ -209,6 +209,7 @@ private: CConnman& connman; CBLSWorker& blsWorker; CDKGSessionManager& dkgManager; + CQuorumBlockProcessor& quorumBlockProcessor; mutable CCriticalSection cs_map_quorums; mutable std::map> mapQuorumsCache GUARDED_BY(cs_map_quorums); @@ -219,7 +220,8 @@ private: mutable CThreadInterrupt quorumThreadInterrupt; public: - CQuorumManager(CEvoDB& _evoDb, CConnman& _connman, CBLSWorker& _blsWorker, CDKGSessionManager& _dkgManager); + CQuorumManager(CEvoDB& _evoDb, CConnman& _connman, CBLSWorker& _blsWorker, CQuorumBlockProcessor& _quorumBlockProcessor, + CDKGSessionManager& _dkgManager); ~CQuorumManager() { Stop(); }; void Start(); @@ -231,7 +233,7 @@ public: void ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRecv); - static bool HasQuorum(Consensus::LLMQType llmqType, const uint256& quorumHash); + static bool HasQuorum(Consensus::LLMQType llmqType, const CQuorumBlockProcessor& quorum_block_processor, const uint256& quorumHash); bool RequestQuorumData(CNode* pFrom, Consensus::LLMQType llmqType, const CBlockIndex* pQuorumBaseBlockIndex, uint16_t nDataMask, const uint256& proTxHash = uint256()) const; diff --git a/src/llmq/signing.cpp b/src/llmq/signing.cpp index f9ced9f04c..02d5cad0d0 100644 --- a/src/llmq/signing.cpp +++ b/src/llmq/signing.cpp @@ -528,8 +528,8 @@ void CRecoveredSigsDb::CleanupOldVotes(int64_t maxAge) ////////////////// -CSigningManager::CSigningManager(CConnman& _connman, bool fMemory, bool fWipe) : - db(fMemory, fWipe), connman(_connman) +CSigningManager::CSigningManager(CConnman& _connman, const CQuorumManager& _qman, bool fMemory, bool fWipe) : + db(fMemory, fWipe), connman(_connman), qman(_qman) { } @@ -553,7 +553,7 @@ bool CSigningManager::GetRecoveredSigForGetData(const uint256& hash, CRecoveredS if (!db.GetRecoveredSigByHash(hash, ret)) { return false; } - if (!utils::IsQuorumActive(ret.getLlmqType(), ret.getQuorumHash())) { + if (!utils::IsQuorumActive(ret.getLlmqType(), qman, ret.getQuorumHash())) { // we don't want to propagate sigs from inactive quorums return false; } @@ -577,7 +577,7 @@ void CSigningManager::ProcessMessageRecoveredSig(CNode* pfrom, const std::shared } bool ban = false; - if (!PreVerifyRecoveredSig(*recoveredSig, ban)) { + if (!PreVerifyRecoveredSig(qman, *recoveredSig, ban)) { if (ban) { LOCK(cs_main); Misbehaving(pfrom->GetId(), 100); @@ -604,7 +604,7 @@ void CSigningManager::ProcessMessageRecoveredSig(CNode* pfrom, const std::shared pendingRecoveredSigs[pfrom->GetId()].emplace_back(recoveredSig); } -bool CSigningManager::PreVerifyRecoveredSig(const CRecoveredSig& recoveredSig, bool& retBan) +bool CSigningManager::PreVerifyRecoveredSig(const CQuorumManager& quorum_manager, const CRecoveredSig& recoveredSig, bool& retBan) { retBan = false; @@ -614,14 +614,14 @@ bool CSigningManager::PreVerifyRecoveredSig(const CRecoveredSig& recoveredSig, b return false; } - CQuorumCPtr quorum = quorumManager->GetQuorum(llmqType, recoveredSig.getQuorumHash()); + CQuorumCPtr quorum = quorum_manager.GetQuorum(llmqType, recoveredSig.getQuorumHash()); if (!quorum) { LogPrint(BCLog::LLMQ, "CSigningManager::%s -- quorum %s not found\n", __func__, recoveredSig.getQuorumHash().ToString()); return false; } - if (!utils::IsQuorumActive(llmqType, quorum->qc->quorumHash)) { + if (!utils::IsQuorumActive(llmqType, quorum_manager, quorum->qc->quorumHash)) { return false; } @@ -672,14 +672,14 @@ void CSigningManager::CollectPendingRecoveredSigsToVerify( auto llmqType = recSig->getLlmqType(); auto quorumKey = std::make_pair(recSig->getLlmqType(), recSig->getQuorumHash()); if (!retQuorums.count(quorumKey)) { - CQuorumCPtr quorum = quorumManager->GetQuorum(llmqType, recSig->getQuorumHash()); + CQuorumCPtr quorum = qman.GetQuorum(llmqType, recSig->getQuorumHash()); if (!quorum) { LogPrint(BCLog::LLMQ, "CSigningManager::%s -- quorum %s not found, node=%d\n", __func__, recSig->getQuorumHash().ToString(), nodeId); it = v.erase(it); continue; } - if (!utils::IsQuorumActive(llmqType, quorum->qc->quorumHash)) { + if (!utils::IsQuorumActive(llmqType, qman, quorum->qc->quorumHash)) { LogPrint(BCLog::LLMQ, "CSigningManager::%s -- quorum %s not active anymore, node=%d\n", __func__, recSig->getQuorumHash().ToString(), nodeId); it = v.erase(it); @@ -872,7 +872,7 @@ void CSigningManager::UnregisterRecoveredSigsListener(CRecoveredSigsListener* l) recoveredSigsListeners.erase(itRem, recoveredSigsListeners.end()); } -bool CSigningManager::AsyncSignIfMember(Consensus::LLMQType llmqType, const uint256& id, const uint256& msgHash, const uint256& quorumHash, bool allowReSign) +bool CSigningManager::AsyncSignIfMember(Consensus::LLMQType llmqType, CSigSharesManager& shareman, const uint256& id, const uint256& msgHash, const uint256& quorumHash, bool allowReSign) { if (!fMasternodeMode || WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash.IsNull())) { return false; @@ -885,9 +885,9 @@ bool CSigningManager::AsyncSignIfMember(Consensus::LLMQType llmqType, const uint // This gives a slight risk of not getting enough shares to recover a signature // But at least it shouldn't be possible to get conflicting recovered signatures // TODO fix this by re-signing when the next block arrives, but only when that block results in a change of the quorum list and no recovered signature has been created in the mean time - quorum = SelectQuorumForSigning(llmqType, id); + quorum = SelectQuorumForSigning(llmqType, qman, id); } else { - quorum = quorumManager->GetQuorum(llmqType, quorumHash); + quorum = qman.GetQuorum(llmqType, quorumHash); } if (!quorum) { @@ -931,9 +931,9 @@ bool CSigningManager::AsyncSignIfMember(Consensus::LLMQType llmqType, const uint if (allowReSign) { // make us re-announce all known shares (other nodes might have run into a timeout) - quorumSigSharesManager->ForceReAnnouncement(quorum, llmqType, id, msgHash); + shareman.ForceReAnnouncement(quorum, llmqType, id, msgHash); } - quorumSigSharesManager->AsyncSign(quorum, id, msgHash); + shareman.AsyncSign(quorum, id, msgHash); return true; } @@ -982,7 +982,7 @@ bool CSigningManager::GetVoteForId(Consensus::LLMQType llmqType, const uint256& return db.GetVoteForId(llmqType, id, msgHashRet); } -CQuorumCPtr CSigningManager::SelectQuorumForSigning(Consensus::LLMQType llmqType, const uint256& selectionHash, int signHeight, int signOffset) +CQuorumCPtr CSigningManager::SelectQuorumForSigning(Consensus::LLMQType llmqType, const CQuorumManager& quorum_manager, const uint256& selectionHash, int signHeight, int signOffset) { size_t poolSize = GetLLMQParams(llmqType).signingActiveQuorumCount; @@ -1000,7 +1000,7 @@ CQuorumCPtr CSigningManager::SelectQuorumForSigning(Consensus::LLMQType llmqType } if (utils::IsQuorumRotationEnabled(llmqType, pindexStart)) { - auto quorums = quorumManager->ScanQuorums(llmqType, pindexStart, poolSize); + auto quorums = quorum_manager.ScanQuorums(llmqType, pindexStart, poolSize); if (quorums.empty()) { return nullptr; } @@ -1024,7 +1024,7 @@ CQuorumCPtr CSigningManager::SelectQuorumForSigning(Consensus::LLMQType llmqType } return *itQuorum; } else { - auto quorums = quorumManager->ScanQuorums(llmqType, pindexStart, poolSize); + auto quorums = quorum_manager.ScanQuorums(llmqType, pindexStart, poolSize); if (quorums.empty()) { return nullptr; } @@ -1043,9 +1043,9 @@ CQuorumCPtr CSigningManager::SelectQuorumForSigning(Consensus::LLMQType llmqType } } -bool CSigningManager::VerifyRecoveredSig(Consensus::LLMQType llmqType, int signedAtHeight, const uint256& id, const uint256& msgHash, const CBLSSignature& sig, const int signOffset) +bool CSigningManager::VerifyRecoveredSig(Consensus::LLMQType llmqType, const CQuorumManager& quorum_manager, int signedAtHeight, const uint256& id, const uint256& msgHash, const CBLSSignature& sig, const int signOffset) { - auto quorum = SelectQuorumForSigning(llmqType, id, signedAtHeight, signOffset); + auto quorum = SelectQuorumForSigning(llmqType, quorum_manager, id, signedAtHeight, signOffset); if (!quorum) { return false; } diff --git a/src/llmq/signing.h b/src/llmq/signing.h index cc97d81081..5ca07f7a1c 100644 --- a/src/llmq/signing.h +++ b/src/llmq/signing.h @@ -24,14 +24,14 @@ class CNode; namespace llmq { - class CQuorum; using CQuorumCPtr = std::shared_ptr; +class CQuorumManager; +class CSigSharesManager; // Keep recovered signatures for a week. This is a "-maxrecsigsage" option default. static constexpr int64_t DEFAULT_MAX_RECOVERED_SIGS_AGE{60 * 60 * 24 * 7}; - class CSigBase { protected: @@ -166,6 +166,7 @@ private: CConnman& connman; CRecoveredSigsDb db; + const CQuorumManager& qman; // Incoming and not verified yet std::unordered_map>> pendingRecoveredSigs GUARDED_BY(cs); @@ -178,7 +179,7 @@ private: std::vector recoveredSigsListeners GUARDED_BY(cs); public: - CSigningManager(CConnman& _connman, bool fMemory, bool fWipe); + CSigningManager(CConnman& _connman, const CQuorumManager& _qman, bool fMemory, bool fWipe); bool AlreadyHave(const CInv& inv) const; bool GetRecoveredSigForGetData(const uint256& hash, CRecoveredSig& ret) const; @@ -197,7 +198,7 @@ public: private: void ProcessMessageRecoveredSig(CNode* pfrom, const std::shared_ptr& recoveredSig); - static bool PreVerifyRecoveredSig(const CRecoveredSig& recoveredSig, bool& retBan); + static bool PreVerifyRecoveredSig(const CQuorumManager& quorum_manager, const CRecoveredSig& recoveredSig, bool& retBan); void CollectPendingRecoveredSigsToVerify(size_t maxUniqueSessions, std::unordered_map>>& retSigShares, @@ -212,7 +213,7 @@ public: void RegisterRecoveredSigsListener(CRecoveredSigsListener* l); void UnregisterRecoveredSigsListener(CRecoveredSigsListener* l); - bool AsyncSignIfMember(Consensus::LLMQType llmqType, const uint256& id, const uint256& msgHash, const uint256& quorumHash = uint256(), bool allowReSign = false); + bool AsyncSignIfMember(Consensus::LLMQType llmqType, CSigSharesManager& shareman, const uint256& id, const uint256& msgHash, const uint256& quorumHash = uint256(), bool allowReSign = false); bool HasRecoveredSig(Consensus::LLMQType llmqType, const uint256& id, const uint256& msgHash) const; bool HasRecoveredSigForId(Consensus::LLMQType llmqType, const uint256& id) const; bool HasRecoveredSigForSession(const uint256& signHash) const; @@ -222,10 +223,10 @@ public: bool GetVoteForId(Consensus::LLMQType llmqType, const uint256& id, uint256& msgHashRet) const; static std::vector GetActiveQuorumSet(Consensus::LLMQType llmqType, int signHeight); - static CQuorumCPtr SelectQuorumForSigning(Consensus::LLMQType llmqType, const uint256& selectionHash, int signHeight = -1 /*chain tip*/, int signOffset = SIGN_HEIGHT_OFFSET); + static CQuorumCPtr SelectQuorumForSigning(Consensus::LLMQType llmqType, const CQuorumManager& quorum_manager, const uint256& selectionHash, int signHeight = -1 /*chain tip*/, int signOffset = SIGN_HEIGHT_OFFSET); // Verifies a recovered sig that was signed while the chain tip was at signedAtTip - static bool VerifyRecoveredSig(Consensus::LLMQType llmqType, int signedAtHeight, const uint256& id, const uint256& msgHash, const CBLSSignature& sig, int signOffset = SIGN_HEIGHT_OFFSET); + static bool VerifyRecoveredSig(Consensus::LLMQType llmqType, const CQuorumManager& quorum_manager, int signedAtHeight, const uint256& id, const uint256& msgHash, const CBLSSignature& sig, int signOffset = SIGN_HEIGHT_OFFSET); }; extern std::unique_ptr quorumSigningManager; diff --git a/src/llmq/signing_shares.cpp b/src/llmq/signing_shares.cpp index 1a8dbf710e..231e85cb97 100644 --- a/src/llmq/signing_shares.cpp +++ b/src/llmq/signing_shares.cpp @@ -202,12 +202,12 @@ void CSigSharesManager::StopWorkerThread() void CSigSharesManager::RegisterAsRecoveredSigsListener() { - quorumSigningManager->RegisterRecoveredSigsListener(this); + sigman.RegisterRecoveredSigsListener(this); } void CSigSharesManager::UnregisterAsRecoveredSigsListener() { - quorumSigningManager->UnregisterRecoveredSigsListener(this); + sigman.UnregisterRecoveredSigsListener(this); } void CSigSharesManager::InterruptWorkerThread() @@ -308,7 +308,7 @@ bool CSigSharesManager::ProcessMessageSigSesAnn(const CNode* pfrom, const CSigSe LogPrint(BCLog::LLMQ_SIGS, "CSigSharesManager::%s -- ann={%s}, node=%d\n", __func__, ann.ToString(), pfrom->GetId()); - auto quorum = quorumManager->GetQuorum(llmqType, ann.getQuorumHash()); + auto quorum = qman.GetQuorum(llmqType, ann.getQuorumHash()); if (!quorum) { // TODO should we ban here? LogPrint(BCLog::LLMQ_SIGS, "CSigSharesManager::%s -- quorum %s not found, node=%d\n", __func__, @@ -345,7 +345,7 @@ bool CSigSharesManager::ProcessMessageSigSharesInv(const CNode* pfrom, const CSi } // TODO for PoSe, we should consider propagating shares even if we already have a recovered sig - if (quorumSigningManager->HasRecoveredSigForSession(sessionInfo.signHash)) { + if (sigman.HasRecoveredSigForSession(sessionInfo.signHash)) { return true; } @@ -382,7 +382,7 @@ bool CSigSharesManager::ProcessMessageGetSigShares(const CNode* pfrom, const CSi } // TODO for PoSe, we should consider propagating shares even if we already have a recovered sig - if (quorumSigningManager->HasRecoveredSigForSession(sessionInfo.signHash)) { + if (sigman.HasRecoveredSigForSession(sessionInfo.signHash)) { return true; } @@ -407,7 +407,7 @@ bool CSigSharesManager::ProcessMessageBatchedSigShares(const CNode* pfrom, const return true; } - if (bool ban{false}; !PreVerifyBatchedSigShares(sessionInfo, batchedSigShares, ban)) { + if (bool ban{false}; !PreVerifyBatchedSigShares(qman, sessionInfo, batchedSigShares, ban)) { return !ban; } @@ -431,7 +431,7 @@ bool CSigSharesManager::ProcessMessageBatchedSigShares(const CNode* pfrom, const } // TODO for PoSe, we should consider propagating shares even if we already have a recovered sig - if (quorumSigningManager->HasRecoveredSigForId(sigShare.getLlmqType(), sigShare.getId())) { + if (sigman.HasRecoveredSigForId(sigShare.getLlmqType(), sigShare.getId())) { continue; } @@ -456,11 +456,11 @@ bool CSigSharesManager::ProcessMessageBatchedSigShares(const CNode* pfrom, const void CSigSharesManager::ProcessMessageSigShare(NodeId fromId, const CSigShare& sigShare) { - auto quorum = quorumManager->GetQuorum(sigShare.getLlmqType(), sigShare.getQuorumHash()); + auto quorum = qman.GetQuorum(sigShare.getLlmqType(), sigShare.getQuorumHash()); if (!quorum) { return; } - if (!utils::IsQuorumActive(sigShare.getLlmqType(), quorum->qc->quorumHash)) { + if (!utils::IsQuorumActive(sigShare.getLlmqType(), qman, quorum->qc->quorumHash)) { // quorum is too old return; } @@ -493,7 +493,7 @@ void CSigSharesManager::ProcessMessageSigShare(NodeId fromId, const CSigShare& s return; } - if (quorumSigningManager->HasRecoveredSigForId(sigShare.getLlmqType(), sigShare.getId())) { + if (sigman.HasRecoveredSigForId(sigShare.getLlmqType(), sigShare.getId())) { return; } @@ -505,11 +505,11 @@ void CSigSharesManager::ProcessMessageSigShare(NodeId fromId, const CSigShare& s sigShare.GetSignHash().ToString(), sigShare.getId().ToString(), sigShare.getMsgHash().ToString(), sigShare.getQuorumMember(), fromId); } -bool CSigSharesManager::PreVerifyBatchedSigShares(const CSigSharesNodeState::SessionInfo& session, const CBatchedSigShares& batchedSigShares, bool& retBan) +bool CSigSharesManager::PreVerifyBatchedSigShares(const CQuorumManager& quorum_manager, const CSigSharesNodeState::SessionInfo& session, const CBatchedSigShares& batchedSigShares, bool& retBan) { retBan = false; - if (!utils::IsQuorumActive(session.llmqType, session.quorum->qc->quorumHash)) { + if (!utils::IsQuorumActive(session.llmqType, quorum_manager, session.quorum->qc->quorumHash)) { // quorum is too old return false; } @@ -597,7 +597,7 @@ void CSigSharesManager::CollectPendingSigSharesToVerify( continue; } - CQuorumCPtr quorum = quorumManager->GetQuorum(llmqType, sigShare.getQuorumHash()); + CQuorumCPtr quorum = qman.GetQuorum(llmqType, sigShare.getQuorumHash()); assert(quorum != nullptr); retQuorums.try_emplace(k, quorum); } @@ -623,7 +623,7 @@ bool CSigSharesManager::ProcessPendingSigShares(const CConnman& connman) size_t verifyCount = 0; for (const auto& [nodeId, v] : sigSharesByNodes) { for (const auto& sigShare : v) { - if (quorumSigningManager->HasRecoveredSigForId(sigShare.getLlmqType(), sigShare.getId())) { + if (sigman.HasRecoveredSigForId(sigShare.getLlmqType(), sigShare.getId())) { continue; } @@ -701,7 +701,7 @@ void CSigSharesManager::ProcessSigShare(const CSigShare& sigShare, const CConnma quorumNodes = connman.GetMasternodeQuorumNodes(sigShare.getLlmqType(), sigShare.getQuorumHash()); } - if (quorumSigningManager->HasRecoveredSigForId(llmqType, sigShare.getId())) { + if (sigman.HasRecoveredSigForId(llmqType, sigShare.getId())) { return; } @@ -743,7 +743,7 @@ void CSigSharesManager::ProcessSigShare(const CSigShare& sigShare, const CConnma void CSigSharesManager::TryRecoverSig(const CQuorumCPtr& quorum, const uint256& id, const uint256& msgHash) { - if (quorumSigningManager->HasRecoveredSigForId(quorum->params.type, id)) { + if (sigman.HasRecoveredSigForId(quorum->params.type, id)) { return; } @@ -800,7 +800,7 @@ void CSigSharesManager::TryRecoverSig(const CQuorumCPtr& quorum, const uint256& } } - quorumSigningManager->ProcessRecoveredSig(rs); + sigman.ProcessRecoveredSig(rs); } CDeterministicMNCPtr CSigSharesManager::SelectMemberForRecovery(const CQuorumCPtr& quorum, const uint256 &id, size_t attempt) @@ -860,7 +860,7 @@ void CSigSharesManager::CollectSigSharesToRequest(std::unordered_mapHasRecoveredSigForSession(signHash)) { + if (sigman.HasRecoveredSigForSession(signHash)) { continue; } @@ -929,7 +929,7 @@ void CSigSharesManager::CollectSigSharesToSend(std::unordered_mapHasRecoveredSigForSession(signHash)) { + if (sigman.HasRecoveredSigForSession(signHash)) { continue; } @@ -1257,8 +1257,8 @@ void CSigSharesManager::Cleanup() // Find quorums which became inactive for (auto it = quorums.begin(); it != quorums.end(); ) { - if (utils::IsQuorumActive(it->first.first, it->first.second)) { - it->second = quorumManager->GetQuorum(it->first.first, it->first.second); + if (utils::IsQuorumActive(it->first.first, qman, it->first.second)) { + it->second = qman.GetQuorum(it->first.first, it->first.second); ++it; } else { it = quorums.erase(it); @@ -1284,11 +1284,11 @@ void CSigSharesManager::Cleanup() // Remove sessions which were successfully recovered std::unordered_set doneSessions; - sigShares.ForEach([&doneSessions](const SigShareKey&, const CSigShare& sigShare) { + sigShares.ForEach([&doneSessions, this](const SigShareKey&, const CSigShare& sigShare) { if (doneSessions.count(sigShare.GetSignHash()) != 0) { return; } - if (quorumSigningManager->HasRecoveredSigForSession(sigShare.GetSignHash())) { + if (sigman.HasRecoveredSigForSession(sigShare.GetSignHash())) { doneSessions.emplace(sigShare.GetSignHash()); } }); @@ -1441,7 +1441,7 @@ void CSigSharesManager::WorkThreadMain() bool fMoreWork{false}; RemoveBannedNodeStates(); - fMoreWork |= quorumSigningManager->ProcessPendingRecoveredSigs(); + fMoreWork |= sigman.ProcessPendingRecoveredSigs(); fMoreWork |= ProcessPendingSigShares(connman); SignPendingSigShares(); @@ -1451,7 +1451,7 @@ void CSigSharesManager::WorkThreadMain() } Cleanup(); - quorumSigningManager->Cleanup(); + sigman.Cleanup(); // TODO Wakeup when pending signing is needed? if (!fMoreWork && !workInterrupt.sleep_for(std::chrono::milliseconds(100))) { diff --git a/src/llmq/signing_shares.h b/src/llmq/signing_shares.h index 8a67521eb2..fd0d154f2c 100644 --- a/src/llmq/signing_shares.h +++ b/src/llmq/signing_shares.h @@ -28,6 +28,8 @@ using CDeterministicMNCPtr = std::shared_ptr; namespace llmq { +class CSigningManager; + // using SigShareKey = std::pair; @@ -395,11 +397,13 @@ private: FastRandomContext rnd GUARDED_BY(cs); CConnman& connman; + const CQuorumManager& qman; + CSigningManager& sigman; int64_t lastCleanupTime{0}; std::atomic recoveredSigsCounter{0}; public: - explicit CSigSharesManager(CConnman& _connman) : connman(_connman) + explicit CSigSharesManager(CConnman& _connman, CQuorumManager& _qman, CSigningManager& _sigman) : connman(_connman), qman(_qman), sigman(_sigman) { workInterrupt.reset(); }; @@ -431,7 +435,7 @@ private: void ProcessMessageSigShare(NodeId fromId, const CSigShare& sigShare); static bool VerifySigSharesInv(Consensus::LLMQType llmqType, const CSigSharesInv& inv); - static bool PreVerifyBatchedSigShares(const CSigSharesNodeState::SessionInfo& session, const CBatchedSigShares& batchedSigShares, bool& retBan); + static bool PreVerifyBatchedSigShares(const CQuorumManager& quorum_manager, const CSigSharesNodeState::SessionInfo& session, const CBatchedSigShares& batchedSigShares, bool& retBan); void CollectPendingSigSharesToVerify(size_t maxUniqueSessions, std::unordered_map>& retSigShares, diff --git a/src/llmq/snapshot.cpp b/src/llmq/snapshot.cpp index c001308284..9d570d7c6d 100644 --- a/src/llmq/snapshot.cpp +++ b/src/llmq/snapshot.cpp @@ -117,7 +117,8 @@ void CQuorumRotationInfo::ToJson(UniValue& obj) const obj.pushKV("mnListDiffList", mnlistdifflist); } -bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotationInfo& response, std::string& errorRet) +bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotationInfo& response, + const CQuorumManager& qman, const CQuorumBlockProcessor& quorumBlockProcessor, std::string& errorRet) { AssertLockHeld(cs_main); @@ -153,7 +154,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, errorRet)) { + if (!BuildSimplifiedMNListDiff(baseBlockIndexes.back()->GetBlockHash(), tipBlockIndex->GetBlockHash(), response.mnListDiffTip, quorumBlockProcessor, errorRet)) { return false; } @@ -164,7 +165,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat } //Quorum rotation is enabled only for InstantSend atm. - Consensus::LLMQType llmqType = utils::GetInstantSendLLMQType(blockIndex); + Consensus::LLMQType llmqType = utils::GetInstantSendLLMQType(qman, blockIndex); // Since the returned quorums are in reversed order, the most recent one is at index 0 const Consensus::LLMQParams& llmqParams = GetLLMQParams(llmqType); @@ -184,7 +185,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat } //Build MN list Diff always with highest baseblock - if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockIndex), pWorkBlockIndex->GetBlockHash(), response.mnListDiffH, errorRet)) { + if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockIndex), pWorkBlockIndex->GetBlockHash(), response.mnListDiffH, quorumBlockProcessor, errorRet)) { return false; } @@ -230,7 +231,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, errorRet)) { + if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockHMinusCIndex), pWorkBlockHMinusCIndex->GetBlockHash(), response.mnListDiffAtHMinusC, quorumBlockProcessor, errorRet)) { return false; } @@ -242,7 +243,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat response.quorumSnapshotAtHMinusC = std::move(snapshotHMinusC.value()); } - if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockHMinus2CIndex), pWorkBlockHMinus2CIndex->GetBlockHash(), response.mnListDiffAtHMinus2C, errorRet)) { + if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockHMinus2CIndex), pWorkBlockHMinus2CIndex->GetBlockHash(), response.mnListDiffAtHMinus2C, quorumBlockProcessor, errorRet)) { return false; } @@ -254,7 +255,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat response.quorumSnapshotAtHMinus2C = std::move(snapshotHMinus2C.value()); } - if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockHMinus3CIndex), pWorkBlockHMinus3CIndex->GetBlockHash(), response.mnListDiffAtHMinus3C, errorRet)) { + if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockHMinus3CIndex), pWorkBlockHMinus3CIndex->GetBlockHash(), response.mnListDiffAtHMinus3C, quorumBlockProcessor, errorRet)) { return false; } @@ -283,7 +284,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat } CSimplifiedMNListDiff mn4c; - if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockHMinus4CIndex), pWorkBlockHMinus4CIndex->GetBlockHash(), mn4c, errorRet)) { + if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pWorkBlockHMinus4CIndex), pWorkBlockHMinus4CIndex->GetBlockHash(), mn4c, quorumBlockProcessor, errorRet)) { return false; } @@ -296,11 +297,11 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat std::set snapshotHeightsNeeded; - std::vector> qdata = quorumBlockProcessor->GetLastMinedCommitmentsPerQuorumIndexUntilBlock(llmqType, blockIndex, 0); + std::vector> qdata = quorumBlockProcessor.GetLastMinedCommitmentsPerQuorumIndexUntilBlock(llmqType, blockIndex, 0); for (const auto& obj : qdata) { uint256 minedBlockHash; - llmq::CFinalCommitmentPtr qc = llmq::quorumBlockProcessor->GetMinedCommitment(llmqType, obj.second->GetBlockHash(), minedBlockHash); + llmq::CFinalCommitmentPtr qc = quorumBlockProcessor.GetMinedCommitment(llmqType, obj.second->GetBlockHash(), minedBlockHash); if (qc == nullptr) { return false; } @@ -339,7 +340,7 @@ bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotat } CSimplifiedMNListDiff mnhneeded; - if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pNeededWorkBlockIndex), pNeededWorkBlockIndex->GetBlockHash(), mnhneeded, errorRet)) { + if (!BuildSimplifiedMNListDiff(GetLastBaseBlockHash(baseBlockIndexes, pNeededWorkBlockIndex), pNeededWorkBlockIndex->GetBlockHash(), mnhneeded, quorumBlockProcessor, errorRet)) { return false; } diff --git a/src/llmq/snapshot.h b/src/llmq/snapshot.h index 2533978d74..d9d19bebab 100644 --- a/src/llmq/snapshot.h +++ b/src/llmq/snapshot.h @@ -22,6 +22,9 @@ class CDeterministicMN; class CDeterministicMNList; namespace llmq { +class CQuorumBlockProcessor; +class CQuorumManager; + //TODO use enum class (probably) enum SnapshotSkipMode : int { MODE_NO_SKIPPING = 0, @@ -204,7 +207,8 @@ public: void ToJson(UniValue& obj) const; }; -bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotationInfo& quorumRotationInfoRet, std::string& errorRet); +bool BuildQuorumRotationInfo(const CGetQuorumRotationInfo& request, CQuorumRotationInfo& response, + const CQuorumManager& qman, const CQuorumBlockProcessor& quorumBlockProcessor, std::string& errorRet); uint256 GetLastBaseBlockHash(const std::vector& baseBlockIndexes, const CBlockIndex* blockIndex); class CQuorumSnapshotManager diff --git a/src/llmq/utils.cpp b/src/llmq/utils.cpp index 1d7790f2d2..49456c9b8d 100644 --- a/src/llmq/utils.cpp +++ b/src/llmq/utils.cpp @@ -48,7 +48,7 @@ std::vector GetAllQuorumMembers(Consensus::LLMQType llmqTy static std::map, StaticSaltedHasher>> mapQuorumMembers GUARDED_BY(cs_members); static CCriticalSection cs_indexed_members; static std::map, std::vector, StaticSaltedHasher>> mapIndexedQuorumMembers GUARDED_BY(cs_indexed_members); - if (!IsQuorumTypeEnabled(llmqType, pQuorumBaseBlockIndex->pprev)) { + if (!IsQuorumTypeEnabled(llmqType, *llmq::quorumManager, pQuorumBaseBlockIndex->pprev)) { return {}; } std::vector quorumMembers; @@ -577,9 +577,9 @@ bool IsQuorumRotationEnabled(Consensus::LLMQType llmqType, const CBlockIndex* pi return IsDIP0024Active(pindex->GetAncestor(cycleQuorumBaseHeight - 1)); } -Consensus::LLMQType GetInstantSendLLMQType(const CBlockIndex* pindex) +Consensus::LLMQType GetInstantSendLLMQType(const CQuorumManager& qman, const CBlockIndex* pindex) { - if (IsDIP0024Active(pindex) && !quorumManager->ScanQuorums(Params().GetConsensus().llmqTypeDIP0024InstantSend, pindex, 1).empty()) { + if (IsDIP0024Active(pindex) && !qman.ScanQuorums(Params().GetConsensus().llmqTypeDIP0024InstantSend, pindex, 1).empty()) { return Params().GetConsensus().llmqTypeDIP0024InstantSend; } return Params().GetConsensus().llmqTypeInstantSend; @@ -827,22 +827,22 @@ void AddQuorumProbeConnections(const Consensus::LLMQParams& llmqParams, const CB } } -bool IsQuorumActive(Consensus::LLMQType llmqType, const uint256& quorumHash) +bool IsQuorumActive(Consensus::LLMQType llmqType, const CQuorumManager& qman, const uint256& quorumHash) { // sig shares and recovered sigs are only accepted from recent/active quorums // we allow one more active quorum as specified in consensus, as otherwise there is a small window where things could // fail while we are on the brink of a new quorum - auto quorums = quorumManager->ScanQuorums(llmqType, GetLLMQParams(llmqType).keepOldConnections); + auto quorums = qman.ScanQuorums(llmqType, GetLLMQParams(llmqType).keepOldConnections); return ranges::any_of(quorums, [&quorumHash](const auto& q){ return q->qc->quorumHash == quorumHash; }); } -bool IsQuorumTypeEnabled(Consensus::LLMQType llmqType, const CBlockIndex* pindex) +bool IsQuorumTypeEnabled(Consensus::LLMQType llmqType, const CQuorumManager& qman, const CBlockIndex* pindex) { - return IsQuorumTypeEnabledInternal(llmqType, pindex, std::nullopt, std::nullopt); + return IsQuorumTypeEnabledInternal(llmqType, qman, pindex, std::nullopt, std::nullopt); } -bool IsQuorumTypeEnabledInternal(Consensus::LLMQType llmqType, const CBlockIndex* pindex, - std::optional optDIP0024IsActive, std::optional optHaveDIP0024Quorums) +bool IsQuorumTypeEnabledInternal(Consensus::LLMQType llmqType, const CQuorumManager& qman, const CBlockIndex* pindex, + std::optional optDIP0024IsActive, std::optional optHaveDIP0024Quorums) { const Consensus::Params& consensusParams = Params().GetConsensus(); @@ -857,7 +857,7 @@ bool IsQuorumTypeEnabledInternal(Consensus::LLMQType llmqType, const CBlockIndex bool fDIP0024IsActive = optDIP0024IsActive.has_value() ? *optDIP0024IsActive : IsDIP0024Active(pindex); if (fDIP0024IsActive) { bool fHaveDIP0024Quorums = optHaveDIP0024Quorums.has_value() ? *optHaveDIP0024Quorums - : !quorumManager->ScanQuorums( + : !qman.ScanQuorums( consensusParams.llmqTypeDIP0024InstantSend, pindex, 1).empty(); if (fHaveDIP0024Quorums) { return false; @@ -896,7 +896,7 @@ std::vector GetEnabledQuorumTypes(const CBlockIndex* pindex std::vector ret; ret.reserve(Params().GetConsensus().llmqs.size()); for (const auto& params : Params().GetConsensus().llmqs) { - if (IsQuorumTypeEnabled(params.type, pindex)) { + if (IsQuorumTypeEnabled(params.type, *llmq::quorumManager, pindex)) { ret.push_back(params.type); } } @@ -909,7 +909,7 @@ std::vector> GetEnabledQuoru ret.reserve(Params().GetConsensus().llmqs.size()); std::copy_if(Params().GetConsensus().llmqs.begin(), Params().GetConsensus().llmqs.end(), std::back_inserter(ret), - [&pindex](const auto& params){return IsQuorumTypeEnabled(params.type, pindex);}); + [&pindex](const auto& params){return IsQuorumTypeEnabled(params.type, *llmq::quorumManager, pindex);}); return ret; } diff --git a/src/llmq/utils.h b/src/llmq/utils.h index af0f5fa6cf..2c4505ed54 100644 --- a/src/llmq/utils.h +++ b/src/llmq/utils.h @@ -25,6 +25,7 @@ class CBLSPublicKey; namespace llmq { +class CQuorumManager; class CQuorumSnapshot; // Use a separate cache instance instead of versionbitscache to avoid locking cs_main @@ -80,15 +81,15 @@ std::set CalcDeterministicWatchConnections(Consensus::LLMQType llmqType, bool EnsureQuorumConnections(const Consensus::LLMQParams& llmqParams, const CBlockIndex* pQuorumBaseBlockIndex, CConnman& connman, const uint256& myProTxHash); void AddQuorumProbeConnections(const Consensus::LLMQParams& llmqParams, const CBlockIndex* pQuorumBaseBlockIndex, CConnman& connman, const uint256& myProTxHash); -bool IsQuorumActive(Consensus::LLMQType llmqType, const uint256& quorumHash); -bool IsQuorumTypeEnabled(Consensus::LLMQType llmqType, const CBlockIndex* pindex); -bool IsQuorumTypeEnabledInternal(Consensus::LLMQType llmqType, const CBlockIndex* pindex, std::optional optDIP0024IsActive, std::optional optHaveDIP0024Quorums); +bool IsQuorumActive(Consensus::LLMQType llmqType, const CQuorumManager& qman, const uint256& quorumHash); +bool IsQuorumTypeEnabled(Consensus::LLMQType llmqType, const CQuorumManager& qman, const CBlockIndex* pindex); +bool IsQuorumTypeEnabledInternal(Consensus::LLMQType llmqType, const CQuorumManager& qman, const CBlockIndex* pindex, std::optional optDIP0024IsActive, std::optional optHaveDIP0024Quorums); std::vector GetEnabledQuorumTypes(const CBlockIndex* pindex); std::vector> GetEnabledQuorumParams(const CBlockIndex* pindex); bool IsQuorumRotationEnabled(Consensus::LLMQType llmqType, const CBlockIndex* pindex); -Consensus::LLMQType GetInstantSendLLMQType(const CBlockIndex* pindex); +Consensus::LLMQType GetInstantSendLLMQType(const CQuorumManager& qman, const CBlockIndex* pindex); Consensus::LLMQType GetInstantSendLLMQType(bool deterministic); bool IsDIP0024Active(const CBlockIndex* pindex); static bool IsInstantSendLLMQTypeShared(); diff --git a/src/miner.cpp b/src/miner.cpp index 0be734307d..937f11f417 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -56,11 +57,15 @@ BlockAssembler::Options::Options() { } BlockAssembler::BlockAssembler(const CSporkManager& sporkManager, CGovernanceManager& governanceManager, - const CTxMemPool& mempool, const CChainParams& params, const Options& options) + const llmq::CQuorumBlockProcessor& quorumBlockProcessor, llmq::CChainLocksHandler& clhandler, + llmq::CInstantSendManager& isman, const CTxMemPool& mempool, const CChainParams& params, const Options& options) : spork_manager(sporkManager), governance_manager(governanceManager), + quorum_block_processor(quorumBlockProcessor), chainparams(params), - m_mempool(mempool) + m_mempool(mempool), + m_clhandler(clhandler), + m_isman(isman) { blockMinFeeRate = options.blockMinFeeRate; // Limit size to between 1K and MaxBlockSize()-1K for sanity: @@ -85,8 +90,9 @@ static BlockAssembler::Options DefaultOptions() } BlockAssembler::BlockAssembler(const CSporkManager& sporkManager, CGovernanceManager& governanceManager, - const CTxMemPool& mempool, const CChainParams& params) - : BlockAssembler(sporkManager, governanceManager, mempool, params, DefaultOptions()) {} + const llmq::CQuorumBlockProcessor& quorumBlockProcessor, llmq::CChainLocksHandler& clhandler, + llmq::CInstantSendManager& isman, const CTxMemPool& mempool, const CChainParams& params) + : BlockAssembler(sporkManager, governanceManager, quorumBlockProcessor, clhandler, isman, mempool, params, DefaultOptions()) {} void BlockAssembler::resetBlock() { @@ -146,9 +152,9 @@ std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& sc if (fDIP0003Active_context) { for (const Consensus::LLMQParams& params : llmq::utils::GetEnabledQuorumParams(pindexPrev)) { std::vector vqcTx; - if (llmq::quorumBlockProcessor->GetMineableCommitmentsTx(params, - nHeight, - vqcTx)) { + if (quorum_block_processor.GetMineableCommitmentsTx(params, + nHeight, + vqcTx)) { for (const auto& qcTx : vqcTx) { pblock->vtx.emplace_back(qcTx); pblocktemplate->vTxFees.emplace_back(0); @@ -206,7 +212,7 @@ std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& sc throw std::runtime_error(strprintf("%s: CalcCbTxMerkleRootMNList failed: %s", __func__, FormatStateMessage(state))); } if (fDIP0008Active_context) { - if (!CalcCbTxMerkleRootQuorums(*pblock, pindexPrev, cbTx.merkleRootQuorums, state)) { + if (!CalcCbTxMerkleRootQuorums(*pblock, pindexPrev, quorum_block_processor, cbTx.merkleRootQuorums, state)) { throw std::runtime_error(strprintf("%s: CalcCbTxMerkleRootQuorums failed: %s", __func__, FormatStateMessage(state))); } } @@ -230,7 +236,7 @@ std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& sc pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(*pblock->vtx[0]); CValidationState state; - if (!TestBlockValidity(state, chainparams, *pblock, pindexPrev, false, false)) { + if (!TestBlockValidity(state, m_clhandler, chainparams, *pblock, pindexPrev, false, false)) { throw std::runtime_error(strprintf("%s: TestBlockValidity failed: %s", __func__, FormatStateMessage(state))); } int64_t nTime2 = GetTimeMicros(); @@ -270,7 +276,7 @@ bool BlockAssembler::TestPackageTransactions(const CTxMemPool::setEntries& packa for (CTxMemPool::txiter it : package) { if (!IsFinalTx(it->GetTx(), nHeight, nLockTimeCutoff)) return false; - if (!llmq::chainLocksHandler->IsTxSafeForMining(it->GetTx().GetHash())) { + if (!m_clhandler.IsTxSafeForMining(m_isman, it->GetTx().GetHash())) { return false; } } diff --git a/src/miner.h b/src/miner.h index db84be2532..28f8472b14 100644 --- a/src/miner.h +++ b/src/miner.h @@ -25,6 +25,11 @@ class CScript; class CSporkManager; namespace Consensus { struct Params; }; +namespace llmq { +class CChainLocksHandler; +class CInstantSendManager; +class CQuorumBlockProcessor; +} // namespace llmq static const bool DEFAULT_PRINTPRIORITY = false; @@ -152,6 +157,9 @@ private: const CTxMemPool& m_mempool; const CSporkManager& spork_manager; CGovernanceManager& governance_manager; + const llmq::CQuorumBlockProcessor& quorum_block_processor; + llmq::CChainLocksHandler& m_clhandler; + llmq::CInstantSendManager& m_isman; public: struct Options { @@ -161,9 +169,11 @@ public: }; explicit BlockAssembler(const CSporkManager& sporkManager, CGovernanceManager& governanceManager, - const CTxMemPool& mempool, const CChainParams& params); + const llmq::CQuorumBlockProcessor& quorumBlockProcessor, llmq::CChainLocksHandler& clhandler, + llmq::CInstantSendManager& isman, const CTxMemPool& mempool, const CChainParams& params); explicit BlockAssembler(const CSporkManager& sporkManager, CGovernanceManager& governanceManager, - const CTxMemPool& mempool, const CChainParams& params, const Options& options); + const llmq::CQuorumBlockProcessor& quorumBlockProcessor, llmq::CChainLocksHandler& clhandler, + llmq::CInstantSendManager& isman, const CTxMemPool& mempool, const CChainParams& params, const Options& options); /** Construct a new block template with coinbase to scriptPubKeyIn */ std::unique_ptr CreateNewBlock(const CScript& scriptPubKeyIn); diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 6653c9b137..8392c52149 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -1268,8 +1268,15 @@ static bool BlockRequestAllowed(const CBlockIndex* pindex, const Consensus::Para (GetBlockProofEquivalentTime(*pindexBestHeader, *pindex, *pindexBestHeader, consensusParams) < STALE_RELAY_AGE_LIMIT); } -PeerLogicValidation::PeerLogicValidation(CConnman* connmanIn, BanMan* banman, CScheduler &scheduler, ChainstateManager& chainman, CTxMemPool& pool, bool enable_bip61) - : connman(connmanIn), m_banman(banman), m_chainman(chainman), m_mempool(pool), m_stale_tip_check_time(0), m_enable_bip61(enable_bip61) { +PeerLogicValidation::PeerLogicValidation(CConnman* connmanIn, BanMan* banman, CScheduler &scheduler, ChainstateManager& chainman, CTxMemPool& pool, + std::unique_ptr& quorum_block_processor, std::unique_ptr& qdkgsman, + std::unique_ptr& qman, std::unique_ptr& shareman, + std::unique_ptr& sigman, std::unique_ptr& clhandler, + std::unique_ptr& isman, bool enable_bip61) : + connman(connmanIn), m_banman(banman), m_chainman(chainman), m_mempool(pool), m_quorum_block_processor(quorum_block_processor), + m_qdkgsman(qdkgsman), m_qman(qman), m_shareman(shareman), m_sigman(sigman), m_clhandler(clhandler), m_isman(isman), + m_stale_tip_check_time(0), m_enable_bip61(enable_bip61) +{ // Initialize global variables that cannot be constructed at startup. recentRejects.reset(new CRollingBloomFilter(120000, 0.000001)); @@ -1465,7 +1472,10 @@ void PeerLogicValidation::BlockChecked(const CBlock& block, const CValidationSta // -bool static AlreadyHave(const CInv& inv, const CTxMemPool& mempool) EXCLUSIVE_LOCKS_REQUIRED(cs_main) +bool static AlreadyHave(const CInv& inv, const CTxMemPool& mempool, const llmq::CQuorumBlockProcessor& quorum_block_processor, + const llmq::CDKGSessionManager& qdkgsman, const llmq::CQuorumManager& qman, + const llmq::CSigSharesManager& shareman, const llmq::CSigningManager& sigman, + const llmq::CChainLocksHandler& clhandler, const llmq::CInstantSendManager& isman) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { switch (inv.type) { @@ -1503,8 +1513,8 @@ bool static AlreadyHave(const CInv& inv, const CTxMemPool& mempool) EXCLUSIVE_LO // crafted invalid DSTX-es and potentially cause high load cheaply, because // corresponding checks in ProcessMessage won't let it to send DSTX-es too often. bool fIgnoreRecentRejects = inv.type == MSG_DSTX || - llmq::quorumInstantSendManager->IsWaitingForTx(inv.hash) || - llmq::quorumInstantSendManager->IsLocked(inv.hash); + isman.IsWaitingForTx(inv.hash) || + isman.IsLocked(inv.hash); return (!fIgnoreRecentRejects && recentRejects->contains(inv.hash)) || (inv.type == MSG_DSTX && static_cast(CCoinJoin::GetDSTX(inv.hash))) || @@ -1538,19 +1548,19 @@ bool static AlreadyHave(const CInv& inv, const CTxMemPool& mempool) EXCLUSIVE_LO return ! governance->ConfirmInventoryRequest(inv); case MSG_QUORUM_FINAL_COMMITMENT: - return llmq::quorumBlockProcessor->HasMineableCommitment(inv.hash); + return quorum_block_processor.HasMineableCommitment(inv.hash); case MSG_QUORUM_CONTRIB: case MSG_QUORUM_COMPLAINT: case MSG_QUORUM_JUSTIFICATION: case MSG_QUORUM_PREMATURE_COMMITMENT: - return llmq::quorumDKGSessionManager->AlreadyHave(inv); + return qdkgsman.AlreadyHave(inv); case MSG_QUORUM_RECOVERED_SIG: - return llmq::quorumSigningManager->AlreadyHave(inv); + return sigman.AlreadyHave(inv); case MSG_CLSIG: - return llmq::chainLocksHandler->AlreadyHave(inv); + return clhandler.AlreadyHave(inv); case MSG_ISLOCK: case MSG_ISDLOCK: - return llmq::quorumInstantSendManager->AlreadyHave(inv); + return isman.AlreadyHave(inv); } // Don't know what it is, just say we already got one @@ -1604,7 +1614,7 @@ static void RelayAddress(const CAddress& addr, bool fReachable, CConnman* connma connman->ForEachNodeThen(std::move(sortfunc), std::move(pushfunc)); } -void static ProcessGetBlockData(CNode* pfrom, const CChainParams& chainparams, const CInv& inv, CConnman* connman) +void static ProcessGetBlockData(CNode* pfrom, const CChainParams& chainparams, const CInv& inv, CConnman* connman, llmq::CInstantSendManager& isman) { bool send = false; std::shared_ptr a_recent_block; @@ -1708,7 +1718,7 @@ void static ProcessGetBlockData(CNode* pfrom, const CChainParams& chainparams, c connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::TX, *pblock->vtx[pair.first])); } for (PairType &pair : merkleBlock.vMatchedTxn) { - auto islock = llmq::quorumInstantSendManager->GetInstantSendLockByTxid(pair.second); + auto islock = isman.GetInstantSendLockByTxid(pair.second); if (islock != nullptr) { connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::ISLOCK, *islock)); } @@ -1749,7 +1759,10 @@ void static ProcessGetBlockData(CNode* pfrom, const CChainParams& chainparams, c } } -void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnman* connman, CTxMemPool& mempool, const std::atomic& interruptMsgProc) LOCKS_EXCLUDED(cs_main) +void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnman* connman, CTxMemPool& mempool, + llmq::CQuorumBlockProcessor &quorum_block_processor, llmq::CDKGSessionManager& qdkgsman, + llmq::CQuorumManager& qman, llmq::CSigSharesManager& shareman, llmq::CSigningManager& sigman, + llmq::CChainLocksHandler& clhandler, llmq::CInstantSendManager& isman, const std::atomic& interruptMsgProc) LOCKS_EXCLUDED(cs_main) { AssertLockNotHeld(cs_main); @@ -1857,7 +1870,7 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm if (!push && (inv.type == MSG_QUORUM_FINAL_COMMITMENT)) { llmq::CFinalCommitment o; - if (llmq::quorumBlockProcessor->GetMineableCommitmentByHash( + if (quorum_block_processor.GetMineableCommitmentByHash( inv.hash, o)) { connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QFCOMMITMENT, o)); push = true; @@ -1866,7 +1879,7 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm if (!push && (inv.type == MSG_QUORUM_CONTRIB)) { llmq::CDKGContribution o; - if (llmq::quorumDKGSessionManager->GetContribution(inv.hash, o)) { + if (qdkgsman.GetContribution(inv.hash, o)) { connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QCONTRIB, o)); push = true; } @@ -1874,7 +1887,7 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm if (!push && (inv.type == MSG_QUORUM_COMPLAINT)) { llmq::CDKGComplaint o; - if (llmq::quorumDKGSessionManager->GetComplaint(inv.hash, o)) { + if (qdkgsman.GetComplaint(inv.hash, o)) { connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QCOMPLAINT, o)); push = true; } @@ -1882,7 +1895,7 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm if (!push && (inv.type == MSG_QUORUM_JUSTIFICATION)) { llmq::CDKGJustification o; - if (llmq::quorumDKGSessionManager->GetJustification(inv.hash, o)) { + if (qdkgsman.GetJustification(inv.hash, o)) { connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QJUSTIFICATION, o)); push = true; } @@ -1890,7 +1903,7 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm if (!push && (inv.type == MSG_QUORUM_PREMATURE_COMMITMENT)) { llmq::CDKGPrematureCommitment o; - if (llmq::quorumDKGSessionManager->GetPrematureCommitment(inv.hash, o)) { + if (qdkgsman.GetPrematureCommitment(inv.hash, o)) { connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QPCOMMITMENT, o)); push = true; } @@ -1898,7 +1911,7 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm if (!push && (inv.type == MSG_QUORUM_RECOVERED_SIG)) { llmq::CRecoveredSig o; - if (llmq::quorumSigningManager->GetRecoveredSigForGetData(inv.hash, o)) { + if (sigman.GetRecoveredSigForGetData(inv.hash, o)) { connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QSIGREC, o)); push = true; } @@ -1906,7 +1919,7 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm if (!push && (inv.type == MSG_CLSIG)) { llmq::CChainLockSig o; - if (llmq::chainLocksHandler->GetChainLockByHash(inv.hash, o)) { + if (clhandler.GetChainLockByHash(inv.hash, o)) { connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::CLSIG, o)); push = true; } @@ -1914,7 +1927,7 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm if (!push && (inv.type == MSG_ISLOCK || inv.type == MSG_ISDLOCK)) { llmq::CInstantSendLock o; - if (llmq::quorumInstantSendManager->GetInstantSendLockByHash(inv.hash, o)) { + if (isman.GetInstantSendLockByHash(inv.hash, o)) { const auto msg_type = inv.type == MSG_ISLOCK ? NetMsgType::ISLOCK : NetMsgType::ISDLOCK; connman->PushMessage(pfrom, msgMaker.Make(msg_type, o)); push = true; @@ -1931,7 +1944,7 @@ void static ProcessGetData(CNode* pfrom, const CChainParams& chainparams, CConnm const CInv &inv = *it; if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK || inv.type == MSG_CMPCT_BLOCK) { it++; - ProcessGetBlockData(pfrom, chainparams, inv, connman); + ProcessGetBlockData(pfrom, chainparams, inv, connman, isman); } } @@ -2501,7 +2514,12 @@ std::pair static ValidateDSTX(CCoinJoinBroadca return {true, false}; } -bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRecv, int64_t nTimeReceived, const CChainParams& chainparams, ChainstateManager& chainman, CTxMemPool& mempool, CConnman* connman, BanMan* banman, const std::atomic& interruptMsgProc, bool enable_bip61) +bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRecv, int64_t nTimeReceived, + const CChainParams& chainparams, ChainstateManager& chainman, CTxMemPool& mempool, + llmq::CQuorumBlockProcessor& quorum_block_processor, llmq::CDKGSessionManager& qdkgsman, + llmq::CQuorumManager& qman, llmq::CSigSharesManager& shareman, llmq::CSigningManager& sigman, + llmq::CChainLocksHandler& clhandler, llmq::CInstantSendManager& isman, CConnman* connman, + BanMan* banman, const std::atomic& interruptMsgProc, bool enable_bip61) { LogPrint(BCLog::NET, "received: %s (%u bytes) peer=%d\n", SanitizeString(msg_type), vRecv.size(), pfrom->GetId()); statsClient.inc("message.received." + SanitizeString(msg_type), 1.0f); @@ -2992,7 +3010,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec if (interruptMsgProc) return true; - bool fAlreadyHave = AlreadyHave(inv, mempool); + bool fAlreadyHave = AlreadyHave(inv, mempool, quorum_block_processor, qdkgsman, qman, shareman, sigman, clhandler, isman); LogPrint(BCLog::NET, "got inv: %s %s peer=%d\n", inv.ToString(), fAlreadyHave ? "have" : "new", pfrom->GetId()); statsClient.inc(strprintf("message.received.inv_%s", inv.GetCommand()), 1.0f); @@ -3076,7 +3094,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec } pfrom->vRecvGetData.insert(pfrom->vRecvGetData.end(), vInv.begin(), vInv.end()); - ProcessGetData(pfrom, chainparams, connman, mempool, interruptMsgProc); + ProcessGetData(pfrom, chainparams, connman, mempool, quorum_block_processor, qdkgsman, qman, shareman, sigman, clhandler, isman, interruptMsgProc); return true; } @@ -3323,7 +3341,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec bool fMissingInputs = false; CValidationState state; - if (!AlreadyHave(inv, mempool) && AcceptToMemoryPool(mempool, state, ptx, &fMissingInputs /* pfMissingInputs */, + if (!AlreadyHave(inv, mempool, quorum_block_processor, qdkgsman, qman, shareman, sigman, clhandler, isman) && AcceptToMemoryPool(mempool, state, ptx, &fMissingInputs /* pfMissingInputs */, false /* bypass_limits */, 0 /* nAbsurdFee */)) { // Process custom txes, this changes AlreadyHave to "true" if (nInvType == MSG_DSTX) { @@ -3369,11 +3387,11 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec for (const CTxIn& txin : tx.vin) { CInv _inv(MSG_TX, txin.prevout.hash); pfrom->AddInventoryKnown(_inv); - if (!AlreadyHave(_inv, mempool)) RequestObject(State(pfrom->GetId()), _inv, current_time); + if (!AlreadyHave(_inv, mempool, quorum_block_processor, qdkgsman, qman, shareman, sigman, clhandler, isman)) RequestObject(State(pfrom->GetId()), _inv, current_time); // We don't know if the previous tx was a regular or a mixing one, try both CInv _inv2(MSG_DSTX, txin.prevout.hash); pfrom->AddInventoryKnown(_inv2); - if (!AlreadyHave(_inv2, mempool)) RequestObject(State(pfrom->GetId()), _inv2, current_time); + if (!AlreadyHave(_inv2, mempool, quorum_block_processor, qdkgsman, qman, shareman, sigman, clhandler, isman)) RequestObject(State(pfrom->GetId()), _inv2, current_time); } AddOrphanTx(ptx, pfrom->GetId()); @@ -3388,7 +3406,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec // We will continue to reject this tx since it has rejected // parents so avoid re-requesting it from other peers. recentRejects->insert(tx.GetHash()); - llmq::quorumInstantSendManager->TransactionRemovedFromMempool(ptx); + isman.TransactionRemovedFromMempool(ptx); } } else { assert(IsTransactionReason(state.GetReason())); @@ -3442,7 +3460,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash)); } MaybePunishNode(pfrom->GetId(), state, /*via_compact_block*/ false); - llmq::quorumInstantSendManager->TransactionRemovedFromMempool(ptx); + isman.TransactionRemovedFromMempool(ptx); } return true; } @@ -3615,7 +3633,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec } // cs_main if (fProcessBLOCKTXN) - return ProcessMessage(pfrom, NetMsgType::BLOCKTXN, blockTxnMsg, nTimeReceived, chainparams, chainman, mempool, connman, banman, interruptMsgProc, enable_bip61); + return ProcessMessage(pfrom, NetMsgType::BLOCKTXN, blockTxnMsg, nTimeReceived, chainparams, chainman, mempool, quorum_block_processor, qdkgsman, qman, shareman, sigman, clhandler, isman, connman, banman, interruptMsgProc, enable_bip61); if (fRevertToHeaderProcessing) { // Headers received from HB compact block peers are permitted to be @@ -4014,7 +4032,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec CSimplifiedMNListDiff mnListDiff; std::string strError; - if (BuildSimplifiedMNListDiff(cmd.baseBlockHash, cmd.blockHash, mnListDiff, strError)) { + if (BuildSimplifiedMNListDiff(cmd.baseBlockHash, cmd.blockHash, mnListDiff, quorum_block_processor, strError)) { 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); @@ -4054,7 +4072,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec llmq::CQuorumRotationInfo quorumRotationInfoRet; std::string strError; - if (BuildQuorumRotationInfo(cmd, quorumRotationInfoRet, strError)) { + if (BuildQuorumRotationInfo(cmd, quorumRotationInfoRet, qman, quorum_block_processor, strError)) { connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QUORUMROTATIONINFO, quorumRotationInfoRet)); } else { strError = strprintf("getquorumrotationinfo failed for size(baseBlockHashes)=%d, blockRequestHash=%s. error=%s", cmd.baseBlockHashes.size(), cmd.blockRequestHash.ToString(), strError); @@ -4118,13 +4136,13 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec masternodeSync->ProcessMessage(pfrom, msg_type, vRecv); governance->ProcessMessage(pfrom, msg_type, vRecv, *connman, enable_bip61); CMNAuth::ProcessMessage(pfrom, msg_type, vRecv, *connman); - llmq::quorumBlockProcessor->ProcessMessage(pfrom, msg_type, vRecv); - llmq::quorumDKGSessionManager->ProcessMessage(pfrom, msg_type, vRecv); - llmq::quorumManager->ProcessMessage(pfrom, msg_type, vRecv); - llmq::quorumSigSharesManager->ProcessMessage(pfrom, msg_type, vRecv, *sporkManager); - llmq::quorumSigningManager->ProcessMessage(pfrom, msg_type, vRecv); - llmq::chainLocksHandler->ProcessMessage(pfrom, msg_type, vRecv); - llmq::quorumInstantSendManager->ProcessMessage(pfrom, msg_type, vRecv); + quorum_block_processor.ProcessMessage(pfrom, msg_type, vRecv); + qdkgsman.ProcessMessage(pfrom, qman, msg_type, vRecv); + qman.ProcessMessage(pfrom, msg_type, vRecv); + shareman.ProcessMessage(pfrom, msg_type, vRecv, *sporkManager); + sigman.ProcessMessage(pfrom, msg_type, vRecv); + clhandler.ProcessMessage(pfrom, msg_type, vRecv); + isman.ProcessMessage(pfrom, msg_type, vRecv); return true; } @@ -4183,7 +4201,7 @@ bool PeerLogicValidation::ProcessMessages(CNode* pfrom, std::atomic& inter bool fMoreWork = false; if (!pfrom->vRecvGetData.empty()) - ProcessGetData(pfrom, chainparams, connman, m_mempool, interruptMsgProc); + ProcessGetData(pfrom, chainparams, connman, m_mempool, *m_quorum_block_processor, *m_qdkgsman, *m_qman, *m_shareman, *m_sigman, *m_clhandler, *m_isman, interruptMsgProc); if (!pfrom->orphan_work_set.empty()) { LOCK2(cs_main, g_cs_orphans); @@ -4247,7 +4265,7 @@ bool PeerLogicValidation::ProcessMessages(CNode* pfrom, std::atomic& inter bool fRet = false; try { - fRet = ProcessMessage(pfrom, msg_type, vRecv, msg.m_time, chainparams, m_chainman, m_mempool, connman, m_banman, interruptMsgProc, m_enable_bip61); + fRet = ProcessMessage(pfrom, msg_type, vRecv, msg.m_time, chainparams, m_chainman, m_mempool, *m_quorum_block_processor, *m_qdkgsman, *m_qman, *m_shareman, *m_sigman, *m_clhandler, *m_isman, connman, m_banman, interruptMsgProc, m_enable_bip61); if (interruptMsgProc) return false; if (!pfrom->vRecvGetData.empty()) @@ -4453,6 +4471,9 @@ public: bool PeerLogicValidation::SendMessages(CNode* pto) { + assert(m_clhandler); + assert(m_isman); + const Consensus::Params& consensusParams = Params().GetConsensus(); { // Don't send anything until the version handshake is complete @@ -4800,14 +4821,14 @@ bool PeerLogicValidation::SendMessages(CNode* pto) int nInvType = CCoinJoin::GetDSTX(hash) ? MSG_DSTX : MSG_TX; queueAndMaybePushInv(CInv(nInvType, hash)); - const auto islock = llmq::quorumInstantSendManager->GetInstantSendLockByTxid(hash); + const auto islock = m_isman->GetInstantSendLockByTxid(hash); if (islock == nullptr) continue; if (pto->nVersion < ISDLOCK_PROTO_VERSION && islock->IsDeterministic()) continue; queueAndMaybePushInv(CInv(islock->IsDeterministic() ? MSG_ISDLOCK : MSG_ISLOCK, ::SerializeHash(*islock))); } // Send an inv for the best ChainLock we have - const auto& clsig = llmq::chainLocksHandler->GetBestChainLock(); + const auto& clsig = m_clhandler->GetBestChainLock(); if (!clsig.IsNull()) { uint256 chainlockHash = ::SerializeHash(clsig); queueAndMaybePushInv(CInv(MSG_CLSIG, chainlockHash)); @@ -5019,7 +5040,7 @@ bool PeerLogicValidation::SendMessages(CNode* pto) state.m_object_download.m_object_in_flight.erase(inv); continue; } - if (!AlreadyHave(inv, m_mempool)) { + if (!AlreadyHave(inv, m_mempool, *m_quorum_block_processor, *m_qdkgsman, *m_qman, *m_shareman, *m_sigman, *m_clhandler, *m_isman)) { // If this object was last requested more than GetObjectInterval ago, // then request. const auto last_request_time = GetObjectRequestTime(inv.hash); diff --git a/src/net_processing.h b/src/net_processing.h index aecd9c0dcc..e6de758839 100644 --- a/src/net_processing.h +++ b/src/net_processing.h @@ -14,6 +14,16 @@ class CTxMemPool; class ChainstateManager; +namespace llmq { +class CChainLocksHandler; +class CDKGSessionManager; +class CInstantSendManager; +class CQuorumBlockProcessor; +class CQuorumManager; +class CSigningManager; +class CSigSharesManager; +} // namespace llmq + extern CCriticalSection cs_main; /** Default for -maxorphantxsize, maximum size in megabytes the orphan map can grow before entries are removed */ @@ -31,10 +41,21 @@ private: BanMan* const m_banman; ChainstateManager& m_chainman; CTxMemPool& m_mempool; + std::unique_ptr& m_qdkgsman; + std::unique_ptr& m_quorum_block_processor; + std::unique_ptr& m_qman; + std::unique_ptr& m_sigman; + std::unique_ptr& m_shareman; + std::unique_ptr& m_clhandler; + std::unique_ptr& m_isman; bool MaybeDiscourageAndDisconnect(CNode* pnode, bool enable_bip61) EXCLUSIVE_LOCKS_REQUIRED(cs_main); public: - PeerLogicValidation(CConnman* connmanIn, BanMan* banman, CScheduler &scheduler, ChainstateManager& chainman, CTxMemPool& pool, bool enable_bip61); + PeerLogicValidation(CConnman* connmanIn, BanMan* banman, CScheduler &scheduler, ChainstateManager& chainman, CTxMemPool& pool, + std::unique_ptr& quorum_block_processor, std::unique_ptr& qdkgsman, + std::unique_ptr& qman, std::unique_ptr& shareman, + std::unique_ptr& sigman, std::unique_ptr& clhandler, + std::unique_ptr& isman, bool enable_bip61); /** * Overridden from CValidationInterface. diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 01189faa52..636963e1e0 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -12,6 +12,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -152,7 +155,7 @@ UniValue generateBlocks(ChainstateManager& chainman, const CTxMemPool& mempool, UniValue blockHashes(UniValue::VARR); while (nHeight < nHeightEnd && !ShutdownRequested()) { - std::unique_ptr pblocktemplate(BlockAssembler(*sporkManager, *governance, mempool, Params()).CreateNewBlock(coinbaseScript->reserveScript)); + std::unique_ptr pblocktemplate(BlockAssembler(*sporkManager, *governance, *llmq::quorumBlockProcessor, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, mempool, Params()).CreateNewBlock(coinbaseScript->reserveScript)); if (!pblocktemplate.get()) throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block"); CBlock *pblock = &pblocktemplate->block; @@ -362,7 +365,7 @@ static UniValue generateblock(const JSONRPCRequest& request) LOCK(cs_main); CTxMemPool empty_mempool; - std::unique_ptr blocktemplate(BlockAssembler(*sporkManager, *governance, empty_mempool, chainparams).CreateNewBlock(coinbase_script)); + std::unique_ptr blocktemplate(BlockAssembler(*sporkManager, *governance, *llmq::quorumBlockProcessor, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, empty_mempool, chainparams).CreateNewBlock(coinbase_script)); if (!blocktemplate) { throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block"); } @@ -378,7 +381,7 @@ static UniValue generateblock(const JSONRPCRequest& request) LOCK(cs_main); CValidationState state; - if (!TestBlockValidity(state, chainparams, block, LookupBlockIndex(block.hashPrevBlock), false, false)) { + if (!TestBlockValidity(state, *llmq::chainLocksHandler, chainparams, block, LookupBlockIndex(block.hashPrevBlock), false, false)) { throw JSONRPCError(RPC_VERIFY_ERROR, strprintf("TestBlockValidity failed: %s", state.GetRejectReason())); } } @@ -664,7 +667,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request) if (block.hashPrevBlock != pindexPrev->GetBlockHash()) return "inconclusive-not-best-prevblk"; CValidationState state; - TestBlockValidity(state, Params(), block, pindexPrev, false, true); + TestBlockValidity(state, *llmq::chainLocksHandler, Params(), block, pindexPrev, false, true); return BIP22ValidationResult(state); } @@ -769,7 +772,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request) // Create new block CScript scriptDummy = CScript() << OP_TRUE; - pblocktemplate = BlockAssembler(*sporkManager, *governance, mempool, Params()).CreateNewBlock(scriptDummy); + pblocktemplate = BlockAssembler(*sporkManager, *governance, *llmq::quorumBlockProcessor, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, mempool, Params()).CreateNewBlock(scriptDummy); if (!pblocktemplate) throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); diff --git a/src/rpc/rpcevo.cpp b/src/rpc/rpcevo.cpp index 3d47eca322..b477efa846 100644 --- a/src/rpc/rpcevo.cpp +++ b/src/rpc/rpcevo.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -1176,7 +1177,7 @@ static UniValue protx_diff(const JSONRPCRequest& request) CSimplifiedMNListDiff mnListDiff; std::string strError; - if (!BuildSimplifiedMNListDiff(baseBlockHash, blockHash, mnListDiff, strError, extended)) { + if (!BuildSimplifiedMNListDiff(baseBlockHash, blockHash, mnListDiff, *llmq::quorumBlockProcessor, strError, extended)) { throw std::runtime_error(strError); } diff --git a/src/rpc/rpcquorums.cpp b/src/rpc/rpcquorums.cpp index 00ca8edae5..8046a56a55 100644 --- a/src/rpc/rpcquorums.cpp +++ b/src/rpc/rpcquorums.cpp @@ -436,13 +436,13 @@ static UniValue quorum_sigs_cmd(const JSONRPCRequest& request) fSubmit = ParseBoolV(request.params[4], "submit"); } if (fSubmit) { - return llmq::quorumSigningManager->AsyncSignIfMember(llmqType, id, msgHash, quorumHash); + return llmq::quorumSigningManager->AsyncSignIfMember(llmqType, *llmq::quorumSigSharesManager, id, msgHash, quorumHash); } else { llmq::CQuorumCPtr pQuorum; if (quorumHash.IsNull()) { - pQuorum = llmq::quorumSigningManager->SelectQuorumForSigning(llmqType, id); + pQuorum = llmq::quorumSigningManager->SelectQuorumForSigning(llmqType, *llmq::quorumManager, id); } else { pQuorum = llmq::quorumManager->GetQuorum(llmqType, quorumHash); } @@ -481,8 +481,8 @@ static UniValue quorum_sigs_cmd(const JSONRPCRequest& request) } // First check against the current active set, if it fails check against the last active set int signOffset{llmq::GetLLMQParams(llmqType).dkgInterval}; - return llmq::quorumSigningManager->VerifyRecoveredSig(llmqType, signHeight, id, msgHash, sig, 0) || - llmq::quorumSigningManager->VerifyRecoveredSig(llmqType, signHeight, id, msgHash, sig, signOffset); + return llmq::quorumSigningManager->VerifyRecoveredSig(llmqType, *llmq::quorumManager, signHeight, id, msgHash, sig, 0) || + llmq::quorumSigningManager->VerifyRecoveredSig(llmqType, *llmq::quorumManager, signHeight, id, msgHash, sig, signOffset); } else { uint256 quorumHash = ParseHashV(request.params[4], "quorumHash"); llmq::CQuorumCPtr quorum = llmq::quorumManager->GetQuorum(llmqType, quorumHash); @@ -539,7 +539,7 @@ static UniValue quorum_selectquorum(const JSONRPCRequest& request) UniValue ret(UniValue::VOBJ); - auto quorum = llmq::quorumSigningManager->SelectQuorumForSigning(llmqType, id); + auto quorum = llmq::quorumSigningManager->SelectQuorumForSigning(llmqType, *llmq::quorumManager, id); if (!quorum) { throw JSONRPCError(RPC_MISC_ERROR, "no quorums active"); } @@ -670,7 +670,7 @@ static UniValue quorum_rotationinfo(const JSONRPCRequest& request) ++idx; } LOCK(cs_main); - if (!BuildQuorumRotationInfo(cmd, quorumRotationInfoRet, strError)) { + if (!BuildQuorumRotationInfo(cmd, quorumRotationInfoRet, *llmq::quorumManager, *llmq::quorumBlockProcessor, strError)) { throw JSONRPCError(RPC_INVALID_REQUEST, strError); } @@ -776,7 +776,7 @@ static UniValue verifychainlock(const JSONRPCRequest& request) const auto llmqType = Params().GetConsensus().llmqTypeChainLocks; const uint256 nRequestId = ::SerializeHash(std::make_pair(llmq::CLSIG_REQUESTID_PREFIX, nBlockHeight)); - return llmq::CSigningManager::VerifyRecoveredSig(llmqType, nBlockHeight, nRequestId, nBlockHash, chainLockSig); + return llmq::CSigningManager::VerifyRecoveredSig(llmqType, *llmq::quorumManager, nBlockHeight, nRequestId, nBlockHash, chainLockSig); } static void verifyislock_help(const JSONRPCRequest& request) @@ -841,11 +841,11 @@ static UniValue verifyislock(const JSONRPCRequest& request) pBlockIndex = ::ChainActive()[signHeight]; } } - auto llmqType = llmq::utils::GetInstantSendLLMQType(pBlockIndex); + auto llmqType = llmq::utils::GetInstantSendLLMQType(*llmq::quorumManager, pBlockIndex); // First check against the current active set, if it fails check against the last active set int signOffset{llmq::GetLLMQParams(llmqType).dkgInterval}; - return llmq::quorumSigningManager->VerifyRecoveredSig(llmqType, signHeight, id, txid, sig, 0) || - llmq::quorumSigningManager->VerifyRecoveredSig(llmqType, signHeight, id, txid, sig, signOffset); + return llmq::quorumSigningManager->VerifyRecoveredSig(llmqType, *llmq::quorumManager, signHeight, id, txid, sig, 0) || + llmq::quorumSigningManager->VerifyRecoveredSig(llmqType, *llmq::quorumManager, signHeight, id, txid, sig, signOffset); } // clang-format off static const CRPCCommand commands[] = diff --git a/src/test/block_reward_reallocation_tests.cpp b/src/test/block_reward_reallocation_tests.cpp index 098eeeecd1..ba9823c1d6 100644 --- a/src/test/block_reward_reallocation_tests.cpp +++ b/src/test/block_reward_reallocation_tests.cpp @@ -20,6 +20,9 @@ #include #include #include +#include +#include +#include #include @@ -214,7 +217,7 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS BOOST_CHECK_EQUAL(VersionBitsTipState(consensus_params, deployment_id), ThresholdState::STARTED); BOOST_CHECK_EQUAL(VersionBitsTipStatistics(consensus_params, deployment_id).threshold, threshold(0)); // Next block should be signaling by default - const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey); + const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *llmq::quorumBlockProcessor, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey); const uint32_t bitmask = ((uint32_t)1) << consensus_params.vDeployments[deployment_id].bit; BOOST_CHECK_EQUAL(::ChainActive().Tip()->nVersion & bitmask, 0); BOOST_CHECK_EQUAL(pblocktemplate->block.nVersion & bitmask, bitmask); @@ -281,7 +284,7 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS deterministicMNManager->UpdatedBlockTip(::ChainActive().Tip()); BOOST_ASSERT(deterministicMNManager->GetListAtChainTip().HasMN(tx.GetHash())); auto masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidy(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params), 2500); - const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey); + const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *llmq::quorumBlockProcessor, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey); BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, masternode_payment); } @@ -292,7 +295,7 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS { LOCK(cs_main); auto masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidy(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params), 2500); - const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey); + const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *llmq::quorumBlockProcessor, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey); BOOST_CHECK_EQUAL(pblocktemplate->block.vtx[0]->GetValueOut(), 13748571607); BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, masternode_payment); BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, 6874285801); // 0.4999999998 @@ -307,7 +310,7 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS } LOCK(cs_main); auto masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidy(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params), 2500); - const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey); + const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *llmq::quorumBlockProcessor, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey); BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, masternode_payment); } } @@ -316,7 +319,7 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS // Reward split should reach ~60/40 after reallocation is done LOCK(cs_main); auto masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidy(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params), 2500); - const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey); + const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *llmq::quorumBlockProcessor, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey); BOOST_CHECK_EQUAL(pblocktemplate->block.vtx[0]->GetValueOut(), 10221599170); BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, masternode_payment); BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, 6132959502); // 0.6 @@ -330,7 +333,7 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS } LOCK(cs_main); auto masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidy(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params), 2500); - const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey); + const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *llmq::quorumBlockProcessor, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey); BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, masternode_payment); } @@ -338,7 +341,7 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS // Reward split should reach ~60/40 after reallocation is done LOCK(cs_main); auto masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidy(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params), 2500); - const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey); + const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *llmq::quorumBlockProcessor, *llmq::chainLocksHandler, *llmq::quorumInstantSendManager, *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey); BOOST_CHECK_EQUAL(pblocktemplate->block.vtx[0]->GetValueOut(), 9491484944); BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, masternode_payment); BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, 5694890966); // 0.6 diff --git a/src/test/blockfilter_index_tests.cpp b/src/test/blockfilter_index_tests.cpp index bd8b8fc086..31bcebb298 100644 --- a/src/test/blockfilter_index_tests.cpp +++ b/src/test/blockfilter_index_tests.cpp @@ -7,6 +7,9 @@ #include #include #include +#include +#include +#include #include #include #include