Skip to content

Commit a29d294

Browse files
codablockpanleone
authored andcommitted
Fix deadlock in CSigSharesManager::SendMessages (PIVX-Project#2757)
* Fix deadlock in CSigSharesManager::SendMessages Locking "cs" at this location caused a (potential) deadlock due to changed order of cs and cs_vNodes locking. This changes the method to not require the session object anymore which removes the need for locking. * Pass size of LLMQ instead of llmqType into CSigSharesInv::Init This allows use of sizes which are not supported in chainparams.
1 parent b4a4e09 commit a29d294

File tree

2 files changed

+21
-23
lines changed

2 files changed

+21
-23
lines changed

src/llmq/quorums_signing_shares.cpp

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,9 @@ std::string CSigSharesInv::ToString() const
7070
return str;
7171
}
7272

73-
void CSigSharesInv::Init(Consensus::LLMQType _llmqType)
73+
void CSigSharesInv::Init(size_t size)
7474
{
75-
size_t llmqSize = (size_t)(Params().GetConsensus().llmqs.at(_llmqType).size);
76-
inv.resize(llmqSize, false);
75+
inv.resize(size, false);
7776
}
7877

7978
bool CSigSharesInv::IsSet(uint16_t quorumMember) const
@@ -88,27 +87,30 @@ void CSigSharesInv::Set(uint16_t quorumMember, bool v)
8887
inv[quorumMember] = v;
8988
}
9089

91-
CSigSharesInv CBatchedSigShares::ToInv(Consensus::LLMQType llmqType) const
90+
std::string CBatchedSigShares::ToInvString() const
9291
{
9392
CSigSharesInv inv;
94-
inv.Init(llmqType);
93+
// we use 400 here no matter what the real size is. We don't really care about that size as we just want to call ToString()
94+
inv.Init(400);
9595
for (size_t i = 0; i < sigShares.size(); i++) {
9696
inv.inv[sigShares[i].first] = true;
9797
}
98-
return inv;
98+
return inv.ToString();
9999
}
100100

101101
template <typename T>
102102
static void InitSession(CSigSharesNodeState::Session& s, const uint256& signHash, T& from)
103103
{
104+
const auto& params = Params().GetConsensus().llmqs.at((Consensus::LLMQType)from.llmqType);
105+
104106
s.llmqType = (Consensus::LLMQType)from.llmqType;
105107
s.quorumHash = from.quorumHash;
106108
s.id = from.id;
107109
s.msgHash = from.msgHash;
108110
s.signHash = signHash;
109-
s.announced.Init((Consensus::LLMQType)from.llmqType);
110-
s.requested.Init((Consensus::LLMQType)from.llmqType);
111-
s.knows.Init((Consensus::LLMQType)from.llmqType);
111+
s.announced.Init((size_t)params.size);
112+
s.requested.Init((size_t)params.size);
113+
s.knows.Init((size_t)params.size);
112114
}
113115

114116
CSigSharesNodeState::Session& CSigSharesNodeState::GetOrCreateSessionFromShare(const llmq::CSigShare& sigShare)
@@ -435,8 +437,8 @@ bool CSigSharesManager::ProcessMessageBatchedSigShares(CNode* pfrom, const CBatc
435437
}
436438
}
437439

438-
LogPrintf("llmq", "CSigSharesManager::%s -- signHash=%s, shares=%d, new=%d, inv={%s}, node=%d\n", __func__,
439-
sessionInfo.signHash.ToString(), batchedSigShares.sigShares.size(), sigShares.size(), batchedSigShares.ToInv(sessionInfo.llmqType).ToString(), pfrom->GetId());
440+
LogPrint(BCLog::LLMQ, "CSigSharesManager::%s -- signHash=%s, shares=%d, new=%d, inv={%s}, node=%d\n", __func__,
441+
sessionInfo.signHash.ToString(), batchedSigShares.sigShares.size(), sigShares.size(), batchedSigShares.ToInvString(), pfrom->GetId());
440442

441443
if (sigShares.empty()) {
442444
return true;
@@ -862,7 +864,8 @@ void CSigSharesManager::CollectSigSharesToRequest(std::unordered_map<NodeId, std
862864
}
863865
auto& inv = (*invMap)[signHash];
864866
if (inv.inv.empty()) {
865-
inv.Init(session.llmqType);
867+
const auto& params = Params().GetConsensus().llmqs.at((Consensus::LLMQType)session.llmqType);
868+
inv.Init((size_t)params.size);
866869
}
867870
inv.inv[k.second] = true;
868871

@@ -974,7 +977,8 @@ void CSigSharesManager::CollectSigSharesToAnnounce(std::unordered_map<NodeId, st
974977

975978
auto& inv = sigSharesToAnnounce[nodeId][signHash];
976979
if (inv.inv.empty()) {
977-
inv.Init((Consensus::LLMQType)sigShare->llmqType);
980+
const auto& params = Params().GetConsensus().llmqs.at((Consensus::LLMQType)sigShare->llmqType);
981+
inv.Init((size_t)params.size);
978982
}
979983
inv.inv[quorumMember] = true;
980984
session.knows.inv[quorumMember] = true;
@@ -1093,14 +1097,8 @@ bool CSigSharesManager::SendMessages()
10931097
std::vector<CBatchedSigShares> msgs;
10941098
for (auto& p : jt->second) {
10951099
assert(!p.second.sigShares.empty());
1096-
if (LogAcceptCategory(BCLog::LogFlags::LLMQ)) {
1097-
LOCK(cs);
1098-
auto session = nodeStates[pnode->GetId()].GetSessionBySignHash(p.first);
1099-
assert(session);
1100-
LogPrintf("llmq", "CSigSharesManager::SendMessages -- QBSIGSHARES signHash=%s, inv={%s}, node=%d\n",
1101-
p.first.ToString(), p.second.ToInv(session->llmqType).ToString(), pnode->GetId());
1102-
}
1103-
1100+
LogPrint(BCLog::LLMQ, "CSigSharesManager::SendMessages -- QBSIGSHARES signHash=%s, inv={%s}, node=%d\n",
1101+
p.first.ToString(), p.second.ToInvString(), pnode->GetId());
11041102
if (totalSigsCount + p.second.sigShares.size() > MAX_MSGS_TOTAL_BATCHED_SIGS) {
11051103
g_connman->PushMessage(pnode, msgMaker.Make(NetMsgType::QBSIGSHARES, msgs));
11061104
msgs.clear();

src/llmq/quorums_signing_shares.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ class CSigSharesInv
9797
READWRITE(AUTOBITSET(obj.inv, (size_t)invSize));
9898
}
9999

100-
void Init(Consensus::LLMQType _llmqType);
100+
void Init(size_t size);
101101
bool IsSet(uint16_t quorumMember) const;
102102
void Set(uint16_t quorumMember, bool v);
103103
void Merge(const CSigSharesInv& inv2);
@@ -120,7 +120,7 @@ class CBatchedSigShares
120120
READWRITE(obj.sigShares);
121121
}
122122

123-
CSigSharesInv ToInv(Consensus::LLMQType llmqType) const;
123+
std::string ToInvString() const;
124124
};
125125

126126
template <typename T>

0 commit comments

Comments
 (0)