Skip to content

Commit a28e1f5

Browse files
committed
Fix data races triggered by functional tests.
Function CWallet::KeepKey requires locking as it has concurrent access to database and member nKeysLeftSinceAutoBackup. Avoid data race when reading setInventoryTxToSend size by locking the read. If locking happens after the read, the size may change. Lock cs_mnauth when reading verifiedProRegTxHash. Make fRPCRunning atomic as it can be read/written from different threads simultaneously. Make m_masternode_iqr_connection atomic as it can be read/written from different threads simultaneously. Use a recursive mutex to synchronize concurrent access to quorumVvec. Make m_masternode_connection atomic as it can be read/written from different threads simultaneously. Make m_masternode_probe_connection atomic as it can be read/written from different threads simultaneously. Use a recursive mutex in order to lock access to activeMasterNode. Use a recursive mutex to synchronize concurrent access to skShare.
1 parent 4848712 commit a28e1f5

17 files changed

+134
-85
lines changed

src/coinjoin/coinjoin-server.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ void CCoinJoinServer::ProcessMessage(CNode* pfrom, const std::string& strCommand
5656
LogPrint(BCLog::COINJOIN, "DSACCEPT -- nDenom %d (%s) txCollateral %s", dsa.nDenom, CCoinJoin::DenominationToString(dsa.nDenom), dsa.txCollateral.ToString()); /* Continued */
5757

5858
auto mnList = deterministicMNManager->GetListAtChainTip();
59-
auto dmn = mnList.GetValidMNByCollateral(activeMasternodeInfo.outpoint);
59+
auto dmn = WITH_LOCK(activeMasternodeInfoCs, return mnList.GetValidMNByCollateral(activeMasternodeInfo.outpoint));
6060
if (!dmn) {
6161
PushStatus(pfrom, STATUS_REJECTED, ERR_MN_LIST, connman);
6262
return;
@@ -68,7 +68,7 @@ void CCoinJoinServer::ProcessMessage(CNode* pfrom, const std::string& strCommand
6868
if (!lockRecv) return;
6969

7070
for (const auto& q : vecCoinJoinQueue) {
71-
if (q.masternodeOutpoint == activeMasternodeInfo.outpoint) {
71+
if (WITH_LOCK(activeMasternodeInfoCs, return q.masternodeOutpoint == activeMasternodeInfo.outpoint)) {
7272
// refuse to create another queue this often
7373
LogPrint(BCLog::COINJOIN, "DSACCEPT -- last dsq is still in queue, refuse to mix\n");
7474
PushStatus(pfrom, STATUS_REJECTED, ERR_RECENT, connman);
@@ -334,7 +334,7 @@ void CCoinJoinServer::CommitFinalTransaction(CConnman& connman)
334334

335335
// create and sign masternode dstx transaction
336336
if (!CCoinJoin::GetDSTX(hashTx)) {
337-
CCoinJoinBroadcastTx dstxNew(finalTransaction, activeMasternodeInfo.outpoint, GetAdjustedTime());
337+
CCoinJoinBroadcastTx dstxNew(finalTransaction, WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.outpoint), GetAdjustedTime());
338338
dstxNew.Sign();
339339
CCoinJoin::AddDSTX(dstxNew);
340340
}
@@ -501,7 +501,7 @@ void CCoinJoinServer::CheckForCompleteQueue(CConnman& connman)
501501
if (nState == POOL_STATE_QUEUE && IsSessionReady()) {
502502
SetState(POOL_STATE_ACCEPTING_ENTRIES);
503503

504-
CCoinJoinQueue dsq(nSessionDenom, activeMasternodeInfo.outpoint, GetAdjustedTime(), true);
504+
CCoinJoinQueue dsq(nSessionDenom, WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.outpoint), GetAdjustedTime(), true);
505505
LogPrint(BCLog::COINJOIN, "CCoinJoinServer::CheckForCompleteQueue -- queue is ready, signing and relaying (%s) " /* Continued */
506506
"with %d participants\n", dsq.ToString(), vecSessionCollaterals.size());
507507
dsq.Sign();
@@ -708,7 +708,7 @@ bool CCoinJoinServer::CreateNewSession(const CCoinJoinAccept& dsa, PoolMessage&
708708

709709
if (!fUnitTest) {
710710
//broadcast that I'm accepting entries, only if it's the first entry through
711-
CCoinJoinQueue dsq(nSessionDenom, activeMasternodeInfo.outpoint, GetAdjustedTime(), false);
711+
CCoinJoinQueue dsq(nSessionDenom, WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.outpoint), GetAdjustedTime(), false);
712712
LogPrint(BCLog::COINJOIN, "CCoinJoinServer::CreateNewSession -- signing and relaying new queue: %s\n", dsq.ToString());
713713
dsq.Sign();
714714
dsq.Relay(connman);

src/coinjoin/coinjoin.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ bool CCoinJoinQueue::Sign()
5050

5151

5252
uint256 hash = GetSignatureHash();
53-
CBLSSignature sig = activeMasternodeInfo.blsKeyOperator->Sign(hash);
53+
CBLSSignature sig = WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.blsKeyOperator->Sign(hash));
5454
if (!sig.IsValid()) {
5555
return false;
5656
}
@@ -96,7 +96,7 @@ bool CCoinJoinBroadcastTx::Sign()
9696

9797
uint256 hash = GetSignatureHash();
9898

99-
CBLSSignature sig = activeMasternodeInfo.blsKeyOperator->Sign(hash);
99+
CBLSSignature sig = WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.blsKeyOperator->Sign(hash));
100100
if (!sig.IsValid()) {
101101
return false;
102102
}

src/evo/mnauth.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
void CMNAuth::PushMNAUTH(CNode* pnode, CConnman& connman)
2020
{
21+
LOCK(activeMasternodeInfoCs);
2122
if (!fMasternodeMode || activeMasternodeInfo.proTxHash.IsNull()) {
2223
return;
2324
}
@@ -149,10 +150,10 @@ void CMNAuth::ProcessMessage(CNode* pnode, const std::string& strCommand, CDataS
149150

150151
if (pnode2->verifiedProRegTxHash == mnauth.proRegTxHash) {
151152
if (fMasternodeMode) {
152-
auto deterministicOutbound = llmq::CLLMQUtils::DeterministicOutboundConnection(activeMasternodeInfo.proTxHash, mnauth.proRegTxHash);
153+
auto deterministicOutbound = WITH_LOCK(activeMasternodeInfoCs, return llmq::CLLMQUtils::DeterministicOutboundConnection(activeMasternodeInfo.proTxHash, mnauth.proRegTxHash));
153154
LogPrint(BCLog::NET_NETCONN, "CMNAuth::ProcessMessage -- Masternode %s has already verified as peer %d, deterministicOutbound=%s. peer=%d\n",
154155
mnauth.proRegTxHash.ToString(), pnode2->GetId(), deterministicOutbound.ToString(), pnode->GetId());
155-
if (deterministicOutbound == activeMasternodeInfo.proTxHash) {
156+
if (WITH_LOCK(activeMasternodeInfoCs, return deterministicOutbound == activeMasternodeInfo.proTxHash)) {
156157
if (pnode2->fInbound) {
157158
LogPrint(BCLog::NET_NETCONN, "CMNAuth::ProcessMessage -- dropping old inbound, peer=%d\n", pnode2->GetId());
158159
pnode2->fDisconnect = true;

src/init.cpp

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -363,9 +363,12 @@ void PrepareShutdown()
363363
UnregisterValidationInterface(activeMasternodeManager);
364364
}
365365

366-
// make sure to clean up BLS keys before global destructors are called (they have allocated from the secure memory pool)
367-
activeMasternodeInfo.blsKeyOperator.reset();
368-
activeMasternodeInfo.blsPubKeyOperator.reset();
366+
{
367+
LOCK(activeMasternodeInfoCs);
368+
// make sure to clean up BLS keys before global destructors are called (they have allocated from the secure memory pool)
369+
activeMasternodeInfo.blsKeyOperator.reset();
370+
activeMasternodeInfo.blsPubKeyOperator.reset();
371+
}
369372

370373
#ifndef WIN32
371374
try {
@@ -2315,8 +2318,12 @@ bool AppInitMain()
23152318
return InitError(_("Invalid masternodeblsprivkey. Please see documentation."));
23162319
}
23172320
fMasternodeMode = true;
2318-
activeMasternodeInfo.blsKeyOperator = std::make_unique<CBLSSecretKey>(keyOperator);
2319-
activeMasternodeInfo.blsPubKeyOperator = std::make_unique<CBLSPublicKey>(activeMasternodeInfo.blsKeyOperator->GetPublicKey());
2321+
{
2322+
LOCK(activeMasternodeInfoCs);
2323+
activeMasternodeInfo.blsKeyOperator = std::make_unique<CBLSSecretKey>(keyOperator);
2324+
activeMasternodeInfo.blsPubKeyOperator = std::make_unique<CBLSPublicKey>(
2325+
activeMasternodeInfo.blsKeyOperator->GetPublicKey());
2326+
}
23202327
LogPrintf("MASTERNODE:\n");
23212328
LogPrintf(" blsPubKeyOperator: %s\n", keyOperator.GetPublicKey().ToString());
23222329
}
@@ -2327,11 +2334,14 @@ bool AppInitMain()
23272334
RegisterValidationInterface(activeMasternodeManager);
23282335
}
23292336

2330-
if (activeMasternodeInfo.blsKeyOperator == nullptr) {
2331-
activeMasternodeInfo.blsKeyOperator = std::make_unique<CBLSSecretKey>();
2332-
}
2333-
if (activeMasternodeInfo.blsPubKeyOperator == nullptr) {
2334-
activeMasternodeInfo.blsPubKeyOperator = std::make_unique<CBLSPublicKey>();
2337+
{
2338+
LOCK(activeMasternodeInfoCs);
2339+
if (activeMasternodeInfo.blsKeyOperator == nullptr) {
2340+
activeMasternodeInfo.blsKeyOperator = std::make_unique<CBLSSecretKey>();
2341+
}
2342+
if (activeMasternodeInfo.blsPubKeyOperator == nullptr) {
2343+
activeMasternodeInfo.blsPubKeyOperator = std::make_unique<CBLSPublicKey>();
2344+
}
23352345
}
23362346

23372347
// ********************************************************* Step 10b: setup CoinJoin

src/llmq/quorums.cpp

Lines changed: 49 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,10 @@ void CQuorum::Init(const CFinalCommitmentPtr& _qc, const CBlockIndex* _pindexQuo
6161

6262
bool 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

7174
bool 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

100104
CBLSPublicKey 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

719737
void 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

Comments
 (0)