Skip to content

Commit 3bdb9ce

Browse files
feat: proactively relay recovered signatures when we are the member who performed recovery
1 parent cdde1b2 commit 3bdb9ce

16 files changed

+51
-33
lines changed

src/llmq/signing.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
#include <algorithm>
2626
#include <unordered_set>
2727

28+
#include "options.h"
29+
2830
namespace llmq
2931
{
3032
CRecoveredSigsDb::CRecoveredSigsDb(const util::DbWrapperParams& db_params) :
@@ -508,7 +510,7 @@ void CSigningManager::ProcessPendingReconstructedRecoveredSigs(PeerManager& peer
508510
WITH_LOCK(cs_pending, swap(m, pendingReconstructedRecoveredSigs));
509511

510512
for (const auto& p : m) {
511-
ProcessRecoveredSig(p.second, peerman);
513+
ProcessRecoveredSig(p.second, peerman, -1);
512514
}
513515
}
514516

@@ -570,15 +572,15 @@ bool CSigningManager::ProcessPendingRecoveredSigs(PeerManager& peerman)
570572
continue;
571573
}
572574

573-
ProcessRecoveredSig(recSig, peerman);
575+
ProcessRecoveredSig(recSig, peerman, nodeId);
574576
}
575577
}
576578

577579
return recSigsByNode.size() >= nMaxBatchSize;
578580
}
579581

580582
// signature must be verified already
581-
void CSigningManager::ProcessRecoveredSig(const std::shared_ptr<const CRecoveredSig>& recoveredSig, PeerManager& peerman)
583+
void CSigningManager::ProcessRecoveredSig(const std::shared_ptr<const CRecoveredSig>& recoveredSig, PeerManager& peerman, NodeId from)
582584
{
583585
auto llmqType = recoveredSig->getLlmqType();
584586

@@ -621,7 +623,12 @@ void CSigningManager::ProcessRecoveredSig(const std::shared_ptr<const CRecovered
621623
peerman.PostProcessMessage(l->HandleNewRecoveredSig(*recoveredSig));
622624
}
623625

624-
GetMainSignals().NotifyRecoveredSig(recoveredSig, recoveredSig->GetHash().ToString());
626+
// TODO refactor to use a better abstraction analogous to IsAllMembersConnectedEnabled
627+
auto proactive_relay = from == -1 &&
628+
llmqType != Consensus::LLMQType::LLMQ_100_67 &&
629+
llmqType != Consensus::LLMQType::LLMQ_400_60 &&
630+
llmqType != Consensus::LLMQType::LLMQ_400_85;
631+
GetMainSignals().NotifyRecoveredSig(recoveredSig, recoveredSig->GetHash().ToString(), proactive_relay);
625632
}
626633

627634
void CSigningManager::PushReconstructedRecoveredSig(const std::shared_ptr<const llmq::CRecoveredSig>& recoveredSig)

src/llmq/signing.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ class CSigningManager
219219

220220
// Used by CSigSharesManager
221221
CRecoveredSigsDb& GetDb() { return db; }
222-
void ProcessRecoveredSig(const std::shared_ptr<const CRecoveredSig>& recoveredSig, PeerManager& peerman)
222+
void ProcessRecoveredSig(const std::shared_ptr<const CRecoveredSig>& recoveredSig, PeerManager& peerman, NodeId pFrom)
223223
EXCLUSIVE_LOCKS_REQUIRED(!cs_pending, !cs_listeners);
224224

225225
// Needed for access to GetDb() and ProcessRecoveredSig()

src/llmq/signing_shares.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -807,7 +807,7 @@ void CSigSharesManager::TryRecoverSig(const CQuorum& quorum, const uint256& id,
807807

808808
auto rs = std::make_shared<CRecoveredSig>(quorum.params.type, quorum.qc->quorumHash, id, msgHash,
809809
recoveredSig);
810-
sigman.ProcessRecoveredSig(rs, m_peerman);
810+
sigman.ProcessRecoveredSig(rs, m_peerman, -1);
811811
return; // end of single-quorum processing
812812
}
813813

@@ -853,7 +853,7 @@ void CSigSharesManager::TryRecoverSig(const CQuorum& quorum, const uint256& id,
853853
}
854854
}
855855

856-
sigman.ProcessRecoveredSig(rs, m_peerman);
856+
sigman.ProcessRecoveredSig(rs, m_peerman, -1);
857857
}
858858

859859
CDeterministicMNCPtr CSigSharesManager::SelectMemberForRecovery(const CQuorum& quorum, const uint256 &id, int attempt)
@@ -951,9 +951,9 @@ bool CSigSharesManager::AsyncSignIfMember(Consensus::LLMQType llmqType, CSigning
951951
return true;
952952
}
953953

954-
void CSigSharesManager::NotifyRecoveredSig(const std::shared_ptr<const CRecoveredSig>& sig) const
954+
void CSigSharesManager::NotifyRecoveredSig(const std::shared_ptr<const CRecoveredSig>& sig, bool proactive_relay) const
955955
{
956-
m_peerman.RelayRecoveredSig(Assert(sig)->GetHash());
956+
m_peerman.RelayRecoveredSig(*Assert(sig), proactive_relay);
957957
}
958958

959959
void CSigSharesManager::CollectSigSharesToRequest(std::unordered_map<NodeId, Uint256HashMap<CSigSharesInv>>& sigSharesToRequest)

src/llmq/signing_shares.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ class CSigSharesManager : public CRecoveredSigsListener
446446
bool allowDiffMsgHashSigning = false)
447447
EXCLUSIVE_LOCKS_REQUIRED(!cs_pendingSigns);
448448

449-
void NotifyRecoveredSig(const std::shared_ptr<const CRecoveredSig>& sig) const;
449+
void NotifyRecoveredSig(const std::shared_ptr<const CRecoveredSig>& sig, bool proactive_relay) const;
450450

451451
private:
452452
// all of these return false when the currently processed message should be aborted (as each message actually contains multiple messages)

src/masternode/active/notificationinterface.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ void ActiveNotificationInterface::UpdatedBlockTip(const CBlockIndex* pindexNew,
2929
m_active_ctx.gov_signer->UpdatedBlockTip(pindexNew);
3030
}
3131

32-
void ActiveNotificationInterface::NotifyRecoveredSig(const std::shared_ptr<const llmq::CRecoveredSig>& sig)
32+
void ActiveNotificationInterface::NotifyRecoveredSig(const std::shared_ptr<const llmq::CRecoveredSig>& sig, bool proactive_relay)
3333
{
34-
m_active_ctx.shareman->NotifyRecoveredSig(sig);
34+
m_active_ctx.shareman->NotifyRecoveredSig(sig, proactive_relay);
3535
}
3636

3737
std::unique_ptr<ActiveNotificationInterface> g_active_notification_interface;

src/masternode/active/notificationinterface.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class ActiveNotificationInterface final : public CValidationInterface
2626

2727
protected:
2828
// CValidationInterface
29-
void NotifyRecoveredSig(const std::shared_ptr<const llmq::CRecoveredSig>& sig) override;
29+
void NotifyRecoveredSig(const std::shared_ptr<const llmq::CRecoveredSig>& sig, bool proactive_relay) override;
3030
void UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, bool fInitialDownload) override;
3131

3232
private:

src/net_processing.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,7 @@ class PeerManagerImpl final : public PeerManager
627627
void RelayInv(const CInv& inv) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
628628
void RelayInv(const CInv& inv, const int minProtoVersion) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
629629
void RelayTransaction(const uint256& txid) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
630-
void RelayRecoveredSig(const uint256& sigHash) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
630+
void RelayRecoveredSig(const llmq::CRecoveredSig& sig, bool proactive_relay) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
631631
void RelayDSQ(const CCoinJoinQueue& queue) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
632632
void SetBestHeight(int height) override { m_best_height = height; };
633633
void Misbehaving(const NodeId pnode, const int howmuch, const std::string& message = "") override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
@@ -2467,9 +2467,20 @@ void PeerManagerImpl::_RelayTransaction(const uint256& txid)
24672467
};
24682468
}
24692469

2470-
void PeerManagerImpl::RelayRecoveredSig(const uint256& sigHash)
2471-
{
2472-
const CInv inv{MSG_QUORUM_RECOVERED_SIG, sigHash};
2470+
void PeerManagerImpl::RelayRecoveredSig(const llmq::CRecoveredSig& sig, bool proactive_relay) {
2471+
if (proactive_relay) {
2472+
// We were the peer that recovered this; avoid a bunch of `inv` -> `GetData` spam by proactively sending
2473+
m_connman.ForEachNode([this, &sig](CNode* pnode) -> bool {
2474+
// Skip nodes that don't want recovered signatures
2475+
PeerRef peer = GetPeerRef(pnode->GetId());
2476+
if (peer == nullptr || !peer->m_wants_recsigs) return true;
2477+
CNetMsgMaker msgMaker(pnode->GetCommonVersion());
2478+
m_connman.PushMessage(pnode, msgMaker.Make(NetMsgType::QSIGREC, sig));
2479+
return true;
2480+
});
2481+
return;
2482+
}
2483+
const CInv inv{MSG_QUORUM_RECOVERED_SIG, sig.GetHash()};
24732484
READ_LOCK(m_peer_mutex);
24742485
for (const auto& [_, peer] : m_peer_map) {
24752486
if (peer->m_wants_recsigs) {

src/net_processing.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ class PeerManager : public CValidationInterface, public NetEventsInterface
104104
virtual void RelayTransaction(const uint256& txid) = 0;
105105

106106
/** Relay recovered sigs to all interested peers */
107-
virtual void RelayRecoveredSig(const uint256& sigHash) = 0;
107+
virtual void RelayRecoveredSig(const llmq::CRecoveredSig& sig, bool proactive_relay) = 0;
108108

109109
/** Set the best height */
110110
virtual void SetBestHeight(int height) = 0;

src/validationinterface.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -312,9 +312,9 @@ void CMainSignals::NotifyInstantSendDoubleSpendAttempt(const CTransactionRef& cu
312312
previousTx->GetHash().ToString());
313313
}
314314

315-
void CMainSignals::NotifyRecoveredSig(const std::shared_ptr<const llmq::CRecoveredSig>& sig, const std::string& id) {
316-
auto event = [sig, this] {
317-
m_internals->Iterate([&](CValidationInterface& callbacks) { callbacks.NotifyRecoveredSig(sig); });
315+
void CMainSignals::NotifyRecoveredSig(const std::shared_ptr<const llmq::CRecoveredSig>& sig, const std::string& id, bool proactive_relay) {
316+
auto event = [sig, proactive_relay, this] {
317+
m_internals->Iterate([&](CValidationInterface& callbacks) { callbacks.NotifyRecoveredSig(sig, proactive_relay); });
318318
};
319319
ENQUEUE_AND_LOG_EVENT(event, "%s: notify recoveredsig=%s", __func__,
320320
id);

src/validationinterface.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ class CValidationInterface {
168168
virtual void NotifyGovernanceVote(const std::shared_ptr<CDeterministicMNList>& tip_mn_list, const std::shared_ptr<const CGovernanceVote>& vote) {}
169169
virtual void NotifyGovernanceObject(const std::shared_ptr<const Governance::Object>& object) {}
170170
virtual void NotifyInstantSendDoubleSpendAttempt(const CTransactionRef& currentTx, const CTransactionRef& previousTx) {}
171-
virtual void NotifyRecoveredSig(const std::shared_ptr<const llmq::CRecoveredSig>& sig) {}
171+
virtual void NotifyRecoveredSig(const std::shared_ptr<const llmq::CRecoveredSig>& sig, bool proactive_relay) {}
172172
virtual void NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff) {}
173173
/**
174174
* Notifies listeners of the new active block chain on-disk.
@@ -236,7 +236,7 @@ class CMainSignals {
236236
void NotifyGovernanceVote(const std::shared_ptr<CDeterministicMNList>& tip_mn_list, const std::shared_ptr<const CGovernanceVote>& vote, const std::string& id);
237237
void NotifyGovernanceObject(const std::shared_ptr<const Governance::Object>& object, const std::string& id);
238238
void NotifyInstantSendDoubleSpendAttempt(const CTransactionRef &currentTx, const CTransactionRef &previousTx);
239-
void NotifyRecoveredSig(const std::shared_ptr<const llmq::CRecoveredSig> &sig, const std::string& id);
239+
void NotifyRecoveredSig(const std::shared_ptr<const llmq::CRecoveredSig> &sig, const std::string &id, bool proactive_relay);
240240
void NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff);
241241
void ChainStateFlushed(const CBlockLocator &);
242242
void BlockChecked(const CBlock&, const BlockValidationState&);

0 commit comments

Comments
 (0)