Skip to content

Commit 276af5a

Browse files
authored
Merge pull request #65 from barrystyle/bugfix/dandelion-cpuusage
Refactor DandelionShuffleThread to run in connection scheduler
2 parents 1fd012c + 48227d4 commit 276af5a

File tree

3 files changed

+24
-23
lines changed

3 files changed

+24
-23
lines changed

src/init.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -1815,6 +1815,11 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
18151815
banman->DumpBanlist();
18161816
}, DUMP_BANS_INTERVAL);
18171817

1818+
CConnman* connman = node.connman.get();
1819+
node.scheduler->scheduleEvery([connman]{
1820+
connman->CheckDandelionShuffle();
1821+
}, CHECK_DANDELION_SHUFFLE_INTERVAL);
1822+
18181823
#if HAVE_SYSTEM
18191824
StartupNotify(args);
18201825
#endif

src/net.cpp

+15-21
Original file line numberDiff line numberDiff line change
@@ -1792,21 +1792,21 @@ void CConnman::DandelionShuffle() {
17921792
LogPrint(BCLog::DANDELION, "After Dandelion shuffle:\n%s", GetDandelionRoutingDataDebugString());
17931793
}
17941794

1795-
void CConnman::ThreadDandelionShuffle() {
1796-
auto current_time = GetTime<std::chrono::microseconds>();
1797-
auto next_dandelion_shuffle = PoissonNextSend(current_time, DANDELION_SHUFFLE_INTERVAL);
1795+
void CConnman::CheckDandelionShuffle()
1796+
{
1797+
{
1798+
LOCK(cs_vNodes);
1799+
if (!vNodes.size())
1800+
return;
1801+
}
17981802

1799-
while (!interruptNet) {
1800-
current_time = GetTime<std::chrono::microseconds>();
1801-
if (current_time > next_dandelion_shuffle) {
1802-
DandelionShuffle();
1803-
next_dandelion_shuffle = PoissonNextSend(current_time, DANDELION_SHUFFLE_INTERVAL);
1804-
// Sleep until the next shuffle time
1805-
auto sleep_ms = std::chrono::duration_cast<std::chrono::milliseconds>((next_dandelion_shuffle - current_time) / 1000);
1806-
if (!interruptNet.sleep_for(sleep_ms)) {
1807-
return;
1808-
}
1809-
}
1803+
//! next_dandelion_shuffle static to avoid needing a global
1804+
auto current_time = GetTime<std::chrono::milliseconds>();
1805+
static auto next_dandelion_shuffle = PoissonNextSend(current_time, DANDELION_SHUFFLE_INTERVAL);
1806+
1807+
if (current_time > next_dandelion_shuffle) {
1808+
DandelionShuffle();
1809+
next_dandelion_shuffle = PoissonNextSend(current_time, DANDELION_SHUFFLE_INTERVAL);
18101810
}
18111811
}
18121812

@@ -2927,9 +2927,6 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
29272927
std::thread(&util::TraceThread, "i2paccept", [this] { ThreadI2PAcceptIncoming(); });
29282928
}
29292929

2930-
// Dandelion shuffle
2931-
threadDandelionShuffle = std::thread(&util::TraceThread, "dandelion", [this] { ThreadDandelionShuffle(); });
2932-
29332930
// Dump network addresses
29342931
scheduler.scheduleEvery([this] { DumpAddresses(); }, DUMP_PEERS_INTERVAL);
29352932

@@ -2977,9 +2974,8 @@ void CConnman::Interrupt()
29772974

29782975
void CConnman::StopThreads()
29792976
{
2980-
if (threadI2PAcceptIncoming.joinable()) {
2977+
if (threadI2PAcceptIncoming.joinable())
29812978
threadI2PAcceptIncoming.join();
2982-
}
29832979
if (threadMessageHandler.joinable())
29842980
threadMessageHandler.join();
29852981
if (threadOpenConnections.joinable())
@@ -2990,8 +2986,6 @@ void CConnman::StopThreads()
29902986
threadDNSAddressSeed.join();
29912987
if (threadSocketHandler.joinable())
29922988
threadSocketHandler.join();
2993-
if (threadDandelionShuffle.joinable())
2994-
threadDandelionShuffle.join();
29952989
}
29962990

29972991
void CConnman::StopNodes()

src/net.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ static const size_t DEFAULT_MAXRECEIVEBUFFER = 5 * 1000;
8787
static const size_t DEFAULT_MAXSENDBUFFER = 1 * 1000;
8888

8989
typedef std::chrono::seconds sec;
90+
typedef std::chrono::milliseconds msec;
9091

9192
/** Maximum number of outbound peers designated as Dandelion destinations */
9293
static const int DANDELION_MAX_DESTINATIONS = 2;
@@ -96,6 +97,8 @@ static const sec DANDELION_SHUFFLE_INTERVAL = sec(600);
9697
static const sec DANDELION_EMBARGO_MINIMUM = sec(10);
9798
/** The average additional embargo time beyond the minimum amount */
9899
static const sec DANDELION_EMBARGO_AVG_ADD = sec(20);
100+
/** The time to wait for the scheduler before rerunning Dandelion shuffle check */
101+
static const msec CHECK_DANDELION_SHUFFLE_INTERVAL = msec(1000);
99102

100103
typedef int64_t NodeId;
101104

@@ -982,6 +985,7 @@ class CConnman
982985
bool insertDandelionEmbargo(const uint256& hash, const std::chrono::seconds& embargo);
983986
bool isTxDandelionEmbargoed(const uint256& hash) const;
984987
bool removeDandelionEmbargo(const uint256& hash);
988+
void CheckDandelionShuffle();
985989

986990
/** Attempts to obfuscate tx time through exponentially distributed emitting.
987991
Works assuming that a single interval is used.
@@ -1038,7 +1042,6 @@ class CConnman
10381042
void SocketHandler();
10391043
void ThreadSocketHandler();
10401044
void ThreadDNSAddressSeed();
1041-
void ThreadDandelionShuffle();
10421045
std::string GetDandelionRoutingDataDebugString() const;
10431046

10441047

@@ -1221,7 +1224,6 @@ class CConnman
12211224
std::thread threadOpenAddedConnections;
12221225
std::thread threadOpenConnections;
12231226
std::thread threadMessageHandler;
1224-
std::thread threadDandelionShuffle;
12251227
std::thread threadI2PAcceptIncoming;
12261228

12271229
/** flag for deciding to connect to an extra outbound peer,

0 commit comments

Comments
 (0)