@@ -61,7 +61,10 @@ void CQuorum::Init(const CFinalCommitmentPtr& _qc, const CBlockIndex* _pindexQuo
6161
6262bool CQuorum::SetVerificationVector (const BLSVerificationVector& quorumVecIn)
6363{
64- if (::SerializeHash (quorumVecIn) != qc->quorumVvecHash ) {
64+ const auto quorumVecInSerialized = ::SerializeHash (quorumVecIn);
65+
66+ LOCK (cs);
67+ if (quorumVecInSerialized != qc->quorumVvecHash ) {
6568 return false ;
6669 }
6770 quorumVvec = std::make_shared<BLSVerificationVector>(quorumVecIn);
@@ -70,9 +73,10 @@ bool CQuorum::SetVerificationVector(const BLSVerificationVector& quorumVecIn)
7073
7174bool CQuorum::SetSecretKeyShare (const CBLSSecretKey& secretKeyShare)
7275{
73- if (!secretKeyShare.IsValid () || (secretKeyShare.GetPublicKey () != GetPubKeyShare (GetMemberIndex (activeMasternodeInfo.proTxHash )))) {
76+ if (!secretKeyShare.IsValid () || (secretKeyShare.GetPublicKey () != GetPubKeyShare (WITH_LOCK (activeMasternodeInfoCs, return GetMemberIndex (activeMasternodeInfo.proTxHash ) )))) {
7477 return false ;
7578 }
79+ LOCK (cs);
7680 skShare = secretKeyShare;
7781 return true ;
7882}
@@ -99,15 +103,22 @@ bool CQuorum::IsValidMember(const uint256& proTxHash) const
99103
100104CBLSPublicKey CQuorum::GetPubKeyShare (size_t memberIdx) const
101105{
102- if (quorumVvec == nullptr || memberIdx >= members.size () || !qc->validMembers [memberIdx]) {
106+ LOCK (cs);
107+ if (!HasVerificationVector () || memberIdx >= members.size () || !qc->validMembers [memberIdx]) {
103108 return CBLSPublicKey ();
104109 }
105110 auto & m = members[memberIdx];
106111 return blsCache.BuildPubKeyShare (m->proTxHash , quorumVvec, CBLSId (m->proTxHash ));
107112}
108113
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
110120{
121+ LOCK (cs);
111122 return skShare;
112123}
113124
@@ -125,9 +136,11 @@ void CQuorum::WriteContributions(CEvoDB& evoDb) const
125136{
126137 uint256 dbKey = MakeQuorumKey (*this );
127138
128- if (quorumVvec != nullptr ) {
139+ LOCK (cs);
140+ if (HasVerificationVector ()) {
129141 evoDb.GetRawDB ().Write (std::make_pair (DB_QUORUM_QUORUM_VVEC, dbKey), *quorumVvec);
130142 }
143+
131144 if (skShare.IsValid ()) {
132145 evoDb.GetRawDB ().Write (std::make_pair (DB_QUORUM_SK_SHARE, dbKey), skShare);
133146 }
@@ -139,14 +152,14 @@ bool CQuorum::ReadContributions(CEvoDB& evoDb)
139152
140153 BLSVerificationVector qv;
141154 if (evoDb.Read (std::make_pair (DB_QUORUM_QUORUM_VVEC, dbKey), qv)) {
142- quorumVvec = std::make_shared<BLSVerificationVector>(std::move (qv));
155+ WITH_LOCK (cs, quorumVvec = std::make_shared<BLSVerificationVector>(std::move (qv) ));
143156 } else {
144157 return false ;
145158 }
146159
147160 // We ignore the return value here as it is ok if this fails. If it fails, it usually means that we are not a
148161 // 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);
162+ WITH_LOCK (cs, evoDb.Read (std::make_pair (DB_QUORUM_SK_SHARE, dbKey), skShare) );
150163
151164 return true ;
152165}
@@ -197,8 +210,10 @@ void CQuorumManager::TriggerQuorumDataRecoveryThreads(const CBlockIndex* pIndex)
197210
198211 // First check if we are member of any quorum of this type
199212 bool fWeAreQuorumTypeMember {false };
200- for (const auto & pQuorum : vecQuorums) {
201- if (pQuorum->IsValidMember (activeMasternodeInfo.proTxHash )) {
213+
214+ auto proTxHash = WITH_LOCK (activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash );
215+ for (const auto &pQuorum : vecQuorums) {
216+ if (pQuorum->IsValidMember (proTxHash)) {
202217 fWeAreQuorumTypeMember = true ;
203218 break ;
204219 }
@@ -211,16 +226,16 @@ void CQuorumManager::TriggerQuorumDataRecoveryThreads(const CBlockIndex* pIndex)
211226 }
212227
213228 uint16_t nDataMask{0 };
214- const bool fWeAreQuorumMember = pQuorum->IsValidMember (activeMasternodeInfo. proTxHash );
229+ const bool fWeAreQuorumMember = pQuorum->IsValidMember (proTxHash);
215230 const bool fSyncForTypeEnabled = mapQuorumVvecSync.count (pQuorum->qc ->llmqType ) > 0 ;
216231 const QvvecSyncMode syncMode = fSyncForTypeEnabled ? mapQuorumVvecSync.at (pQuorum->qc ->llmqType ) : QvvecSyncMode::Invalid;
217232 const bool fSyncCurrent = syncMode == QvvecSyncMode::Always || (syncMode == QvvecSyncMode::OnlyIfTypeMember && fWeAreQuorumTypeMember );
218233
219- if ((fWeAreQuorumMember || (fSyncForTypeEnabled && fSyncCurrent )) && pQuorum->quorumVvec == nullptr ) {
234+ if ((fWeAreQuorumMember || (fSyncForTypeEnabled && fSyncCurrent )) && ! pQuorum->HasVerificationVector () ) {
220235 nDataMask |= llmq::CQuorumDataRequest::QUORUM_VERIFICATION_VECTOR;
221236 }
222237
223- if (fWeAreQuorumMember && !pQuorum->skShare .IsValid ()) {
238+ if (fWeAreQuorumMember && !pQuorum->GetSkShare () .IsValid ()) {
224239 nDataMask |= llmq::CQuorumDataRequest::ENCRYPTED_CONTRIBUTIONS;
225240 }
226241
@@ -266,7 +281,6 @@ void CQuorumManager::EnsureQuorumConnections(Consensus::LLMQType llmqType, const
266281{
267282 const auto & params = Params ().GetConsensus ().llmqs .at (llmqType);
268283
269- const auto & myProTxHash = activeMasternodeInfo.proTxHash ;
270284 auto lastQuorums = ScanQuorums (llmqType, pindexNew, (size_t )params.keepOldConnections );
271285
272286 auto connmanQuorumsToDelete = g_connman->GetMasternodeQuorums (llmqType);
@@ -277,7 +291,7 @@ void CQuorumManager::EnsureQuorumConnections(Consensus::LLMQType llmqType, const
277291 connmanQuorumsToDelete.erase (curDkgBlock);
278292
279293 for (const auto & quorum : lastQuorums) {
280- if (CLLMQUtils::EnsureQuorumConnections (llmqType, quorum->pindexQuorum , myProTxHash )) {
294+ if (CLLMQUtils::EnsureQuorumConnections (llmqType, quorum->pindexQuorum , WITH_LOCK (activeMasternodeInfoCs, return activeMasternodeInfo. proTxHash ) )) {
281295 continue ;
282296 }
283297 if (connmanQuorumsToDelete.count (quorum->qc ->quorumHash ) > 0 ) {
@@ -339,8 +353,9 @@ bool CQuorumManager::BuildQuorumContributions(const CFinalCommitmentPtr& fqc, co
339353 }
340354
341355 cxxtimer::Timer t2 (true );
356+ LOCK (quorum->cs );
342357 quorum->quorumVvec = blsWorker.BuildQuorumVerificationVector (vvecs);
343- if (quorum->quorumVvec == nullptr ) {
358+ if (quorum->HasVerificationVector () ) {
344359 LogPrint (BCLog::LLMQ, " CQuorumManager::%s -- failed to build quorumVvec\n " , __func__);
345360 // without the quorum vvec, there can't be a skShare, so we fail here. Failure is not fatal here, as it still
346361 // allows to use the quorum as a non-member (verification through the quorum pub key)
@@ -517,10 +532,13 @@ size_t CQuorumManager::GetQuorumRecoveryStartOffset(const CQuorumCPtr pQuorum, c
517532 });
518533 std::sort (vecProTxHashes.begin (), vecProTxHashes.end ());
519534 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 ;
535+ {
536+ LOCK (activeMasternodeInfoCs);
537+ for (size_t i = 0 ; i < vecProTxHashes.size (); ++i) {
538+ if (activeMasternodeInfo.proTxHash == vecProTxHashes[i]) {
539+ nIndex = i;
540+ break ;
541+ }
524542 }
525543 }
526544 return nIndex % pQuorum->qc ->validMembers .size ();
@@ -592,13 +610,12 @@ void CQuorumManager::ProcessMessage(CNode* pFrom, const std::string& strCommand,
592610
593611 // Check if request wants QUORUM_VERIFICATION_VECTOR data
594612 if (request.GetDataMask () & CQuorumDataRequest::QUORUM_VERIFICATION_VECTOR) {
595-
596- if (!pQuorum->quorumVvec ) {
613+ if (!pQuorum->HasVerificationVector ()) {
597614 sendQDATA (CQuorumDataRequest::Errors::QUORUM_VERIFICATION_VECTOR_MISSING);
598615 return ;
599616 }
600617
601- ssResponseData << *pQuorum->quorumVvec ;
618+ WITH_LOCK (pQuorum-> cs , ssResponseData << *pQuorum->quorumVvec ) ;
602619 }
603620
604621 // Check if request wants ENCRYPTED_CONTRIBUTIONS data
@@ -682,7 +699,7 @@ void CQuorumManager::ProcessMessage(CNode* pFrom, const std::string& strCommand,
682699 // Check if request has ENCRYPTED_CONTRIBUTIONS data
683700 if (request.GetDataMask () & CQuorumDataRequest::ENCRYPTED_CONTRIBUTIONS) {
684701
685- if (pQuorum->quorumVvec ->size () != pQuorum->params .threshold ) {
702+ if (WITH_LOCK ( pQuorum->cs , return pQuorum-> quorumVvec ->size () != pQuorum->params .threshold ) ) {
686703 errorHandler (" No valid quorum verification vector available" , 0 ); // Don't bump score because we asked for it
687704 return ;
688705 }
@@ -698,8 +715,9 @@ void CQuorumManager::ProcessMessage(CNode* pFrom, const std::string& strCommand,
698715
699716 BLSSecretKeyVector vecSecretKeys;
700717 vecSecretKeys.resize (vecEncrypted.size ());
718+ auto secret = WITH_LOCK (activeMasternodeInfoCs, return *activeMasternodeInfo.blsKeyOperator );
701719 for (size_t i = 0 ; i < vecEncrypted.size (); ++i) {
702- if (!vecEncrypted[i].Decrypt (memberIdx, *activeMasternodeInfo. blsKeyOperator , vecSecretKeys[i], PROTOCOL_VERSION)) {
720+ if (!vecEncrypted[i].Decrypt (memberIdx, secret , vecSecretKeys[i], PROTOCOL_VERSION)) {
703721 errorHandler (" Failed to decrypt" );
704722 return ;
705723 }
@@ -718,7 +736,7 @@ void CQuorumManager::ProcessMessage(CNode* pFrom, const std::string& strCommand,
718736
719737void CQuorumManager::StartCachePopulatorThread (const CQuorumCPtr pQuorum) const
720738{
721- if (pQuorum->quorumVvec == nullptr ) {
739+ if (! pQuorum->HasVerificationVector () ) {
722740 return ;
723741 }
724742
@@ -771,7 +789,7 @@ void CQuorumManager::StartQuorumDataRecoveryThread(const CQuorumCPtr pQuorum, co
771789
772790 vecMemberHashes.reserve (pQuorum->qc ->validMembers .size ());
773791 for (auto & member : pQuorum->members ) {
774- if (pQuorum->IsValidMember (member->proTxHash ) && member->proTxHash != activeMasternodeInfo.proTxHash ) {
792+ if (pQuorum->IsValidMember (member->proTxHash ) && member->proTxHash != WITH_LOCK (activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash ) ) {
775793 vecMemberHashes.push_back (member->proTxHash );
776794 }
777795 }
@@ -781,12 +799,13 @@ void CQuorumManager::StartQuorumDataRecoveryThread(const CQuorumCPtr pQuorum, co
781799
782800 while (nDataMask > 0 && !quorumThreadInterrupt) {
783801
784- if (nDataMask & llmq::CQuorumDataRequest::QUORUM_VERIFICATION_VECTOR && pQuorum->quorumVvec != nullptr ) {
802+ if (nDataMask & llmq::CQuorumDataRequest::QUORUM_VERIFICATION_VECTOR &&
803+ pQuorum->HasVerificationVector ()) {
785804 nDataMask &= ~llmq::CQuorumDataRequest::QUORUM_VERIFICATION_VECTOR;
786805 printLog (" Received quorumVvec" );
787806 }
788807
789- if (nDataMask & llmq::CQuorumDataRequest::ENCRYPTED_CONTRIBUTIONS && pQuorum->skShare .IsValid ()) {
808+ if (nDataMask & llmq::CQuorumDataRequest::ENCRYPTED_CONTRIBUTIONS && pQuorum->GetSkShare () .IsValid ()) {
790809 nDataMask &= ~llmq::CQuorumDataRequest::ENCRYPTED_CONTRIBUTIONS;
791810 printLog (" Received skShare" );
792811 }
@@ -818,13 +837,14 @@ void CQuorumManager::StartQuorumDataRecoveryThread(const CQuorumCPtr pQuorum, co
818837 printLog (" Connect" );
819838 }
820839
840+ auto proTxHash = WITH_LOCK (activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash );
821841 g_connman->ForEachNode ([&](CNode* pNode) {
822842
823843 if (pCurrentMemberHash == nullptr || pNode->verifiedProRegTxHash != *pCurrentMemberHash) {
824844 return ;
825845 }
826846
827- if (quorumManager->RequestQuorumData (pNode, pQuorum->qc ->llmqType , pQuorum->pindexQuorum , nDataMask, activeMasternodeInfo. proTxHash )) {
847+ if (quorumManager->RequestQuorumData (pNode, pQuorum->qc ->llmqType , pQuorum->pindexQuorum , nDataMask, proTxHash)) {
828848 nTimeLastSuccess = GetAdjustedTime ();
829849 printLog (" Requested" );
830850 } else {
0 commit comments