From 7be3d4a8842a476035cc02c1fd4c4450b4026a26 Mon Sep 17 00:00:00 2001 From: pasta Date: Wed, 12 Nov 2025 18:02:30 -0600 Subject: [PATCH 1/7] feat: proactively relay recovered signatures when we are the member who performed recovery --- src/llmq/signing.cpp | 15 +++++++++++---- src/llmq/signing.h | 2 +- src/llmq/signing_shares.cpp | 8 ++++---- src/llmq/signing_shares.h | 2 +- .../active/notificationinterface.cpp | 4 ++-- src/masternode/active/notificationinterface.h | 2 +- src/net_processing.cpp | 19 +++++++++++++++---- src/net_processing.h | 2 +- src/validationinterface.cpp | 6 +++--- src/validationinterface.h | 4 ++-- src/zmq/zmqabstractnotifier.cpp | 2 +- src/zmq/zmqabstractnotifier.h | 2 +- src/zmq/zmqnotificationinterface.cpp | 6 +++--- src/zmq/zmqnotificationinterface.h | 2 +- src/zmq/zmqpublishnotifier.cpp | 4 ++-- src/zmq/zmqpublishnotifier.h | 4 ++-- 16 files changed, 51 insertions(+), 33 deletions(-) diff --git a/src/llmq/signing.cpp b/src/llmq/signing.cpp index 4a1ac7a6b528..e1741f34cc1e 100644 --- a/src/llmq/signing.cpp +++ b/src/llmq/signing.cpp @@ -25,6 +25,8 @@ #include #include +#include "options.h" + namespace llmq { CRecoveredSigsDb::CRecoveredSigsDb(const util::DbWrapperParams& db_params) : @@ -517,7 +519,7 @@ void CSigningManager::ProcessPendingReconstructedRecoveredSigs(PeerManager& peer WITH_LOCK(cs_pending, swap(m, pendingReconstructedRecoveredSigs)); for (const auto& p : m) { - ProcessRecoveredSig(p.second, peerman); + ProcessRecoveredSig(p.second, peerman, -1); } } @@ -579,7 +581,7 @@ bool CSigningManager::ProcessPendingRecoveredSigs(PeerManager& peerman) continue; } - ProcessRecoveredSig(recSig, peerman); + ProcessRecoveredSig(recSig, peerman, nodeId); } } @@ -587,7 +589,7 @@ bool CSigningManager::ProcessPendingRecoveredSigs(PeerManager& peerman) } // signature must be verified already -void CSigningManager::ProcessRecoveredSig(const std::shared_ptr& recoveredSig, PeerManager& peerman) +void CSigningManager::ProcessRecoveredSig(const std::shared_ptr& recoveredSig, PeerManager& peerman, NodeId from) { auto llmqType = recoveredSig->getLlmqType(); @@ -630,7 +632,12 @@ void CSigningManager::ProcessRecoveredSig(const std::shared_ptrHandleNewRecoveredSig(*recoveredSig)); } - GetMainSignals().NotifyRecoveredSig(recoveredSig, recoveredSig->GetHash().ToString()); + // TODO refactor to use a better abstraction analogous to IsAllMembersConnectedEnabled + auto proactive_relay = from == -1 && + llmqType != Consensus::LLMQType::LLMQ_100_67 && + llmqType != Consensus::LLMQType::LLMQ_400_60 && + llmqType != Consensus::LLMQType::LLMQ_400_85; + GetMainSignals().NotifyRecoveredSig(recoveredSig, recoveredSig->GetHash().ToString(), proactive_relay); } void CSigningManager::PushReconstructedRecoveredSig(const std::shared_ptr& recoveredSig) diff --git a/src/llmq/signing.h b/src/llmq/signing.h index d4149314c011..88d426539de6 100644 --- a/src/llmq/signing.h +++ b/src/llmq/signing.h @@ -220,7 +220,7 @@ class CSigningManager // Used by CSigSharesManager CRecoveredSigsDb& GetDb() { return db; } - void ProcessRecoveredSig(const std::shared_ptr& recoveredSig, PeerManager& peerman) + void ProcessRecoveredSig(const std::shared_ptr& recoveredSig, PeerManager& peerman, NodeId pFrom) EXCLUSIVE_LOCKS_REQUIRED(!cs_pending, !cs_listeners); // Needed for access to GetDb() and ProcessRecoveredSig() diff --git a/src/llmq/signing_shares.cpp b/src/llmq/signing_shares.cpp index ef899d1b1134..eec16b2f9aca 100644 --- a/src/llmq/signing_shares.cpp +++ b/src/llmq/signing_shares.cpp @@ -844,7 +844,7 @@ void CSigSharesManager::TryRecoverSig(const CQuorum& quorum, const uint256& id, // Handle single-member quorum case after releasing the lock if (singleMemberRecoveredSig) { - sigman.ProcessRecoveredSig(singleMemberRecoveredSig, m_peerman); + sigman.ProcessRecoveredSig(singleMemberRecoveredSig, m_peerman, -1); return; // end of single-quorum processing } @@ -876,7 +876,7 @@ void CSigSharesManager::TryRecoverSig(const CQuorum& quorum, const uint256& id, } } - sigman.ProcessRecoveredSig(rs, m_peerman); + sigman.ProcessRecoveredSig(rs, m_peerman, -1); } CDeterministicMNCPtr CSigSharesManager::SelectMemberForRecovery(const CQuorum& quorum, const uint256 &id, int attempt) @@ -974,9 +974,9 @@ bool CSigSharesManager::AsyncSignIfMember(Consensus::LLMQType llmqType, CSigning return true; } -void CSigSharesManager::NotifyRecoveredSig(const std::shared_ptr& sig) const +void CSigSharesManager::NotifyRecoveredSig(const std::shared_ptr& sig, bool proactive_relay) const { - m_peerman.RelayRecoveredSig(Assert(sig)->GetHash()); + m_peerman.RelayRecoveredSig(*Assert(sig), proactive_relay); } void CSigSharesManager::CollectSigSharesToRequest(std::unordered_map>& sigSharesToRequest) diff --git a/src/llmq/signing_shares.h b/src/llmq/signing_shares.h index 24865fec98a8..7e8e23eb17a3 100644 --- a/src/llmq/signing_shares.h +++ b/src/llmq/signing_shares.h @@ -449,7 +449,7 @@ class CSigSharesManager : public CRecoveredSigsListener const uint256& msgHash, const uint256& quorumHash = uint256(), bool allowReSign = false, bool allowDiffMsgHashSigning = false) EXCLUSIVE_LOCKS_REQUIRED(!cs_pendingSigns, !cs); - void NotifyRecoveredSig(const std::shared_ptr& sig) const EXCLUSIVE_LOCKS_REQUIRED(!cs); + void NotifyRecoveredSig(const std::shared_ptr& sig, bool proactive_relay) const EXCLUSIVE_LOCKS_REQUIRED(!cs); private: std::optional CreateSigShareForSingleMember(const CQuorum& quorum, const uint256& id, const uint256& msgHash) const; diff --git a/src/masternode/active/notificationinterface.cpp b/src/masternode/active/notificationinterface.cpp index 17340861ae6c..126ba167940b 100644 --- a/src/masternode/active/notificationinterface.cpp +++ b/src/masternode/active/notificationinterface.cpp @@ -29,9 +29,9 @@ void ActiveNotificationInterface::UpdatedBlockTip(const CBlockIndex* pindexNew, m_active_ctx.gov_signer->UpdatedBlockTip(pindexNew); } -void ActiveNotificationInterface::NotifyRecoveredSig(const std::shared_ptr& sig) +void ActiveNotificationInterface::NotifyRecoveredSig(const std::shared_ptr& sig, bool proactive_relay) { - m_active_ctx.shareman->NotifyRecoveredSig(sig); + m_active_ctx.shareman->NotifyRecoveredSig(sig, proactive_relay); } std::unique_ptr g_active_notification_interface; diff --git a/src/masternode/active/notificationinterface.h b/src/masternode/active/notificationinterface.h index 905371e41b7a..fade9ede4130 100644 --- a/src/masternode/active/notificationinterface.h +++ b/src/masternode/active/notificationinterface.h @@ -26,7 +26,7 @@ class ActiveNotificationInterface final : public CValidationInterface protected: // CValidationInterface - void NotifyRecoveredSig(const std::shared_ptr& sig) override; + void NotifyRecoveredSig(const std::shared_ptr& sig, bool proactive_relay) override; void UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, bool fInitialDownload) override; private: diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 9808fb9f646a..c3180f3e8b61 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -632,7 +632,7 @@ class PeerManagerImpl final : public PeerManager void RelayInv(const CInv& inv) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex); void RelayInv(const CInv& inv, const int minProtoVersion) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex); void RelayTransaction(const uint256& txid) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex); - void RelayRecoveredSig(const uint256& sigHash) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex); + void RelayRecoveredSig(const llmq::CRecoveredSig& sig, bool proactive_relay) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex); void RelayDSQ(const CCoinJoinQueue& queue) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex); void SetBestHeight(int height) override { m_best_height = height; }; void Misbehaving(const NodeId pnode, const int howmuch, const std::string& message = "") override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex); @@ -2536,9 +2536,20 @@ void PeerManagerImpl::_RelayTransaction(const uint256& txid) }; } -void PeerManagerImpl::RelayRecoveredSig(const uint256& sigHash) -{ - const CInv inv{MSG_QUORUM_RECOVERED_SIG, sigHash}; +void PeerManagerImpl::RelayRecoveredSig(const llmq::CRecoveredSig& sig, bool proactive_relay) { + if (proactive_relay) { + // We were the peer that recovered this; avoid a bunch of `inv` -> `GetData` spam by proactively sending + m_connman.ForEachNode([this, &sig](CNode* pnode) -> bool { + // Skip nodes that don't want recovered signatures + PeerRef peer = GetPeerRef(pnode->GetId()); + if (peer == nullptr || !peer->m_wants_recsigs) return true; + CNetMsgMaker msgMaker(pnode->GetCommonVersion()); + m_connman.PushMessage(pnode, msgMaker.Make(NetMsgType::QSIGREC, sig)); + return true; + }); + return; + } + const CInv inv{MSG_QUORUM_RECOVERED_SIG, sig.GetHash()}; READ_LOCK(m_peer_mutex); for (const auto& [_, peer] : m_peer_map) { if (peer->m_wants_recsigs) { diff --git a/src/net_processing.h b/src/net_processing.h index d15298401c24..7dc68e272d53 100644 --- a/src/net_processing.h +++ b/src/net_processing.h @@ -133,7 +133,7 @@ class PeerManager : public CValidationInterface, public NetEventsInterface, publ virtual void RelayTransaction(const uint256& txid) = 0; /** Relay recovered sigs to all interested peers */ - virtual void RelayRecoveredSig(const uint256& sigHash) = 0; + virtual void RelayRecoveredSig(const llmq::CRecoveredSig& sig, bool proactive_relay) = 0; /** Set the best height */ virtual void SetBestHeight(int height) = 0; diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp index a71c7ab1f3c5..2fd14b426434 100644 --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -312,9 +312,9 @@ void CMainSignals::NotifyInstantSendDoubleSpendAttempt(const CTransactionRef& cu previousTx->GetHash().ToString()); } -void CMainSignals::NotifyRecoveredSig(const std::shared_ptr& sig, const std::string& id) { - auto event = [sig, this] { - m_internals->Iterate([&](CValidationInterface& callbacks) { callbacks.NotifyRecoveredSig(sig); }); +void CMainSignals::NotifyRecoveredSig(const std::shared_ptr& sig, const std::string& id, bool proactive_relay) { + auto event = [sig, proactive_relay, this] { + m_internals->Iterate([&](CValidationInterface& callbacks) { callbacks.NotifyRecoveredSig(sig, proactive_relay); }); }; ENQUEUE_AND_LOG_EVENT(event, "%s: notify recoveredsig=%s", __func__, id); diff --git a/src/validationinterface.h b/src/validationinterface.h index 271c76f88fa5..faed6347aba7 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -168,7 +168,7 @@ class CValidationInterface { virtual void NotifyGovernanceVote(const std::shared_ptr& tip_mn_list, const std::shared_ptr& vote) {} virtual void NotifyGovernanceObject(const std::shared_ptr& object) {} virtual void NotifyInstantSendDoubleSpendAttempt(const CTransactionRef& currentTx, const CTransactionRef& previousTx) {} - virtual void NotifyRecoveredSig(const std::shared_ptr& sig) {} + virtual void NotifyRecoveredSig(const std::shared_ptr& sig, bool proactive_relay) {} virtual void NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff) {} /** * Notifies listeners of the new active block chain on-disk. @@ -236,7 +236,7 @@ class CMainSignals { void NotifyGovernanceVote(const std::shared_ptr& tip_mn_list, const std::shared_ptr& vote, const std::string& id); void NotifyGovernanceObject(const std::shared_ptr& object, const std::string& id); void NotifyInstantSendDoubleSpendAttempt(const CTransactionRef ¤tTx, const CTransactionRef &previousTx); - void NotifyRecoveredSig(const std::shared_ptr &sig, const std::string& id); + void NotifyRecoveredSig(const std::shared_ptr &sig, const std::string &id, bool proactive_relay); void NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff); void ChainStateFlushed(const CBlockLocator &); void BlockChecked(const CBlock&, const BlockValidationState&); diff --git a/src/zmq/zmqabstractnotifier.cpp b/src/zmq/zmqabstractnotifier.cpp index a38921871534..22781e00fadf 100644 --- a/src/zmq/zmqabstractnotifier.cpp +++ b/src/zmq/zmqabstractnotifier.cpp @@ -68,7 +68,7 @@ bool CZMQAbstractNotifier::NotifyInstantSendDoubleSpendAttempt(const CTransactio return true; } -bool CZMQAbstractNotifier::NotifyRecoveredSig(const std::shared_ptr & /*sig*/) +bool CZMQAbstractNotifier::NotifyRecoveredSig(const std::shared_ptr & /*sig*/, bool /*proactive_relay*/) { return true; } diff --git a/src/zmq/zmqabstractnotifier.h b/src/zmq/zmqabstractnotifier.h index 6abee4024859..7284ff3b7e51 100644 --- a/src/zmq/zmqabstractnotifier.h +++ b/src/zmq/zmqabstractnotifier.h @@ -75,7 +75,7 @@ class CZMQAbstractNotifier virtual bool NotifyGovernanceVote(const std::shared_ptr& tip_mn_list, const std::shared_ptr& vote); virtual bool NotifyGovernanceObject(const std::shared_ptr& object); virtual bool NotifyInstantSendDoubleSpendAttempt(const CTransactionRef& currentTx, const CTransactionRef& previousTx); - virtual bool NotifyRecoveredSig(const std::shared_ptr& sig); + virtual bool NotifyRecoveredSig(const std::shared_ptr& sig, bool proactive_relay); protected: void *psocket; diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp index 06e21f8cefef..1d02e4780d6f 100644 --- a/src/zmq/zmqnotificationinterface.cpp +++ b/src/zmq/zmqnotificationinterface.cpp @@ -241,10 +241,10 @@ void CZMQNotificationInterface::NotifyInstantSendDoubleSpendAttempt(const CTrans }); } -void CZMQNotificationInterface::NotifyRecoveredSig(const std::shared_ptr& sig) +void CZMQNotificationInterface::NotifyRecoveredSig(const std::shared_ptr& sig, bool proactive_relay) { - TryForEachAndRemoveFailed(notifiers, [&sig](CZMQAbstractNotifier* notifier) { - return notifier->NotifyRecoveredSig(sig); + TryForEachAndRemoveFailed(notifiers, [&sig, proactive_relay](CZMQAbstractNotifier* notifier) { + return notifier->NotifyRecoveredSig(sig, proactive_relay); }); } diff --git a/src/zmq/zmqnotificationinterface.h b/src/zmq/zmqnotificationinterface.h index e0de1074f4d3..ce8c53e86ce7 100644 --- a/src/zmq/zmqnotificationinterface.h +++ b/src/zmq/zmqnotificationinterface.h @@ -36,7 +36,7 @@ class CZMQNotificationInterface final : public CValidationInterface void NotifyGovernanceVote(const std::shared_ptr& tip_mn_list, const std::shared_ptr& vote) override; void NotifyGovernanceObject(const std::shared_ptr& object) override; void NotifyInstantSendDoubleSpendAttempt(const CTransactionRef& currentTx, const CTransactionRef& previousTx) override; - void NotifyRecoveredSig(const std::shared_ptr& sig) override; + void NotifyRecoveredSig(const std::shared_ptr& sig, bool proactive_relay) override; private: CZMQNotificationInterface(); diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp index 82e0a5660a2f..6c8354bf9fbf 100644 --- a/src/zmq/zmqpublishnotifier.cpp +++ b/src/zmq/zmqpublishnotifier.cpp @@ -296,7 +296,7 @@ bool CZMQPublishHashInstantSendDoubleSpendNotifier::NotifyInstantSendDoubleSpend && SendZmqMessage(MSG_HASHISCON, dataPreviousHash, 32); } -bool CZMQPublishHashRecoveredSigNotifier::NotifyRecoveredSig(const std::shared_ptr &sig) +bool CZMQPublishHashRecoveredSigNotifier::NotifyRecoveredSig(const std::shared_ptr &sig, bool proactive_relay) { LogPrint(BCLog::ZMQ, "Publish hashrecoveredsig %s to %s\n", sig->getMsgHash().ToString(), this->address); char data[32]; @@ -462,7 +462,7 @@ bool CZMQPublishRawInstantSendDoubleSpendNotifier::NotifyInstantSendDoubleSpendA && SendZmqMessage(MSG_RAWISCON, &(*ssPrevious.begin()), ssPrevious.size()); } -bool CZMQPublishRawRecoveredSigNotifier::NotifyRecoveredSig(const std::shared_ptr& sig) +bool CZMQPublishRawRecoveredSigNotifier::NotifyRecoveredSig(const std::shared_ptr& sig, bool proactive_relay) { LogPrint(BCLog::ZMQ, "Publish rawrecoveredsig %s to %s\n", sig->getMsgHash().ToString(), this->address); diff --git a/src/zmq/zmqpublishnotifier.h b/src/zmq/zmqpublishnotifier.h index 2f1803add73f..f9f32bfe1a5d 100644 --- a/src/zmq/zmqpublishnotifier.h +++ b/src/zmq/zmqpublishnotifier.h @@ -81,7 +81,7 @@ class CZMQPublishHashInstantSendDoubleSpendNotifier : public CZMQAbstractPublish class CZMQPublishHashRecoveredSigNotifier : public CZMQAbstractPublishNotifier { public: - bool NotifyRecoveredSig(const std::shared_ptr&) override; + bool NotifyRecoveredSig(const std::shared_ptr&, bool proactive_relay) override; }; class CZMQPublishRawBlockNotifier : public CZMQAbstractPublishNotifier @@ -150,6 +150,6 @@ class CZMQPublishRawInstantSendDoubleSpendNotifier : public CZMQAbstractPublishN class CZMQPublishRawRecoveredSigNotifier : public CZMQAbstractPublishNotifier { public: - bool NotifyRecoveredSig(const std::shared_ptr &sig) override; + bool NotifyRecoveredSig(const std::shared_ptr &sig, bool proactive_relay) override; }; #endif // BITCOIN_ZMQ_ZMQPUBLISHNOTIFIER_H From 4e449d01b4a4a93abb953fc55b09e3b2fdd7ae54 Mon Sep 17 00:00:00 2001 From: pasta Date: Wed, 12 Nov 2025 19:55:48 -0600 Subject: [PATCH 2/7] feat: enhance recovered signature propagation by leveraging full-mesh connections for all members --- src/llmq/utils.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/llmq/utils.cpp b/src/llmq/utils.cpp index 099f5f74c9b9..a0aab7b722d5 100644 --- a/src/llmq/utils.cpp +++ b/src/llmq/utils.cpp @@ -862,7 +862,19 @@ bool EnsureQuorumConnections(const Consensus::LLMQParams& llmqParams, CConnman& if (isMember) { connections = GetQuorumConnections(llmqParams, dmnman, qsnapman, sporkman, pQuorumBaseBlockIndex, myProTxHash, true); - relayMembers = GetQuorumRelayMembers(llmqParams, dmnman, qsnapman, pQuorumBaseBlockIndex, myProTxHash, true); + // If all-members-connected is enabled for this quorum type, leverage the full-mesh + // connections for low-latency recovered sig propagation by treating all members as + // relay members (instead of the ring-based subset). This ensures peers will send + // QSENDRECSIGS to each other across the full mesh and set m_wants_recsigs widely. + if (IsAllMembersConnectedEnabled(llmqParams.type, sporkman)) { + for (const auto& dmn : members) { + if (dmn->proTxHash != myProTxHash) { + relayMembers.emplace(dmn->proTxHash); + } + } + } else { + relayMembers = GetQuorumRelayMembers(llmqParams, dmnman, qsnapman, pQuorumBaseBlockIndex, myProTxHash, true); + } } else { auto cindexes = CalcDeterministicWatchConnections(llmqParams.type, pQuorumBaseBlockIndex, members.size(), 1); for (auto idx : cindexes) { From 9f27cfb26d8e593a6f1825f60193d0fa1dd22d32 Mon Sep 17 00:00:00 2001 From: pasta Date: Wed, 12 Nov 2025 19:57:08 -0600 Subject: [PATCH 3/7] fix: proper include syntax --- src/llmq/signing.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/llmq/signing.cpp b/src/llmq/signing.cpp index e1741f34cc1e..d2a2f87c7710 100644 --- a/src/llmq/signing.cpp +++ b/src/llmq/signing.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -25,8 +26,6 @@ #include #include -#include "options.h" - namespace llmq { CRecoveredSigsDb::CRecoveredSigsDb(const util::DbWrapperParams& db_params) : From a57a8119a081bfa75f044e75b9c5eb073f0b58d5 Mon Sep 17 00:00:00 2001 From: pasta Date: Wed, 19 Nov 2025 15:01:38 -0600 Subject: [PATCH 4/7] fix: avoid improper dual way connection attempts --- src/llmq/utils.cpp | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/src/llmq/utils.cpp b/src/llmq/utils.cpp index a0aab7b722d5..be3307675bea 100644 --- a/src/llmq/utils.cpp +++ b/src/llmq/utils.cpp @@ -858,29 +858,14 @@ bool EnsureQuorumConnections(const Consensus::LLMQParams& llmqParams, CConnman& __func__, isMember, pQuorumBaseBlockIndex->GetBlockHash().ToString()); Uint256HashSet connections; - Uint256HashSet relayMembers; if (isMember) { connections = GetQuorumConnections(llmqParams, dmnman, qsnapman, sporkman, pQuorumBaseBlockIndex, myProTxHash, true); - // If all-members-connected is enabled for this quorum type, leverage the full-mesh - // connections for low-latency recovered sig propagation by treating all members as - // relay members (instead of the ring-based subset). This ensures peers will send - // QSENDRECSIGS to each other across the full mesh and set m_wants_recsigs widely. - if (IsAllMembersConnectedEnabled(llmqParams.type, sporkman)) { - for (const auto& dmn : members) { - if (dmn->proTxHash != myProTxHash) { - relayMembers.emplace(dmn->proTxHash); - } - } - } else { - relayMembers = GetQuorumRelayMembers(llmqParams, dmnman, qsnapman, pQuorumBaseBlockIndex, myProTxHash, true); - } } else { auto cindexes = CalcDeterministicWatchConnections(llmqParams.type, pQuorumBaseBlockIndex, members.size(), 1); for (auto idx : cindexes) { connections.emplace(members[idx]->proTxHash); } - relayMembers = connections; } if (!connections.empty()) { if (!connman.HasMasternodeQuorumNodes(llmqParams.type, pQuorumBaseBlockIndex->GetBlockHash()) && @@ -898,9 +883,7 @@ bool EnsureQuorumConnections(const Consensus::LLMQParams& llmqParams, CConnman& LogPrint(BCLog::NET_NETCONN, debugMsg.c_str()); /* Continued */ } connman.SetMasternodeQuorumNodes(llmqParams.type, pQuorumBaseBlockIndex->GetBlockHash(), connections); - } - if (!relayMembers.empty()) { - connman.SetMasternodeQuorumRelayMembers(llmqParams.type, pQuorumBaseBlockIndex->GetBlockHash(), relayMembers); + connman.SetMasternodeQuorumRelayMembers(llmqParams.type, pQuorumBaseBlockIndex->GetBlockHash(), connections); } return true; } From 08a3a181f433982c7289f6c2c8eb55e836ef2809 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Mon, 24 Nov 2025 20:32:28 +0300 Subject: [PATCH 5/7] refactor: avoid passing unused `proactive_relay` to `CZMQAbstractNotifier` --- src/zmq/zmqabstractnotifier.cpp | 2 +- src/zmq/zmqabstractnotifier.h | 2 +- src/zmq/zmqnotificationinterface.cpp | 6 +++--- src/zmq/zmqnotificationinterface.h | 2 +- src/zmq/zmqpublishnotifier.cpp | 4 ++-- src/zmq/zmqpublishnotifier.h | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/zmq/zmqabstractnotifier.cpp b/src/zmq/zmqabstractnotifier.cpp index 22781e00fadf..a38921871534 100644 --- a/src/zmq/zmqabstractnotifier.cpp +++ b/src/zmq/zmqabstractnotifier.cpp @@ -68,7 +68,7 @@ bool CZMQAbstractNotifier::NotifyInstantSendDoubleSpendAttempt(const CTransactio return true; } -bool CZMQAbstractNotifier::NotifyRecoveredSig(const std::shared_ptr & /*sig*/, bool /*proactive_relay*/) +bool CZMQAbstractNotifier::NotifyRecoveredSig(const std::shared_ptr & /*sig*/) { return true; } diff --git a/src/zmq/zmqabstractnotifier.h b/src/zmq/zmqabstractnotifier.h index 7284ff3b7e51..6abee4024859 100644 --- a/src/zmq/zmqabstractnotifier.h +++ b/src/zmq/zmqabstractnotifier.h @@ -75,7 +75,7 @@ class CZMQAbstractNotifier virtual bool NotifyGovernanceVote(const std::shared_ptr& tip_mn_list, const std::shared_ptr& vote); virtual bool NotifyGovernanceObject(const std::shared_ptr& object); virtual bool NotifyInstantSendDoubleSpendAttempt(const CTransactionRef& currentTx, const CTransactionRef& previousTx); - virtual bool NotifyRecoveredSig(const std::shared_ptr& sig, bool proactive_relay); + virtual bool NotifyRecoveredSig(const std::shared_ptr& sig); protected: void *psocket; diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp index 1d02e4780d6f..7528e9ac8d77 100644 --- a/src/zmq/zmqnotificationinterface.cpp +++ b/src/zmq/zmqnotificationinterface.cpp @@ -241,10 +241,10 @@ void CZMQNotificationInterface::NotifyInstantSendDoubleSpendAttempt(const CTrans }); } -void CZMQNotificationInterface::NotifyRecoveredSig(const std::shared_ptr& sig, bool proactive_relay) +void CZMQNotificationInterface::NotifyRecoveredSig(const std::shared_ptr& sig, bool /*proactive_relay*/) { - TryForEachAndRemoveFailed(notifiers, [&sig, proactive_relay](CZMQAbstractNotifier* notifier) { - return notifier->NotifyRecoveredSig(sig, proactive_relay); + TryForEachAndRemoveFailed(notifiers, [&sig](CZMQAbstractNotifier* notifier) { + return notifier->NotifyRecoveredSig(sig); }); } diff --git a/src/zmq/zmqnotificationinterface.h b/src/zmq/zmqnotificationinterface.h index ce8c53e86ce7..3f935f407862 100644 --- a/src/zmq/zmqnotificationinterface.h +++ b/src/zmq/zmqnotificationinterface.h @@ -36,7 +36,7 @@ class CZMQNotificationInterface final : public CValidationInterface void NotifyGovernanceVote(const std::shared_ptr& tip_mn_list, const std::shared_ptr& vote) override; void NotifyGovernanceObject(const std::shared_ptr& object) override; void NotifyInstantSendDoubleSpendAttempt(const CTransactionRef& currentTx, const CTransactionRef& previousTx) override; - void NotifyRecoveredSig(const std::shared_ptr& sig, bool proactive_relay) override; + void NotifyRecoveredSig(const std::shared_ptr& sig, bool /*proactive_relay*/) override; private: CZMQNotificationInterface(); diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp index 6c8354bf9fbf..82e0a5660a2f 100644 --- a/src/zmq/zmqpublishnotifier.cpp +++ b/src/zmq/zmqpublishnotifier.cpp @@ -296,7 +296,7 @@ bool CZMQPublishHashInstantSendDoubleSpendNotifier::NotifyInstantSendDoubleSpend && SendZmqMessage(MSG_HASHISCON, dataPreviousHash, 32); } -bool CZMQPublishHashRecoveredSigNotifier::NotifyRecoveredSig(const std::shared_ptr &sig, bool proactive_relay) +bool CZMQPublishHashRecoveredSigNotifier::NotifyRecoveredSig(const std::shared_ptr &sig) { LogPrint(BCLog::ZMQ, "Publish hashrecoveredsig %s to %s\n", sig->getMsgHash().ToString(), this->address); char data[32]; @@ -462,7 +462,7 @@ bool CZMQPublishRawInstantSendDoubleSpendNotifier::NotifyInstantSendDoubleSpendA && SendZmqMessage(MSG_RAWISCON, &(*ssPrevious.begin()), ssPrevious.size()); } -bool CZMQPublishRawRecoveredSigNotifier::NotifyRecoveredSig(const std::shared_ptr& sig, bool proactive_relay) +bool CZMQPublishRawRecoveredSigNotifier::NotifyRecoveredSig(const std::shared_ptr& sig) { LogPrint(BCLog::ZMQ, "Publish rawrecoveredsig %s to %s\n", sig->getMsgHash().ToString(), this->address); diff --git a/src/zmq/zmqpublishnotifier.h b/src/zmq/zmqpublishnotifier.h index f9f32bfe1a5d..2f1803add73f 100644 --- a/src/zmq/zmqpublishnotifier.h +++ b/src/zmq/zmqpublishnotifier.h @@ -81,7 +81,7 @@ class CZMQPublishHashInstantSendDoubleSpendNotifier : public CZMQAbstractPublish class CZMQPublishHashRecoveredSigNotifier : public CZMQAbstractPublishNotifier { public: - bool NotifyRecoveredSig(const std::shared_ptr&, bool proactive_relay) override; + bool NotifyRecoveredSig(const std::shared_ptr&) override; }; class CZMQPublishRawBlockNotifier : public CZMQAbstractPublishNotifier @@ -150,6 +150,6 @@ class CZMQPublishRawInstantSendDoubleSpendNotifier : public CZMQAbstractPublishN class CZMQPublishRawRecoveredSigNotifier : public CZMQAbstractPublishNotifier { public: - bool NotifyRecoveredSig(const std::shared_ptr &sig, bool proactive_relay) override; + bool NotifyRecoveredSig(const std::shared_ptr &sig) override; }; #endif // BITCOIN_ZMQ_ZMQPUBLISHNOTIFIER_H From f18a12e86d1a33461086315ec081ffb803118476 Mon Sep 17 00:00:00 2001 From: pasta Date: Tue, 25 Nov 2025 08:02:28 -0600 Subject: [PATCH 6/7] fix: use llmq/params.h --- src/llmq/signing.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llmq/signing.cpp b/src/llmq/signing.cpp index d2a2f87c7710..6d9163ec63fd 100644 --- a/src/llmq/signing.cpp +++ b/src/llmq/signing.cpp @@ -5,10 +5,10 @@ #include #include +#include #include #include #include -#include #include #include From a58f1bb5b9a4838c66c4dae11e0ab552cc27af0e Mon Sep 17 00:00:00 2001 From: PastaPastaPasta <6443210+PastaPastaPasta@users.noreply.github.com> Date: Sat, 29 Nov 2025 10:42:58 -0600 Subject: [PATCH 7/7] trivial: add a few comments and fix reference location Co-authored-by: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> --- src/llmq/signing.cpp | 2 +- src/llmq/signing.h | 2 +- src/llmq/signing_shares.cpp | 4 ++-- src/validationinterface.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/llmq/signing.cpp b/src/llmq/signing.cpp index 6d9163ec63fd..d4218f04aad7 100644 --- a/src/llmq/signing.cpp +++ b/src/llmq/signing.cpp @@ -518,7 +518,7 @@ void CSigningManager::ProcessPendingReconstructedRecoveredSigs(PeerManager& peer WITH_LOCK(cs_pending, swap(m, pendingReconstructedRecoveredSigs)); for (const auto& p : m) { - ProcessRecoveredSig(p.second, peerman, -1); + ProcessRecoveredSig(p.second, peerman, /*from=*/-1); } } diff --git a/src/llmq/signing.h b/src/llmq/signing.h index 88d426539de6..e37f79093172 100644 --- a/src/llmq/signing.h +++ b/src/llmq/signing.h @@ -220,7 +220,7 @@ class CSigningManager // Used by CSigSharesManager CRecoveredSigsDb& GetDb() { return db; } - void ProcessRecoveredSig(const std::shared_ptr& recoveredSig, PeerManager& peerman, NodeId pFrom) + void ProcessRecoveredSig(const std::shared_ptr& recoveredSig, PeerManager& peerman, NodeId from) EXCLUSIVE_LOCKS_REQUIRED(!cs_pending, !cs_listeners); // Needed for access to GetDb() and ProcessRecoveredSig() diff --git a/src/llmq/signing_shares.cpp b/src/llmq/signing_shares.cpp index eec16b2f9aca..f14116e43383 100644 --- a/src/llmq/signing_shares.cpp +++ b/src/llmq/signing_shares.cpp @@ -844,7 +844,7 @@ void CSigSharesManager::TryRecoverSig(const CQuorum& quorum, const uint256& id, // Handle single-member quorum case after releasing the lock if (singleMemberRecoveredSig) { - sigman.ProcessRecoveredSig(singleMemberRecoveredSig, m_peerman, -1); + sigman.ProcessRecoveredSig(singleMemberRecoveredSig, m_peerman, /*from=*/-1); return; // end of single-quorum processing } @@ -876,7 +876,7 @@ void CSigSharesManager::TryRecoverSig(const CQuorum& quorum, const uint256& id, } } - sigman.ProcessRecoveredSig(rs, m_peerman, -1); + sigman.ProcessRecoveredSig(rs, m_peerman, /*from=*/-1); } CDeterministicMNCPtr CSigSharesManager::SelectMemberForRecovery(const CQuorum& quorum, const uint256 &id, int attempt) diff --git a/src/validationinterface.h b/src/validationinterface.h index faed6347aba7..563133d29cc4 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -236,7 +236,7 @@ class CMainSignals { void NotifyGovernanceVote(const std::shared_ptr& tip_mn_list, const std::shared_ptr& vote, const std::string& id); void NotifyGovernanceObject(const std::shared_ptr& object, const std::string& id); void NotifyInstantSendDoubleSpendAttempt(const CTransactionRef ¤tTx, const CTransactionRef &previousTx); - void NotifyRecoveredSig(const std::shared_ptr &sig, const std::string &id, bool proactive_relay); + void NotifyRecoveredSig(const std::shared_ptr &sig, const std::string& id, bool proactive_relay); void NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff); void ChainStateFlushed(const CBlockLocator &); void BlockChecked(const CBlock&, const BlockValidationState&);