@@ -61,7 +61,10 @@ void CQuorum::Init(const CFinalCommitmentPtr& _qc, const CBlockIndex* _pindexQuo
61
61
62
62
bool CQuorum::SetVerificationVector (const BLSVerificationVector& quorumVecIn)
63
63
{
64
- if (::SerializeHash (quorumVecIn) != qc->quorumVvecHash ) {
64
+ const auto quorumVecInSerialized = ::SerializeHash (quorumVecIn);
65
+
66
+ LOCK (cs);
67
+ if (quorumVecInSerialized != qc->quorumVvecHash ) {
65
68
return false ;
66
69
}
67
70
quorumVvec = std::make_shared<BLSVerificationVector>(quorumVecIn);
@@ -70,9 +73,10 @@ bool CQuorum::SetVerificationVector(const BLSVerificationVector& quorumVecIn)
70
73
71
74
bool CQuorum::SetSecretKeyShare (const CBLSSecretKey& secretKeyShare)
72
75
{
73
- if (!secretKeyShare.IsValid () || (secretKeyShare.GetPublicKey () != GetPubKeyShare (GetMemberIndex (activeMasternodeInfo.proTxHash )))) {
76
+ if (!secretKeyShare.IsValid () || (secretKeyShare.GetPublicKey () != GetPubKeyShare (WITH_LOCK (activeMasternodeInfoCs, return GetMemberIndex (activeMasternodeInfo.proTxHash ) )))) {
74
77
return false ;
75
78
}
79
+ LOCK (cs);
76
80
skShare = secretKeyShare;
77
81
return true ;
78
82
}
@@ -99,15 +103,22 @@ bool CQuorum::IsValidMember(const uint256& proTxHash) const
99
103
100
104
CBLSPublicKey CQuorum::GetPubKeyShare (size_t memberIdx) const
101
105
{
102
- if (quorumVvec == nullptr || memberIdx >= members.size () || !qc->validMembers [memberIdx]) {
106
+ LOCK (cs);
107
+ if (!HasVerificationVector () || memberIdx >= members.size () || !qc->validMembers [memberIdx]) {
103
108
return CBLSPublicKey ();
104
109
}
105
110
auto & m = members[memberIdx];
106
111
return blsCache.BuildPubKeyShare (m->proTxHash , quorumVvec, CBLSId (m->proTxHash ));
107
112
}
108
113
109
- const CBLSSecretKey& CQuorum::GetSkShare () const
114
+ bool CQuorum::HasVerificationVector () const {
115
+ LOCK (cs);
116
+ return quorumVvec != nullptr ;
117
+ }
118
+
119
+ CBLSSecretKey CQuorum::GetSkShare () const
110
120
{
121
+ LOCK (cs);
111
122
return skShare;
112
123
}
113
124
@@ -125,7 +136,8 @@ void CQuorum::WriteContributions(CEvoDB& evoDb) const
125
136
{
126
137
uint256 dbKey = MakeQuorumKey (*this );
127
138
128
- if (quorumVvec != nullptr ) {
139
+ LOCK (cs);
140
+ if (HasVerificationVector ()) {
129
141
evoDb.GetRawDB ().Write (std::make_pair (DB_QUORUM_QUORUM_VVEC, dbKey), *quorumVvec);
130
142
}
131
143
if (skShare.IsValid ()) {
@@ -139,14 +151,14 @@ bool CQuorum::ReadContributions(CEvoDB& evoDb)
139
151
140
152
BLSVerificationVector qv;
141
153
if (evoDb.Read (std::make_pair (DB_QUORUM_QUORUM_VVEC, dbKey), qv)) {
142
- quorumVvec = std::make_shared<BLSVerificationVector>(std::move (qv));
154
+ WITH_LOCK (cs, quorumVvec = std::make_shared<BLSVerificationVector>(std::move (qv) ));
143
155
} else {
144
156
return false ;
145
157
}
146
158
147
159
// We ignore the return value here as it is ok if this fails. If it fails, it usually means that we are not a
148
160
// member of the quorum but observed the whole DKG process to have the quorum verification vector.
149
- evoDb.Read (std::make_pair (DB_QUORUM_SK_SHARE, dbKey), skShare);
161
+ WITH_LOCK (cs, evoDb.Read (std::make_pair (DB_QUORUM_SK_SHARE, dbKey), skShare) );
150
162
151
163
return true ;
152
164
}
@@ -197,8 +209,10 @@ void CQuorumManager::TriggerQuorumDataRecoveryThreads(const CBlockIndex* pIndex)
197
209
198
210
// First check if we are member of any quorum of this type
199
211
bool fWeAreQuorumTypeMember {false };
200
- for (const auto & pQuorum : vecQuorums) {
201
- if (pQuorum->IsValidMember (activeMasternodeInfo.proTxHash )) {
212
+
213
+ auto proTxHash = WITH_LOCK (activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash );
214
+ for (const auto &pQuorum : vecQuorums) {
215
+ if (pQuorum->IsValidMember (proTxHash)) {
202
216
fWeAreQuorumTypeMember = true ;
203
217
break ;
204
218
}
@@ -211,16 +225,16 @@ void CQuorumManager::TriggerQuorumDataRecoveryThreads(const CBlockIndex* pIndex)
211
225
}
212
226
213
227
uint16_t nDataMask{0 };
214
- const bool fWeAreQuorumMember = pQuorum->IsValidMember (activeMasternodeInfo. proTxHash );
228
+ const bool fWeAreQuorumMember = pQuorum->IsValidMember (proTxHash);
215
229
const bool fSyncForTypeEnabled = mapQuorumVvecSync.count (pQuorum->qc ->llmqType ) > 0 ;
216
230
const QvvecSyncMode syncMode = fSyncForTypeEnabled ? mapQuorumVvecSync.at (pQuorum->qc ->llmqType ) : QvvecSyncMode::Invalid;
217
231
const bool fSyncCurrent = syncMode == QvvecSyncMode::Always || (syncMode == QvvecSyncMode::OnlyIfTypeMember && fWeAreQuorumTypeMember );
218
232
219
- if ((fWeAreQuorumMember || (fSyncForTypeEnabled && fSyncCurrent )) && pQuorum->quorumVvec == nullptr ) {
233
+ if ((fWeAreQuorumMember || (fSyncForTypeEnabled && fSyncCurrent )) && ! pQuorum->HasVerificationVector () ) {
220
234
nDataMask |= llmq::CQuorumDataRequest::QUORUM_VERIFICATION_VECTOR;
221
235
}
222
236
223
- if (fWeAreQuorumMember && !pQuorum->skShare .IsValid ()) {
237
+ if (fWeAreQuorumMember && !pQuorum->GetSkShare () .IsValid ()) {
224
238
nDataMask |= llmq::CQuorumDataRequest::ENCRYPTED_CONTRIBUTIONS;
225
239
}
226
240
@@ -266,7 +280,6 @@ void CQuorumManager::EnsureQuorumConnections(Consensus::LLMQType llmqType, const
266
280
{
267
281
const auto & llmq_params = GetLLMQParams (llmqType);
268
282
269
- const auto & myProTxHash = activeMasternodeInfo.proTxHash ;
270
283
auto lastQuorums = ScanQuorums (llmqType, pindexNew, (size_t )llmq_params.keepOldConnections );
271
284
272
285
auto connmanQuorumsToDelete = g_connman->GetMasternodeQuorums (llmqType);
@@ -277,7 +290,7 @@ void CQuorumManager::EnsureQuorumConnections(Consensus::LLMQType llmqType, const
277
290
connmanQuorumsToDelete.erase (curDkgBlock);
278
291
279
292
for (const auto & quorum : lastQuorums) {
280
- if (CLLMQUtils::EnsureQuorumConnections (llmqType, quorum->pindexQuorum , myProTxHash )) {
293
+ if (CLLMQUtils::EnsureQuorumConnections (llmqType, quorum->pindexQuorum , WITH_LOCK (activeMasternodeInfoCs, return activeMasternodeInfo. proTxHash ) )) {
281
294
continue ;
282
295
}
283
296
if (connmanQuorumsToDelete.count (quorum->qc ->quorumHash ) > 0 ) {
@@ -339,8 +352,9 @@ bool CQuorumManager::BuildQuorumContributions(const CFinalCommitmentPtr& fqc, co
339
352
}
340
353
341
354
cxxtimer::Timer t2 (true );
355
+ LOCK (quorum->cs );
342
356
quorum->quorumVvec = blsWorker.BuildQuorumVerificationVector (vvecs);
343
- if (quorum->quorumVvec == nullptr ) {
357
+ if (quorum->HasVerificationVector () ) {
344
358
LogPrint (BCLog::LLMQ, " CQuorumManager::%s -- failed to build quorumVvec\n " , __func__);
345
359
// without the quorum vvec, there can't be a skShare, so we fail here. Failure is not fatal here, as it still
346
360
// allows to use the quorum as a non-member (verification through the quorum pub key)
@@ -517,10 +531,13 @@ size_t CQuorumManager::GetQuorumRecoveryStartOffset(const CQuorumCPtr pQuorum, c
517
531
});
518
532
std::sort (vecProTxHashes.begin (), vecProTxHashes.end ());
519
533
size_t nIndex{0 };
520
- for (size_t i = 0 ; i < vecProTxHashes.size (); ++i) {
521
- if (activeMasternodeInfo.proTxHash == vecProTxHashes[i]) {
522
- nIndex = i;
523
- break ;
534
+ {
535
+ LOCK (activeMasternodeInfoCs);
536
+ for (size_t i = 0 ; i < vecProTxHashes.size (); ++i) {
537
+ if (activeMasternodeInfo.proTxHash == vecProTxHashes[i]) {
538
+ nIndex = i;
539
+ break ;
540
+ }
524
541
}
525
542
}
526
543
return nIndex % pQuorum->qc ->validMembers .size ();
@@ -592,13 +609,12 @@ void CQuorumManager::ProcessMessage(CNode* pFrom, const std::string& strCommand,
592
609
593
610
// Check if request wants QUORUM_VERIFICATION_VECTOR data
594
611
if (request.GetDataMask () & CQuorumDataRequest::QUORUM_VERIFICATION_VECTOR) {
595
-
596
- if (!pQuorum->quorumVvec ) {
612
+ if (!pQuorum->HasVerificationVector ()) {
597
613
sendQDATA (CQuorumDataRequest::Errors::QUORUM_VERIFICATION_VECTOR_MISSING);
598
614
return ;
599
615
}
600
616
601
- ssResponseData << *pQuorum->quorumVvec ;
617
+ WITH_LOCK (pQuorum-> cs , ssResponseData << *pQuorum->quorumVvec ) ;
602
618
}
603
619
604
620
// Check if request wants ENCRYPTED_CONTRIBUTIONS data
@@ -682,7 +698,7 @@ void CQuorumManager::ProcessMessage(CNode* pFrom, const std::string& strCommand,
682
698
// Check if request has ENCRYPTED_CONTRIBUTIONS data
683
699
if (request.GetDataMask () & CQuorumDataRequest::ENCRYPTED_CONTRIBUTIONS) {
684
700
685
- if (pQuorum->quorumVvec ->size () != pQuorum->params .threshold ) {
701
+ if (WITH_LOCK ( pQuorum->cs , return pQuorum-> quorumVvec ->size () != pQuorum->params .threshold ) ) {
686
702
errorHandler (" No valid quorum verification vector available" , 0 ); // Don't bump score because we asked for it
687
703
return ;
688
704
}
@@ -698,8 +714,9 @@ void CQuorumManager::ProcessMessage(CNode* pFrom, const std::string& strCommand,
698
714
699
715
BLSSecretKeyVector vecSecretKeys;
700
716
vecSecretKeys.resize (vecEncrypted.size ());
717
+ auto secret = WITH_LOCK (activeMasternodeInfoCs, return *activeMasternodeInfo.blsKeyOperator );
701
718
for (size_t i = 0 ; i < vecEncrypted.size (); ++i) {
702
- if (!vecEncrypted[i].Decrypt (memberIdx, *activeMasternodeInfo. blsKeyOperator , vecSecretKeys[i], PROTOCOL_VERSION)) {
719
+ if (!vecEncrypted[i].Decrypt (memberIdx, secret , vecSecretKeys[i], PROTOCOL_VERSION)) {
703
720
errorHandler (" Failed to decrypt" );
704
721
return ;
705
722
}
@@ -718,7 +735,7 @@ void CQuorumManager::ProcessMessage(CNode* pFrom, const std::string& strCommand,
718
735
719
736
void CQuorumManager::StartCachePopulatorThread (const CQuorumCPtr pQuorum) const
720
737
{
721
- if (pQuorum->quorumVvec == nullptr ) {
738
+ if (! pQuorum->HasVerificationVector () ) {
722
739
return ;
723
740
}
724
741
@@ -771,7 +788,7 @@ void CQuorumManager::StartQuorumDataRecoveryThread(const CQuorumCPtr pQuorum, co
771
788
772
789
vecMemberHashes.reserve (pQuorum->qc ->validMembers .size ());
773
790
for (auto & member : pQuorum->members ) {
774
- if (pQuorum->IsValidMember (member->proTxHash ) && member->proTxHash != activeMasternodeInfo.proTxHash ) {
791
+ if (pQuorum->IsValidMember (member->proTxHash ) && member->proTxHash != WITH_LOCK (activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash ) ) {
775
792
vecMemberHashes.push_back (member->proTxHash );
776
793
}
777
794
}
@@ -781,12 +798,13 @@ void CQuorumManager::StartQuorumDataRecoveryThread(const CQuorumCPtr pQuorum, co
781
798
782
799
while (nDataMask > 0 && !quorumThreadInterrupt) {
783
800
784
- if (nDataMask & llmq::CQuorumDataRequest::QUORUM_VERIFICATION_VECTOR && pQuorum->quorumVvec != nullptr ) {
801
+ if (nDataMask & llmq::CQuorumDataRequest::QUORUM_VERIFICATION_VECTOR &&
802
+ pQuorum->HasVerificationVector ()) {
785
803
nDataMask &= ~llmq::CQuorumDataRequest::QUORUM_VERIFICATION_VECTOR;
786
804
printLog (" Received quorumVvec" );
787
805
}
788
806
789
- if (nDataMask & llmq::CQuorumDataRequest::ENCRYPTED_CONTRIBUTIONS && pQuorum->skShare .IsValid ()) {
807
+ if (nDataMask & llmq::CQuorumDataRequest::ENCRYPTED_CONTRIBUTIONS && pQuorum->GetSkShare () .IsValid ()) {
790
808
nDataMask &= ~llmq::CQuorumDataRequest::ENCRYPTED_CONTRIBUTIONS;
791
809
printLog (" Received skShare" );
792
810
}
@@ -818,13 +836,14 @@ void CQuorumManager::StartQuorumDataRecoveryThread(const CQuorumCPtr pQuorum, co
818
836
printLog (" Connect" );
819
837
}
820
838
839
+ auto proTxHash = WITH_LOCK (activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash );
821
840
g_connman->ForEachNode ([&](CNode* pNode) {
822
841
823
842
if (pCurrentMemberHash == nullptr || pNode->verifiedProRegTxHash != *pCurrentMemberHash) {
824
843
return ;
825
844
}
826
845
827
- if (quorumManager->RequestQuorumData (pNode, pQuorum->qc ->llmqType , pQuorum->pindexQuorum , nDataMask, activeMasternodeInfo. proTxHash )) {
846
+ if (quorumManager->RequestQuorumData (pNode, pQuorum->qc ->llmqType , pQuorum->pindexQuorum , nDataMask, proTxHash)) {
828
847
nTimeLastSuccess = GetAdjustedTime ();
829
848
printLog (" Requested" );
830
849
} else {
0 commit comments