Skip to content

Commit 25c87e4

Browse files
committed
refactor: abstract away parent implementation from handler
1 parent a492068 commit 25c87e4

7 files changed

Lines changed: 136 additions & 49 deletions

File tree

src/active/quorums.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#include <llmq/commitment.h>
1010
#include <llmq/dkgsessionmgr.h>
1111
#include <llmq/options.h>
12-
#include <llmq/quorumsman.h>
12+
#include <llmq/quorums.h>
1313
#include <llmq/utils.h>
1414
#include <masternode/node.h>
1515
#include <masternode/sync.h>
@@ -25,7 +25,7 @@
2525

2626
namespace llmq {
2727
QuorumParticipant::QuorumParticipant(CBLSWorker& bls_worker, CConnman& connman, CDeterministicMNManager& dmnman,
28-
CQuorumManager& qman, CQuorumSnapshotManager& qsnapman,
28+
QuorumHandlerParent& qman, CQuorumSnapshotManager& qsnapman,
2929
const CActiveMasternodeManager& mn_activeman, const ChainstateManager& chainman,
3030
const CMasternodeSync& mn_sync, const CSporkManager& sporkman,
3131
const llmq::QvvecSyncModeMap& sync_map, bool quorums_recovery, bool quorums_watch) :
@@ -123,9 +123,8 @@ MessageProcessingResult QuorumParticipant::ProcessEncryptedContribs(CNode& pfrom
123123
}
124124

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

src/active/quorums.h

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

88
#include <bls/bls.h>
99
#include <llmq/observer/quorums.h>
10-
#include <llmq/quorumsman.h>
1110
#include <llmq/types.h>
1211
#include <msg_result.h>
1312

@@ -28,14 +27,14 @@ class CDeterministicMNManager;
2827
class CDKGSessionManager;
2928
class CNode;
3029
class CSporkManager;
31-
3230
namespace llmq {
3331
class CQuorum;
3432
class CQuorumDataRequest;
35-
class CQuorumManager;
3633
class CQuorumSnapshotManager;
3734
enum class QvvecSyncMode : int8_t;
35+
} // namespace llmq
3836

37+
namespace llmq {
3938
class QuorumParticipant final : public QuorumObserver
4039
{
4140
private:
@@ -48,7 +47,7 @@ class QuorumParticipant final : public QuorumObserver
4847
QuorumParticipant(const QuorumParticipant&) = delete;
4948
QuorumParticipant& operator=(const QuorumParticipant&) = delete;
5049
explicit QuorumParticipant(CBLSWorker& bls_worker, CConnman& connman, CDeterministicMNManager& dmnman,
51-
CQuorumManager& qman, CQuorumSnapshotManager& qsnapman,
50+
QuorumHandlerParent& qman, CQuorumSnapshotManager& qsnapman,
5251
const CActiveMasternodeManager& mn_activeman, const ChainstateManager& chainman,
5352
const CMasternodeSync& mn_sync, const CSporkManager& sporkman,
5453
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: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
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 <unordered_lru_cache.h>
1314

1415
#include <chain.h>
1516
#include <chainparams.h>
@@ -20,7 +21,7 @@
2021
#include <cxxtimer.hpp>
2122

2223
namespace llmq {
23-
QuorumObserver::QuorumObserver(CConnman& connman, CDeterministicMNManager& dmnman, CQuorumManager& qman,
24+
QuorumObserver::QuorumObserver(CConnman& connman, CDeterministicMNManager& dmnman, QuorumHandlerParent& qman,
2425
CQuorumSnapshotManager& qsnapman, const ChainstateManager& chainman,
2526
const CMasternodeSync& mn_sync, const CSporkManager& sporkman,
2627
const llmq::QvvecSyncModeMap& sync_map, bool quorums_recovery) :
@@ -66,18 +67,8 @@ void QuorumObserver::UpdatedBlockTip(const CBlockIndex* pindexNew, bool fInitial
6667
CheckQuorumConnections(params, pindexNew);
6768
}
6869

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-
}
70+
// Cleanup expired data requests
71+
m_qman.CleanupExpiredDataRequests();
8172

8273
TriggerQuorumDataRecoveryThreads(pindexNew);
8374
StartCleanupOldQuorumDataThread(pindexNew);
@@ -231,14 +222,10 @@ void QuorumObserver::DataRecoveryThread(gsl::not_null<const CBlockIndex*> block_
231222
}
232223
// Access the member list of the quorum with the calculated offset applied to balance the load equally
233224
pCurrentMemberHash = &vecMemberHashes[(start_offset + nTries++) % vecMemberHashes.size()];
234-
{
235-
LOCK(m_qman.cs_data_requests);
236-
const CQuorumDataRequestKey key(*pCurrentMemberHash, true, pQuorum->qc->quorumHash, pQuorum->qc->llmqType);
237-
auto it = m_qman.mapQuorumDataRequests.find(key);
238-
if (it != m_qman.mapQuorumDataRequests.end() && !it->second.IsExpired(/*add_bias=*/true)) {
239-
printLog("Already asked");
240-
continue;
241-
}
225+
if (m_qman.IsDataRequestPending(*pCurrentMemberHash, /*we_requested=*/true, pQuorum->qc->quorumHash,
226+
pQuorum->qc->llmqType)) {
227+
printLog("Already asked");
228+
continue;
242229
}
243230
// Sleep a bit depending on the start offset to balance out multiple requests to same masternode
244231
quorumThreadInterrupt.sleep_for(std::chrono::milliseconds(start_offset * 100));
@@ -257,20 +244,20 @@ void QuorumObserver::DataRecoveryThread(gsl::not_null<const CBlockIndex*> block_
257244
nTimeLastSuccess = GetTime<std::chrono::seconds>().count();
258245
printLog("Requested");
259246
} else {
260-
LOCK(m_qman.cs_data_requests);
261-
const CQuorumDataRequestKey key(*pCurrentMemberHash, true, pQuorum->qc->quorumHash, pQuorum->qc->llmqType);
262-
auto it = m_qman.mapQuorumDataRequests.find(key);
263-
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:
264251
printLog("Failed");
265252
pNode->fDisconnect = true;
266253
pCurrentMemberHash = nullptr;
267254
return;
268-
} else if (it->second.IsProcessed()) {
255+
case DataRequestStatus::Processed:
269256
printLog("Processed");
270257
pNode->fDisconnect = true;
271258
pCurrentMemberHash = nullptr;
272259
return;
273-
} else {
260+
case DataRequestStatus::Pending:
274261
printLog("Waiting");
275262
return;
276263
}
@@ -377,7 +364,7 @@ void QuorumObserver::StartCleanupOldQuorumDataThread(gsl::not_null<const CBlockI
377364
}
378365

379366
if (!quorumThreadInterrupt) {
380-
WITH_LOCK(m_qman.cs_db, DataCleanupHelper(*m_qman.db, dbKeysToSkip));
367+
m_qman.CleanupOldQuorumData(dbKeysToSkip);
381368
}
382369

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

src/llmq/observer/quorums.h

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
#define BITCOIN_LLMQ_OBSERVER_QUORUMS_H
77

88
#include <bls/bls.h>
9-
#include <llmq/quorumsman.h>
9+
#include <bls/bls_ies.h>
10+
#include <llmq/options.h>
1011
#include <llmq/types.h>
1112
#include <msg_result.h>
1213

@@ -16,23 +17,58 @@
1617
#include <sync.h>
1718
#include <threadsafety.h>
1819
#include <uint256.h>
20+
#include <util/threadinterrupt.h>
1921

2022
#include <ctpl_stl.h>
23+
#include <gsl/pointers.h>
2124

2225
#include <map>
26+
#include <set>
2327

2428
class CConnman;
29+
class CDataStream;
30+
class CDeterministicMNManager;
31+
class CMasternodeSync;
32+
class CNode;
33+
class CSporkManager;
34+
namespace llmq {
35+
class CQuorumDataRequest;
36+
class CQuorumSnapshotManager;
37+
} // namespace llmq
2538

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

3066
class QuorumObserver
3167
{
3268
protected:
3369
CConnman& m_connman;
3470
CDeterministicMNManager& m_dmnman;
35-
CQuorumManager& m_qman;
71+
QuorumHandlerParent& m_qman;
3672
CQuorumSnapshotManager& m_qsnapman;
3773
const ChainstateManager& m_chainman;
3874
const CMasternodeSync& m_mn_sync;
@@ -51,7 +87,7 @@ class QuorumObserver
5187
QuorumObserver() = delete;
5288
QuorumObserver(const QuorumObserver&) = delete;
5389
QuorumObserver& operator=(const QuorumObserver&) = delete;
54-
explicit QuorumObserver(CConnman& connman, CDeterministicMNManager& dmnman, CQuorumManager& qman,
90+
explicit QuorumObserver(CConnman& connman, CDeterministicMNManager& dmnman, QuorumHandlerParent& qman,
5591
CQuorumSnapshotManager& qsnapman, const ChainstateManager& chainman,
5692
const CMasternodeSync& mn_sync, const CSporkManager& sporkman,
5793
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 QuorumHandlerParent
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)