Skip to content

Commit 7a192e2

Browse files
codablockUdjinM6
authored andcommitted
Optimize sleeping behavior in CSigSharesManager::WorkThreadMain (#2707)
* Don't sleep in WorkThreadMain when CPU intensive work was done When the current iteration resulted in CPU intensive work, it's likely that the next iteration will result in work as well. Do not sleep in that case, as we're otherwise wasting (unused) CPU resources. * No matter how fast we process sig shares, always force 100ms between sending * Apply review suggestions
1 parent feb4e0a commit 7a192e2

File tree

4 files changed

+35
-16
lines changed

4 files changed

+35
-16
lines changed

src/llmq/quorums_signing.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -421,14 +421,14 @@ void CSigningManager::CollectPendingRecoveredSigsToVerify(
421421
}
422422
}
423423

424-
void CSigningManager::ProcessPendingRecoveredSigs(CConnman& connman)
424+
bool CSigningManager::ProcessPendingRecoveredSigs(CConnman& connman)
425425
{
426426
std::map<NodeId, std::list<CRecoveredSig>> recSigsByNode;
427427
std::map<std::pair<Consensus::LLMQType, uint256>, CQuorumCPtr> quorums;
428428

429429
CollectPendingRecoveredSigsToVerify(32, recSigsByNode, quorums);
430430
if (recSigsByNode.empty()) {
431-
return;
431+
return false;
432432
}
433433

434434
// It's ok to perform insecure batched verification here as we verify against the quorum public keys, which are not
@@ -474,6 +474,8 @@ void CSigningManager::ProcessPendingRecoveredSigs(CConnman& connman)
474474
ProcessRecoveredSig(nodeId, recSig, quorum, connman);
475475
}
476476
}
477+
478+
return true;
477479
}
478480

479481
// signature must be verified already

src/llmq/quorums_signing.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ class CSigningManager
157157
bool PreVerifyRecoveredSig(NodeId nodeId, const CRecoveredSig& recoveredSig, bool& retBan);
158158

159159
void CollectPendingRecoveredSigsToVerify(size_t maxUniqueSessions, std::map<NodeId, std::list<CRecoveredSig>>& retSigShares, std::map<std::pair<Consensus::LLMQType, uint256>, CQuorumCPtr>& retQuorums);
160-
void ProcessPendingRecoveredSigs(CConnman& connman); // called from the worker thread of CSigSharesManager
160+
bool ProcessPendingRecoveredSigs(CConnman& connman); // called from the worker thread of CSigSharesManager
161161
void ProcessRecoveredSig(NodeId nodeId, const CRecoveredSig& recoveredSig, const CQuorumCPtr& quorum, CConnman& connman);
162162
void Cleanup(); // called from the worker thread of CSigSharesManager
163163

src/llmq/quorums_signing_shares.cpp

+27-10
Original file line numberDiff line numberDiff line change
@@ -454,14 +454,14 @@ void CSigSharesManager::CollectPendingSigSharesToVerify(
454454
}
455455
}
456456

457-
void CSigSharesManager::ProcessPendingSigShares(CConnman& connman)
457+
bool CSigSharesManager::ProcessPendingSigShares(CConnman& connman)
458458
{
459459
std::map<NodeId, std::vector<CSigShare>> sigSharesByNodes;
460460
std::map<std::pair<Consensus::LLMQType, uint256>, CQuorumCPtr> quorums;
461461

462462
CollectPendingSigSharesToVerify(32, sigSharesByNodes, quorums);
463463
if (sigSharesByNodes.empty()) {
464-
return;
464+
return false;
465465
}
466466

467467
// It's ok to perform insecure batched verification here as we verify against the quorum public key shares,
@@ -521,6 +521,8 @@ void CSigSharesManager::ProcessPendingSigShares(CConnman& connman)
521521

522522
ProcessPendingSigSharesFromNode(nodeId, v, quorums, connman);
523523
}
524+
525+
return true;
524526
}
525527

526528
// It's ensured that no duplicates are passed to this method
@@ -881,7 +883,7 @@ void CSigSharesManager::CollectSigSharesToAnnounce(std::map<NodeId, std::map<uin
881883
this->sigSharesToAnnounce.clear();
882884
}
883885

884-
void CSigSharesManager::SendMessages()
886+
bool CSigSharesManager::SendMessages()
885887
{
886888
std::multimap<CService, NodeId> nodesByAddress;
887889
g_connman->ForEachNode([&nodesByAddress](CNode* pnode) {
@@ -943,6 +945,8 @@ void CSigSharesManager::SendMessages()
943945
if (didSend) {
944946
g_connman->WakeSelect();
945947
}
948+
949+
return didSend;
946950
}
947951

948952
void CSigSharesManager::Cleanup()
@@ -1110,6 +1114,8 @@ void CSigSharesManager::WorkThreadMain()
11101114
{
11111115
workInterrupt.reset();
11121116

1117+
int64_t lastSendTime = 0;
1118+
11131119
while (!workInterrupt) {
11141120
if (!quorumSigningManager || !g_connman || !quorumSigningManager) {
11151121
if (!workInterrupt.sleep_for(std::chrono::milliseconds(100))) {
@@ -1118,17 +1124,26 @@ void CSigSharesManager::WorkThreadMain()
11181124
continue;
11191125
}
11201126

1127+
bool didWork = false;
1128+
11211129
RemoveBannedNodeStates();
1122-
quorumSigningManager->ProcessPendingRecoveredSigs(*g_connman);
1123-
ProcessPendingSigShares(*g_connman);
1124-
SignPendingSigShares();
1125-
SendMessages();
1130+
didWork |= quorumSigningManager->ProcessPendingRecoveredSigs(*g_connman);
1131+
didWork |= ProcessPendingSigShares(*g_connman);
1132+
didWork |= SignPendingSigShares();
1133+
1134+
if (GetTimeMillis() - lastSendTime > 100) {
1135+
SendMessages();
1136+
lastSendTime = GetTimeMillis();
1137+
}
1138+
11261139
Cleanup();
11271140
quorumSigningManager->Cleanup();
11281141

11291142
// TODO Wakeup when pending signing is needed?
1130-
if (!workInterrupt.sleep_for(std::chrono::milliseconds(100))) {
1131-
return;
1143+
if (!didWork) {
1144+
if (!workInterrupt.sleep_for(std::chrono::milliseconds(100))) {
1145+
return;
1146+
}
11321147
}
11331148
}
11341149
}
@@ -1139,7 +1154,7 @@ void CSigSharesManager::AsyncSign(const CQuorumCPtr& quorum, const uint256& id,
11391154
pendingSigns.emplace_back(quorum, id, msgHash);
11401155
}
11411156

1142-
void CSigSharesManager::SignPendingSigShares()
1157+
bool CSigSharesManager::SignPendingSigShares()
11431158
{
11441159
std::vector<std::tuple<const CQuorumCPtr, uint256, uint256>> v;
11451160
{
@@ -1150,6 +1165,8 @@ void CSigSharesManager::SignPendingSigShares()
11501165
for (auto& t : v) {
11511166
Sign(std::get<0>(t), std::get<1>(t), std::get<2>(t));
11521167
}
1168+
1169+
return !v.empty();
11531170
}
11541171

11551172
void CSigSharesManager::Sign(const CQuorumCPtr& quorum, const uint256& id, const uint256& msgHash)

src/llmq/quorums_signing_shares.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ class CSigSharesManager
212212
bool PreVerifyBatchedSigShares(NodeId nodeId, const CBatchedSigShares& batchedSigShares, bool& retBan);
213213

214214
void CollectPendingSigSharesToVerify(size_t maxUniqueSessions, std::map<NodeId, std::vector<CSigShare>>& retSigShares, std::map<std::pair<Consensus::LLMQType, uint256>, CQuorumCPtr>& retQuorums);
215-
void ProcessPendingSigShares(CConnman& connman);
215+
bool ProcessPendingSigShares(CConnman& connman);
216216

217217
void ProcessPendingSigSharesFromNode(NodeId nodeId, const std::vector<CSigShare>& sigShares, const std::map<std::pair<Consensus::LLMQType, uint256>, CQuorumCPtr>& quorums, CConnman& connman);
218218

@@ -226,11 +226,11 @@ class CSigSharesManager
226226

227227
void BanNode(NodeId nodeId);
228228

229-
void SendMessages();
229+
bool SendMessages();
230230
void CollectSigSharesToRequest(std::map<NodeId, std::map<uint256, CSigSharesInv>>& sigSharesToRequest);
231231
void CollectSigSharesToSend(std::map<NodeId, std::map<uint256, CBatchedSigShares>>& sigSharesToSend);
232232
void CollectSigSharesToAnnounce(std::map<NodeId, std::map<uint256, CSigSharesInv>>& sigSharesToAnnounce);
233-
void SignPendingSigShares();
233+
bool SignPendingSigShares();
234234
void WorkThreadMain();
235235
};
236236

0 commit comments

Comments
 (0)