Skip to content

Commit 8a3ad09

Browse files
committed
refactor: abstract away parent implementation from handler
1 parent 718ee50 commit 8a3ad09

File tree

7 files changed

+136
-49
lines changed

7 files changed

+136
-49
lines changed

src/active/quorums.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#include <llmq/commitment.h>
1111
#include <llmq/dkgsessionmgr.h>
1212
#include <llmq/options.h>
13-
#include <llmq/quorumsman.h>
13+
#include <llmq/quorums.h>
1414
#include <llmq/utils.h>
1515
#include <masternode/node.h>
1616
#include <masternode/sync.h>
@@ -26,7 +26,7 @@
2626

2727
namespace llmq {
2828
QuorumParticipant::QuorumParticipant(CBLSWorker& bls_worker, CConnman& connman, CDeterministicMNManager& dmnman,
29-
CQuorumManager& qman, CQuorumSnapshotManager& qsnapman,
29+
QuorumObserverParent& qman, CQuorumSnapshotManager& qsnapman,
3030
const CActiveMasternodeManager& mn_activeman, const ChainstateManager& chainman,
3131
const CMasternodeSync& mn_sync, const CSporkManager& sporkman,
3232
const llmq::QvvecSyncModeMap& sync_map, bool quorums_recovery, bool quorums_watch) :
@@ -121,9 +121,8 @@ MessageProcessingResult QuorumParticipant::ProcessContribQGETDATA(bool request_l
121121
}
122122

123123
std::vector<CBLSIESEncryptedObject<CBLSSecretKey>> vecEncrypted;
124-
if (!m_qman.m_qdkgsman ||
125-
!m_qman.m_qdkgsman->GetEncryptedContributions(request.GetLLMQType(), block_index,
126-
quorum.qc->validMembers, request.GetProTxHash(), vecEncrypted)) {
124+
if (!m_qman.GetEncryptedContributions(request.GetLLMQType(), block_index,
125+
quorum.qc->validMembers, request.GetProTxHash(), vecEncrypted)) {
127126
request.SetError(CQuorumDataRequest::Errors::ENCRYPTED_CONTRIBUTIONS_MISSING);
128127
return request_limit_exceeded ? MisbehavingError{25, "request limit exceeded"} : MessageProcessingResult{};
129128
}

src/active/quorums.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
#define BITCOIN_ACTIVE_QUORUMS_H
77

88
#include <llmq/observer/quorums.h>
9-
#include <llmq/quorumsman.h>
109
#include <llmq/types.h>
1110

1211
#include <consensus/params.h>
@@ -27,14 +26,14 @@ class CDKGSessionManager;
2726
class CNode;
2827
class CSporkManager;
2928
struct MessageProcessingResult;
30-
3129
namespace llmq {
3230
class CQuorum;
3331
class CQuorumDataRequest;
34-
class CQuorumManager;
3532
class CQuorumSnapshotManager;
3633
enum class QvvecSyncMode : int8_t;
34+
} // namespace llmq
3735

36+
namespace llmq {
3837
class QuorumParticipant final : public QuorumObserver
3938
{
4039
private:
@@ -47,7 +46,7 @@ class QuorumParticipant final : public QuorumObserver
4746
QuorumParticipant(const QuorumParticipant&) = delete;
4847
QuorumParticipant& operator=(const QuorumParticipant&) = delete;
4948
explicit QuorumParticipant(CBLSWorker& bls_worker, CConnman& connman, CDeterministicMNManager& dmnman,
50-
CQuorumManager& qman, CQuorumSnapshotManager& qsnapman,
49+
QuorumObserverParent& qman, CQuorumSnapshotManager& qsnapman,
5150
const CActiveMasternodeManager& mn_activeman, const ChainstateManager& chainman,
5251
const CMasternodeSync& mn_sync, const CSporkManager& sporkman,
5352
const llmq::QvvecSyncModeMap& sync_map, bool quorums_recovery, bool quorums_watch);

src/chainlock/chainlock.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ namespace llmq {
3838
class CInstantSendManager;
3939
class CQuorumManager;
4040
class CSigningManager;
41-
enum class VerifyRecSigStatus;
41+
enum class VerifyRecSigStatus : uint8_t;
4242

4343
class CChainLocksHandler final : public chainlock::ChainLockSignerParent
4444
{

src/llmq/observer/quorums.cpp

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77
#include <evo/deterministicmns.h>
88
#include <llmq/commitment.h>
99
#include <llmq/options.h>
10-
#include <llmq/quorumsman.h>
10+
#include <llmq/quorums.h>
1111
#include <llmq/utils.h>
1212
#include <masternode/sync.h>
13+
#include <msg_result.h>
14+
#include <unordered_lru_cache.h>
1315

1416
#include <chain.h>
1517
#include <chainparams.h>
@@ -20,7 +22,7 @@
2022
#include <cxxtimer.hpp>
2123

2224
namespace llmq {
23-
QuorumObserver::QuorumObserver(CConnman& connman, CDeterministicMNManager& dmnman, CQuorumManager& qman,
25+
QuorumObserver::QuorumObserver(CConnman& connman, CDeterministicMNManager& dmnman, QuorumObserverParent& qman,
2426
CQuorumSnapshotManager& qsnapman, const ChainstateManager& chainman,
2527
const CMasternodeSync& mn_sync, const CSporkManager& sporkman,
2628
const llmq::QvvecSyncModeMap& sync_map, bool quorums_recovery) :
@@ -66,18 +68,8 @@ void QuorumObserver::UpdatedBlockTip(const CBlockIndex* pindexNew, bool fInitial
6668
CheckQuorumConnections(params, pindexNew);
6769
}
6870

69-
{
70-
// Cleanup expired data requests
71-
LOCK(m_qman.cs_data_requests);
72-
auto it = m_qman.mapQuorumDataRequests.begin();
73-
while (it != m_qman.mapQuorumDataRequests.end()) {
74-
if (it->second.IsExpired(/*add_bias=*/true)) {
75-
it = m_qman.mapQuorumDataRequests.erase(it);
76-
} else {
77-
++it;
78-
}
79-
}
80-
}
71+
// Cleanup expired data requests
72+
m_qman.CleanupExpiredDataRequests();
8173

8274
TriggerQuorumDataRecoveryThreads(pindexNew);
8375
StartCleanupOldQuorumDataThread(pindexNew);
@@ -230,14 +222,10 @@ void QuorumObserver::DataRecoveryThread(gsl::not_null<const CBlockIndex*> block_
230222
}
231223
// Access the member list of the quorum with the calculated offset applied to balance the load equally
232224
pCurrentMemberHash = &vecMemberHashes[(start_offset + nTries++) % vecMemberHashes.size()];
233-
{
234-
LOCK(m_qman.cs_data_requests);
235-
const CQuorumDataRequestKey key(*pCurrentMemberHash, true, pQuorum->qc->quorumHash, pQuorum->qc->llmqType);
236-
auto it = m_qman.mapQuorumDataRequests.find(key);
237-
if (it != m_qman.mapQuorumDataRequests.end() && !it->second.IsExpired(/*add_bias=*/true)) {
238-
printLog("Already asked");
239-
continue;
240-
}
225+
if (m_qman.IsDataRequestPending(*pCurrentMemberHash, /*we_requested=*/true, pQuorum->qc->quorumHash,
226+
pQuorum->qc->llmqType)) {
227+
printLog("Already asked");
228+
continue;
241229
}
242230
// Sleep a bit depending on the start offset to balance out multiple requests to same masternode
243231
quorumThreadInterrupt.sleep_for(std::chrono::milliseconds(start_offset * 100));
@@ -256,20 +244,20 @@ void QuorumObserver::DataRecoveryThread(gsl::not_null<const CBlockIndex*> block_
256244
nTimeLastSuccess = GetTime<std::chrono::seconds>().count();
257245
printLog("Requested");
258246
} else {
259-
LOCK(m_qman.cs_data_requests);
260-
const CQuorumDataRequestKey key(*pCurrentMemberHash, true, pQuorum->qc->quorumHash, pQuorum->qc->llmqType);
261-
auto it = m_qman.mapQuorumDataRequests.find(key);
262-
if (it == m_qman.mapQuorumDataRequests.end()) {
247+
const auto status = m_qman.GetDataRequestStatus(*pCurrentMemberHash, /*we_requested=*/true,
248+
pQuorum->qc->quorumHash, pQuorum->qc->llmqType);
249+
switch (status) {
250+
case DataRequestStatus::NotFound:
263251
printLog("Failed");
264252
pNode->fDisconnect = true;
265253
pCurrentMemberHash = nullptr;
266254
return;
267-
} else if (it->second.IsProcessed()) {
255+
case DataRequestStatus::Processed:
268256
printLog("Processed");
269257
pNode->fDisconnect = true;
270258
pCurrentMemberHash = nullptr;
271259
return;
272-
} else {
260+
case DataRequestStatus::Pending:
273261
printLog("Waiting");
274262
return;
275263
}
@@ -376,7 +364,7 @@ void QuorumObserver::StartCleanupOldQuorumDataThread(gsl::not_null<const CBlockI
376364
}
377365

378366
if (!quorumThreadInterrupt) {
379-
WITH_LOCK(m_qman.cs_db, DataCleanupHelper(*m_qman.db, dbKeysToSkip));
367+
m_qman.CleanupOldQuorumData(dbKeysToSkip);
380368
}
381369

382370
LogPrint(BCLog::LLMQ, "QuorumObserver::StartCleanupOldQuorumDataThread -- done. time=%d\n", t.count());

src/llmq/observer/quorums.h

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
#ifndef BITCOIN_LLMQ_OBSERVER_QUORUMS_H
66
#define BITCOIN_LLMQ_OBSERVER_QUORUMS_H
77

8+
#include <bls/bls_ies.h>
89
#include <ctpl_stl.h>
9-
#include <llmq/quorumsman.h>
10+
#include <llmq/options.h>
1011
#include <llmq/types.h>
1112

1213
#include <consensus/params.h>
@@ -15,24 +16,58 @@
1516
#include <sync.h>
1617
#include <threadsafety.h>
1718
#include <uint256.h>
19+
#include <util/threadinterrupt.h>
1820

1921
#include <gsl/pointers.h>
2022

2123
#include <map>
24+
#include <set>
2225

2326
class CConnman;
27+
class CDataStream;
28+
class CDeterministicMNManager;
29+
class CMasternodeSync;
30+
class CNode;
31+
class CSporkManager;
2432
struct MessageProcessingResult;
33+
namespace llmq {
34+
class CQuorumDataRequest;
35+
class CQuorumSnapshotManager;
36+
} // namespace llmq
2537

2638
namespace llmq {
27-
class CQuorumManager;
28-
enum class QvvecSyncMode : int8_t;
39+
enum class DataRequestStatus : uint8_t {
40+
NotFound,
41+
Pending,
42+
Processed,
43+
};
44+
45+
class QuorumObserverParent
46+
{
47+
public:
48+
virtual ~QuorumObserverParent() = default;
49+
virtual bool GetEncryptedContributions(Consensus::LLMQType llmq_type, const CBlockIndex* block_index,
50+
const std::vector<bool>& valid_members, const uint256& protx_hash,
51+
std::vector<CBLSIESEncryptedObject<CBLSSecretKey>>& vec_enc) const = 0;
52+
virtual bool IsDataRequestPending(const uint256& proRegTx, bool we_requested, const uint256& quorumHash,
53+
Consensus::LLMQType llmqType) const = 0;
54+
virtual bool RequestQuorumData(CNode* pfrom, CConnman& connman, const CQuorum& quorum, uint16_t nDataMask,
55+
const uint256& proTxHash) const = 0;
56+
virtual DataRequestStatus GetDataRequestStatus(const uint256& proRegTx, bool we_requested,
57+
const uint256& quorumHash, Consensus::LLMQType llmqType) const = 0;
58+
virtual std::vector<CQuorumCPtr> ScanQuorums(Consensus::LLMQType llmqType,
59+
gsl::not_null<const CBlockIndex*> pindexStart,
60+
size_t nCountRequested) const = 0;
61+
virtual void CleanupExpiredDataRequests() const = 0;
62+
virtual void CleanupOldQuorumData(const std::set<uint256>& dbKeysToSkip) const = 0;
63+
};
2964

3065
class QuorumObserver
3166
{
3267
protected:
3368
CConnman& m_connman;
3469
CDeterministicMNManager& m_dmnman;
35-
CQuorumManager& m_qman;
70+
QuorumObserverParent& m_qman;
3671
CQuorumSnapshotManager& m_qsnapman;
3772
const ChainstateManager& m_chainman;
3873
const CMasternodeSync& m_mn_sync;
@@ -51,7 +86,7 @@ class QuorumObserver
5186
QuorumObserver() = delete;
5287
QuorumObserver(const QuorumObserver&) = delete;
5388
QuorumObserver& operator=(const QuorumObserver&) = delete;
54-
explicit QuorumObserver(CConnman& connman, CDeterministicMNManager& dmnman, CQuorumManager& qman,
89+
explicit QuorumObserver(CConnman& connman, CDeterministicMNManager& dmnman, QuorumObserverParent& qman,
5590
CQuorumSnapshotManager& qsnapman, const ChainstateManager& chainman,
5691
const CMasternodeSync& mn_sync, const CSporkManager& sporkman,
5792
const llmq::QvvecSyncModeMap& sync_map, bool quorums_recovery);

src/llmq/quorumsman.cpp

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
#include <llmq/quorumsman.h>
66

7-
#include <active/quorums.h>
87
#include <bls/bls.h>
98
#include <bls/bls_ies.h>
109
#include <evo/deterministicmns.h>
@@ -54,6 +53,16 @@ CQuorumManager::~CQuorumManager()
5453
}
5554
}
5655

56+
bool CQuorumManager::GetEncryptedContributions(Consensus::LLMQType llmq_type, const CBlockIndex* block_index,
57+
const std::vector<bool>& valid_members, const uint256& protx_hash,
58+
std::vector<CBLSIESEncryptedObject<CBLSSecretKey>>& vec_enc) const
59+
{
60+
if (m_qdkgsman) {
61+
return m_qdkgsman->GetEncryptedContributions(llmq_type, block_index, valid_members, protx_hash, vec_enc);
62+
}
63+
return false;
64+
}
65+
5766
CQuorumPtr CQuorumManager::BuildQuorumFromCommitment(const Consensus::LLMQType llmqType, gsl::not_null<const CBlockIndex*> pQuorumBaseBlockIndex, bool populate_cache) const
5867
{
5968
const uint256& quorumHash{pQuorumBaseBlockIndex->GetBlockHash()};
@@ -313,6 +322,49 @@ bool CQuorumManager::IsWatching() const
313322
return false;
314323
}
315324

325+
bool CQuorumManager::IsDataRequestPending(const uint256& proRegTx, bool we_requested, const uint256& quorumHash,
326+
Consensus::LLMQType llmqType) const
327+
{
328+
const CQuorumDataRequestKey key{proRegTx, we_requested, quorumHash, llmqType};
329+
LOCK(cs_data_requests);
330+
const auto it = mapQuorumDataRequests.find(key);
331+
return it != mapQuorumDataRequests.end() && !it->second.IsExpired(/*add_bias=*/true);
332+
}
333+
334+
DataRequestStatus CQuorumManager::GetDataRequestStatus(const uint256& proRegTx, bool we_requested,
335+
const uint256& quorumHash, Consensus::LLMQType llmqType) const
336+
{
337+
const CQuorumDataRequestKey key{proRegTx, we_requested, quorumHash, llmqType};
338+
LOCK(cs_data_requests);
339+
const auto it = mapQuorumDataRequests.find(key);
340+
if (it == mapQuorumDataRequests.end()) {
341+
return DataRequestStatus::NotFound;
342+
}
343+
if (it->second.IsProcessed()) {
344+
return DataRequestStatus::Processed;
345+
}
346+
return DataRequestStatus::Pending;
347+
}
348+
349+
void CQuorumManager::CleanupExpiredDataRequests() const
350+
{
351+
LOCK(cs_data_requests);
352+
auto it = mapQuorumDataRequests.begin();
353+
while (it != mapQuorumDataRequests.end()) {
354+
if (it->second.IsExpired(/*add_bias=*/true)) {
355+
it = mapQuorumDataRequests.erase(it);
356+
} else {
357+
++it;
358+
}
359+
}
360+
}
361+
362+
void CQuorumManager::CleanupOldQuorumData(const std::set<uint256>& dbKeysToSkip) const
363+
{
364+
LOCK(cs_db);
365+
DataCleanupHelper(*db, dbKeysToSkip);
366+
}
367+
316368
CQuorumCPtr CQuorumManager::GetQuorum(Consensus::LLMQType llmqType, const uint256& quorumHash) const
317369
{
318370
const CBlockIndex* pQuorumBaseBlockIndex = [&]() {

src/llmq/quorumsman.h

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#define BITCOIN_LLMQ_QUORUMSMAN_H
77

88
#include <evo/types.h>
9+
#include <llmq/observer/quorums.h>
910
#include <llmq/options.h>
1011
#include <llmq/params.h>
1112
#include <llmq/quorums.h>
@@ -42,7 +43,7 @@ struct DbWrapperParams;
4243
} // namespace util
4344

4445
namespace llmq {
45-
enum class VerifyRecSigStatus {
46+
enum class VerifyRecSigStatus : uint8_t {
4647
NoQuorum,
4748
Invalid,
4849
Valid,
@@ -60,7 +61,7 @@ class QuorumParticipant;
6061
*
6162
* It is also responsible for initialization of the intra-quorum connections for new quorums.
6263
*/
63-
class CQuorumManager
64+
class CQuorumManager final : public QuorumObserverParent
6465
{
6566
friend class llmq::QuorumObserver;
6667
friend class llmq::QuorumParticipant;
@@ -123,14 +124,19 @@ class CQuorumManager
123124
m_qdkgsman = nullptr;
124125
}
125126

127+
bool GetEncryptedContributions(Consensus::LLMQType llmq_type, const CBlockIndex* block_index,
128+
const std::vector<bool>& valid_members, const uint256& protx_hash,
129+
std::vector<CBLSIESEncryptedObject<CBLSSecretKey>>& vec_enc) const override;
130+
126131
[[nodiscard]] MessageProcessingResult ProcessMessage(CNode& pfrom, CConnman& connman, std::string_view msg_type,
127132
CDataStream& vRecv)
128133
EXCLUSIVE_LOCKS_REQUIRED(!cs_db, !cs_data_requests, !cs_map_quorums, !m_cache_cs);
129134

130135
static bool HasQuorum(Consensus::LLMQType llmqType, const CQuorumBlockProcessor& quorum_block_processor, const uint256& quorumHash);
131136

132137
bool RequestQuorumData(CNode* pfrom, CConnman& connman, const CQuorum& quorum, uint16_t nDataMask,
133-
const uint256& proTxHash = uint256()) const EXCLUSIVE_LOCKS_REQUIRED(!cs_data_requests);
138+
const uint256& proTxHash = uint256()) const override
139+
EXCLUSIVE_LOCKS_REQUIRED(!cs_data_requests);
134140

135141
// all these methods will lock cs_main for a short period of time
136142
CQuorumCPtr GetQuorum(Consensus::LLMQType llmqType, const uint256& quorumHash) const
@@ -140,12 +146,20 @@ class CQuorumManager
140146

141147
// this one is cs_main-free
142148
std::vector<CQuorumCPtr> ScanQuorums(Consensus::LLMQType llmqType, gsl::not_null<const CBlockIndex*> pindexStart,
143-
size_t nCountRequested) const
149+
size_t nCountRequested) const override
144150
EXCLUSIVE_LOCKS_REQUIRED(!cs_db, !cs_map_quorums, !cs_scan_quorums, !m_cache_cs);
145151

146152
bool IsMasternode() const;
147153
bool IsWatching() const;
148154

155+
bool IsDataRequestPending(const uint256& proRegTx, bool we_requested, const uint256& quorumHash,
156+
Consensus::LLMQType llmqType) const override EXCLUSIVE_LOCKS_REQUIRED(!cs_data_requests);
157+
DataRequestStatus GetDataRequestStatus(const uint256& proRegTx, bool we_requested, const uint256& quorumHash,
158+
Consensus::LLMQType llmqType) const override
159+
EXCLUSIVE_LOCKS_REQUIRED(!cs_data_requests);
160+
void CleanupExpiredDataRequests() const override EXCLUSIVE_LOCKS_REQUIRED(!cs_data_requests);
161+
void CleanupOldQuorumData(const std::set<uint256>& dbKeysToSkip) const override EXCLUSIVE_LOCKS_REQUIRED(!cs_db);
162+
149163
private:
150164
// all private methods here are cs_main-free
151165
bool BuildQuorumContributions(const CFinalCommitmentPtr& fqc, const std::shared_ptr<CQuorum>& quorum) const;

0 commit comments

Comments
 (0)