Skip to content

Commit 0194061

Browse files
authored
Merge pull request #2704 from codablock/pr_llmq_optimizations1
Optimize LLMQs sending of sig shares
2 parents bedfc26 + d7bd095 commit 0194061

File tree

3 files changed

+85
-6
lines changed

3 files changed

+85
-6
lines changed

src/llmq/quorums_signing_shares.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -896,6 +896,8 @@ void CSigSharesManager::SendMessages()
896896
CollectSigSharesToAnnounce(sigSharesToAnnounce);
897897
}
898898

899+
bool didSend = false;
900+
899901
g_connman->ForEachNode([&](CNode* pnode) {
900902
CNetMsgMaker msgMaker(pnode->GetSendVersion());
901903

@@ -905,7 +907,8 @@ void CSigSharesManager::SendMessages()
905907
assert(p.second.CountSet() != 0);
906908
LogPrint("llmq", "CSigSharesManager::SendMessages -- QGETSIGSHARES inv={%s}, node=%d\n",
907909
p.second.ToString(), pnode->id);
908-
g_connman->PushMessage(pnode, msgMaker.Make(NetMsgType::QGETSIGSHARES, p.second));
910+
g_connman->PushMessage(pnode, msgMaker.Make(NetMsgType::QGETSIGSHARES, p.second), false);
911+
didSend = true;
909912
}
910913
}
911914

@@ -915,7 +918,8 @@ void CSigSharesManager::SendMessages()
915918
assert(!p.second.sigShares.empty());
916919
LogPrint("llmq", "CSigSharesManager::SendMessages -- QBSIGSHARES inv={%s}, node=%d\n",
917920
p.second.ToInv().ToString(), pnode->id);
918-
g_connman->PushMessage(pnode, msgMaker.Make(NetMsgType::QBSIGSHARES, p.second));
921+
g_connman->PushMessage(pnode, msgMaker.Make(NetMsgType::QBSIGSHARES, p.second), false);
922+
didSend = true;
919923
}
920924
}
921925

@@ -925,12 +929,17 @@ void CSigSharesManager::SendMessages()
925929
assert(p.second.CountSet() != 0);
926930
LogPrint("llmq", "CSigSharesManager::SendMessages -- QSIGSHARESINV inv={%s}, node=%d\n",
927931
p.second.ToString(), pnode->id);
928-
g_connman->PushMessage(pnode, msgMaker.Make(NetMsgType::QSIGSHARESINV, p.second));
932+
g_connman->PushMessage(pnode, msgMaker.Make(NetMsgType::QSIGSHARESINV, p.second), false);
933+
didSend = true;
929934
}
930935
}
931936

932937
return true;
933938
});
939+
940+
if (didSend) {
941+
g_connman->WakeSelect();
942+
}
934943
}
935944

936945
void CSigSharesManager::Cleanup()

src/net.cpp

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,6 +1210,18 @@ void CConnman::ThreadSocketHandler()
12101210
SOCKET hSocketMax = 0;
12111211
bool have_fds = false;
12121212

1213+
#ifndef WIN32
1214+
// We add a pipe to the read set so that the select() call can be woken up from the outside
1215+
// This is done when data is available for sending and at the same time optimistic sending was disabled
1216+
// when pushing the data.
1217+
// This is currently only implemented for POSIX compliant systems. This means that Windows will fall back to
1218+
// timing out after 50ms and then trying to send. This is ok as we assume that heavy-load daemons are usually
1219+
// run on Linux and friends.
1220+
FD_SET(wakeupPipe[0], &fdsetRecv);
1221+
hSocketMax = std::max(hSocketMax, (SOCKET)wakeupPipe[0]);
1222+
have_fds = true;
1223+
#endif
1224+
12131225
BOOST_FOREACH(const ListenSocket& hListenSocket, vhListenSocket) {
12141226
FD_SET(hListenSocket.socket, &fdsetRecv);
12151227
hSocketMax = std::max(hSocketMax, hListenSocket.socket);
@@ -1276,6 +1288,20 @@ void CConnman::ThreadSocketHandler()
12761288
return;
12771289
}
12781290

1291+
#ifndef WIN32
1292+
// drain the wakeup pipe
1293+
if (FD_ISSET(wakeupPipe[0], &fdsetRecv)) {
1294+
LogPrint("net", "woke up select()\n");
1295+
char buf[128];
1296+
while (true) {
1297+
int r = read(wakeupPipe[0], buf, sizeof(buf));
1298+
if (r <= 0) {
1299+
break;
1300+
}
1301+
}
1302+
}
1303+
#endif
1304+
12791305
//
12801306
// Accept new connections
12811307
//
@@ -1426,6 +1452,21 @@ void CConnman::WakeMessageHandler()
14261452
condMsgProc.notify_one();
14271453
}
14281454

1455+
void CConnman::WakeSelect()
1456+
{
1457+
#ifndef WIN32
1458+
if (wakeupPipe[1] == -1) {
1459+
return;
1460+
}
1461+
1462+
LogPrint("net", "waking up select()\n");
1463+
1464+
char buf[1];
1465+
if (write(wakeupPipe[1], buf, 1) != 1) {
1466+
LogPrint("net", "write to wakeupPipe failed\n");
1467+
}
1468+
#endif
1469+
}
14291470

14301471

14311472

@@ -2387,6 +2428,22 @@ bool CConnman::Start(CScheduler& scheduler, std::string& strNodeError, Options c
23872428
fMsgProcWake = false;
23882429
}
23892430

2431+
#ifndef WIN32
2432+
if (pipe(wakeupPipe) != 0) {
2433+
wakeupPipe[0] = wakeupPipe[1] = -1;
2434+
LogPrint("net", "pipe() for wakeupPipe failed\n");
2435+
} else {
2436+
int fFlags = fcntl(wakeupPipe[0], F_GETFL, 0);
2437+
if (fcntl(wakeupPipe[0], F_SETFL, fFlags | O_NONBLOCK) == -1) {
2438+
LogPrint("net", "fcntl for O_NONBLOCK on wakeupPipe failed\n");
2439+
}
2440+
fFlags = fcntl(wakeupPipe[1], F_GETFL, 0);
2441+
if (fcntl(wakeupPipe[1], F_SETFL, fFlags | O_NONBLOCK) == -1) {
2442+
LogPrint("net", "fcntl for O_NONBLOCK on wakeupPipe failed\n");
2443+
}
2444+
}
2445+
#endif
2446+
23902447
// Send and receive from sockets, accept connections
23912448
threadSocketHandler = std::thread(&TraceThread<std::function<void()> >, "net", std::function<void()>(std::bind(&CConnman::ThreadSocketHandler, this)));
23922449

@@ -2512,6 +2569,12 @@ void CConnman::Stop()
25122569
semAddnode = NULL;
25132570
delete semMasternodeOutbound;
25142571
semMasternodeOutbound = NULL;
2572+
2573+
#ifndef WIN32
2574+
if (wakeupPipe[0] != -1) close(wakeupPipe[0]);
2575+
if (wakeupPipe[1] != -1) close(wakeupPipe[1]);
2576+
wakeupPipe[0] = wakeupPipe[1] = -1;
2577+
#endif
25152578
}
25162579

25172580
void CConnman::DeleteNode(CNode* pnode)
@@ -3054,7 +3117,7 @@ bool CConnman::NodeFullyConnected(const CNode* pnode)
30543117
return pnode && pnode->fSuccessfullyConnected && !pnode->fDisconnect;
30553118
}
30563119

3057-
void CConnman::PushMessage(CNode* pnode, CSerializedNetMsg&& msg)
3120+
void CConnman::PushMessage(CNode* pnode, CSerializedNetMsg&& msg, bool allowOptimisticSend)
30583121
{
30593122
size_t nMessageSize = msg.data.size();
30603123
size_t nTotalSize = nMessageSize + CMessageHeader::HEADER_SIZE;
@@ -3071,7 +3134,7 @@ void CConnman::PushMessage(CNode* pnode, CSerializedNetMsg&& msg)
30713134
size_t nBytesSent = 0;
30723135
{
30733136
LOCK(pnode->cs_vSend);
3074-
bool optimisticSend(pnode->vSendMsg.empty());
3137+
bool optimisticSend(allowOptimisticSend && pnode->vSendMsg.empty());
30753138

30763139
//log total amount of bytes per command
30773140
pnode->mapSendBytesPerMsgCmd[msg.command] += nTotalSize;

src/net.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ class CConnman
201201

202202
bool IsMasternodeOrDisconnectRequested(const CService& addr);
203203

204-
void PushMessage(CNode* pnode, CSerializedNetMsg&& msg);
204+
void PushMessage(CNode* pnode, CSerializedNetMsg&& msg, bool allowOptimisticSend = true);
205205

206206
template<typename Condition, typename Callable>
207207
bool ForEachNodeContinueIf(const Condition& cond, Callable&& func)
@@ -408,6 +408,8 @@ class CConnman
408408
unsigned int GetReceiveFloodSize() const;
409409

410410
void WakeMessageHandler();
411+
void WakeSelect();
412+
411413
private:
412414
struct ListenSocket {
413415
SOCKET socket;
@@ -525,6 +527,11 @@ class CConnman
525527

526528
CThreadInterrupt interruptNet;
527529

530+
#ifndef WIN32
531+
/** a pipe which is added to select() calls to wakeup before the timeout */
532+
int wakeupPipe[2]{-1,-1};
533+
#endif
534+
528535
std::thread threadDNSAddressSeed;
529536
std::thread threadSocketHandler;
530537
std::thread threadOpenAddedConnections;

0 commit comments

Comments
 (0)