Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor DandelionShuffleThread to run in connection scheduler #65

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1815,6 +1815,11 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
banman->DumpBanlist();
}, DUMP_BANS_INTERVAL);

CConnman* connman = node.connman.get();
node.scheduler->scheduleEvery([connman]{
connman->CheckDandelionShuffle();
}, CHECK_DANDELION_SHUFFLE_INTERVAL);

#if HAVE_SYSTEM
StartupNotify(args);
#endif
Expand Down
36 changes: 15 additions & 21 deletions src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1788,21 +1788,21 @@ void CConnman::DandelionShuffle() {
LogPrint(BCLog::DANDELION, "After Dandelion shuffle:\n%s", GetDandelionRoutingDataDebugString());
}

void CConnman::ThreadDandelionShuffle() {
auto current_time = GetTime<std::chrono::microseconds>();
auto next_dandelion_shuffle = PoissonNextSend(current_time, DANDELION_SHUFFLE_INTERVAL);
void CConnman::CheckDandelionShuffle()
{
{
LOCK(cs_vNodes);
if (!vNodes.size())
return;
}

while (!interruptNet) {
current_time = GetTime<std::chrono::microseconds>();
if (current_time > next_dandelion_shuffle) {
DandelionShuffle();
next_dandelion_shuffle = PoissonNextSend(current_time, DANDELION_SHUFFLE_INTERVAL);
// Sleep until the next shuffle time
auto sleep_ms = std::chrono::duration_cast<std::chrono::milliseconds>((next_dandelion_shuffle - current_time) / 1000);
if (!interruptNet.sleep_for(sleep_ms)) {
return;
}
}
//! next_dandelion_shuffle static to avoid needing a global
auto current_time = GetTime<std::chrono::milliseconds>();
static auto next_dandelion_shuffle = PoissonNextSend(current_time, DANDELION_SHUFFLE_INTERVAL);

if (current_time > next_dandelion_shuffle) {
DandelionShuffle();
next_dandelion_shuffle = PoissonNextSend(current_time, DANDELION_SHUFFLE_INTERVAL);
}
}

Expand Down Expand Up @@ -2923,9 +2923,6 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
std::thread(&util::TraceThread, "i2paccept", [this] { ThreadI2PAcceptIncoming(); });
}

// Dandelion shuffle
threadDandelionShuffle = std::thread(&util::TraceThread, "dandelion", [this] { ThreadDandelionShuffle(); });

// Dump network addresses
scheduler.scheduleEvery([this] { DumpAddresses(); }, DUMP_PEERS_INTERVAL);

Expand Down Expand Up @@ -2973,9 +2970,8 @@ void CConnman::Interrupt()

void CConnman::StopThreads()
{
if (threadI2PAcceptIncoming.joinable()) {
if (threadI2PAcceptIncoming.joinable())
threadI2PAcceptIncoming.join();
}
if (threadMessageHandler.joinable())
threadMessageHandler.join();
if (threadOpenConnections.joinable())
Expand All @@ -2986,8 +2982,6 @@ void CConnman::StopThreads()
threadDNSAddressSeed.join();
if (threadSocketHandler.joinable())
threadSocketHandler.join();
if (threadDandelionShuffle.joinable())
threadDandelionShuffle.join();
}

void CConnman::StopNodes()
Expand Down
6 changes: 4 additions & 2 deletions src/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ static const size_t DEFAULT_MAXRECEIVEBUFFER = 5 * 1000;
static const size_t DEFAULT_MAXSENDBUFFER = 1 * 1000;

typedef std::chrono::seconds sec;
typedef std::chrono::milliseconds msec;

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

typedef int64_t NodeId;

Expand Down Expand Up @@ -982,6 +985,7 @@ class CConnman
bool insertDandelionEmbargo(const uint256& hash, const std::chrono::seconds& embargo);
bool isTxDandelionEmbargoed(const uint256& hash) const;
bool removeDandelionEmbargo(const uint256& hash);
void CheckDandelionShuffle();

/** Attempts to obfuscate tx time through exponentially distributed emitting.
Works assuming that a single interval is used.
Expand Down Expand Up @@ -1038,7 +1042,6 @@ class CConnman
void SocketHandler();
void ThreadSocketHandler();
void ThreadDNSAddressSeed();
void ThreadDandelionShuffle();
std::string GetDandelionRoutingDataDebugString() const;


Expand Down Expand Up @@ -1221,7 +1224,6 @@ class CConnman
std::thread threadOpenAddedConnections;
std::thread threadOpenConnections;
std::thread threadMessageHandler;
std::thread threadDandelionShuffle;
std::thread threadI2PAcceptIncoming;

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