Skip to content

Commit 588eb30

Browse files
codablockUdjinM6
authored andcommitted
Fix deadlock in CSigSharesManager::SendMessages (#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 7b24f9b commit 588eb30

File tree

2 files changed

+20
-22
lines changed

2 files changed

+20
-22
lines changed

src/llmq/quorums_signing_shares.cpp

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,9 @@ std::string CSigSharesInv::ToString() const
6565
return str;
6666
}
6767

68-
void CSigSharesInv::Init(Consensus::LLMQType _llmqType)
68+
void CSigSharesInv::Init(size_t size)
6969
{
70-
size_t llmqSize = (size_t)(Params().GetConsensus().llmqs.at(_llmqType).size);
71-
inv.resize(llmqSize, false);
70+
inv.resize(size, false);
7271
}
7372

7473
bool CSigSharesInv::IsSet(uint16_t quorumMember) const
@@ -83,27 +82,30 @@ void CSigSharesInv::Set(uint16_t quorumMember, bool v)
8382
inv[quorumMember] = v;
8483
}
8584

86-
CSigSharesInv CBatchedSigShares::ToInv(Consensus::LLMQType llmqType) const
85+
std::string CBatchedSigShares::ToInvString() const
8786
{
8887
CSigSharesInv inv;
89-
inv.Init(llmqType);
88+
// 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()
89+
inv.Init(400);
9090
for (size_t i = 0; i < sigShares.size(); i++) {
9191
inv.inv[sigShares[i].first] = true;
9292
}
93-
return inv;
93+
return inv.ToString();
9494
}
9595

9696
template<typename T>
9797
static void InitSession(CSigSharesNodeState::Session& s, const uint256& signHash, T& from)
9898
{
99+
const auto& params = Params().GetConsensus().llmqs.at((Consensus::LLMQType)from.llmqType);
100+
99101
s.llmqType = (Consensus::LLMQType)from.llmqType;
100102
s.quorumHash = from.quorumHash;
101103
s.id = from.id;
102104
s.msgHash = from.msgHash;
103105
s.signHash = signHash;
104-
s.announced.Init((Consensus::LLMQType)from.llmqType);
105-
s.requested.Init((Consensus::LLMQType)from.llmqType);
106-
s.knows.Init((Consensus::LLMQType)from.llmqType);
106+
s.announced.Init((size_t)params.size);
107+
s.requested.Init((size_t)params.size);
108+
s.knows.Init((size_t)params.size);
107109
}
108110

109111
CSigSharesNodeState::Session& CSigSharesNodeState::GetOrCreateSessionFromShare(const llmq::CSigShare& sigShare)
@@ -443,7 +445,7 @@ bool CSigSharesManager::ProcessMessageBatchedSigShares(CNode* pfrom, const CBatc
443445
}
444446

445447
LogPrint("llmq", "CSigSharesManager::%s -- signHash=%s, shares=%d, new=%d, inv={%s}, node=%d\n", __func__,
446-
sessionInfo.signHash.ToString(), batchedSigShares.sigShares.size(), sigShares.size(), batchedSigShares.ToInv(sessionInfo.llmqType).ToString(), pfrom->id);
448+
sessionInfo.signHash.ToString(), batchedSigShares.sigShares.size(), sigShares.size(), batchedSigShares.ToInvString(), pfrom->id);
447449

448450
if (sigShares.empty()) {
449451
return true;
@@ -871,7 +873,8 @@ void CSigSharesManager::CollectSigSharesToRequest(std::unordered_map<NodeId, std
871873
}
872874
auto& inv = (*invMap)[signHash];
873875
if (inv.inv.empty()) {
874-
inv.Init(session.llmqType);
876+
const auto& params = Params().GetConsensus().llmqs.at((Consensus::LLMQType)session.llmqType);
877+
inv.Init((size_t)params.size);
875878
}
876879
inv.inv[k.second] = true;
877880

@@ -982,7 +985,8 @@ void CSigSharesManager::CollectSigSharesToAnnounce(std::unordered_map<NodeId, st
982985

983986
auto& inv = sigSharesToAnnounce[nodeId][signHash];
984987
if (inv.inv.empty()) {
985-
inv.Init((Consensus::LLMQType)sigShare->llmqType);
988+
const auto& params = Params().GetConsensus().llmqs.at((Consensus::LLMQType)sigShare->llmqType);
989+
inv.Init((size_t)params.size);
986990
}
987991
inv.inv[quorumMember] = true;
988992
session.knows.inv[quorumMember] = true;
@@ -1101,14 +1105,8 @@ bool CSigSharesManager::SendMessages()
11011105
std::vector<CBatchedSigShares> msgs;
11021106
for (auto& p : jt->second) {
11031107
assert(!p.second.sigShares.empty());
1104-
if (LogAcceptCategory("llmq")) {
1105-
LOCK(cs);
1106-
auto session = nodeStates[pnode->id].GetSessionBySignHash(p.first);
1107-
assert(session);
1108-
LogPrint("llmq", "CSigSharesManager::SendMessages -- QBSIGSHARES signHash=%s, inv={%s}, node=%d\n",
1109-
p.first.ToString(), p.second.ToInv(session->llmqType).ToString(), pnode->id);
1110-
}
1111-
1108+
LogPrint("llmq", "CSigSharesManager::SendMessages -- QBSIGSHARES signHash=%s, inv={%s}, node=%d\n",
1109+
p.first.ToString(), p.second.ToInvString(), pnode->id);
11121110
if (totalSigsCount + p.second.sigShares.size() > MAX_MSGS_TOTAL_BATCHED_SIGS) {
11131111
g_connman->PushMessage(pnode, msgMaker.Make(NetMsgType::QBSIGSHARES, msgs), false);
11141112
msgs.clear();

src/llmq/quorums_signing_shares.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ class CSigSharesInv
101101
READWRITE(AUTOBITSET(inv, (size_t)invSize));
102102
}
103103

104-
void Init(Consensus::LLMQType _llmqType);
104+
void Init(size_t size);
105105
bool IsSet(uint16_t quorumMember) const;
106106
void Set(uint16_t quorumMember, bool v);
107107
void Merge(const CSigSharesInv& inv2);
@@ -127,7 +127,7 @@ class CBatchedSigShares
127127
READWRITE(sigShares);
128128
}
129129

130-
CSigSharesInv ToInv(Consensus::LLMQType llmqType) const;
130+
std::string ToInvString() const;
131131
};
132132

133133
template<typename T>

0 commit comments

Comments
 (0)