From b1869e9a2db71427000b2000ea3ebf6ea1d28754 Mon Sep 17 00:00:00 2001 From: Fabian Jahr Date: Fri, 13 Mar 2026 15:19:48 +0100 Subject: [PATCH] torcontrol: Move tor controller into node context Co-authored-by: sedited --- src/init.cpp | 11 ++++++++--- src/node/context.cpp | 1 + src/node/context.h | 2 ++ src/torcontrol.cpp | 29 ----------------------------- src/torcontrol.h | 4 ---- 5 files changed, 11 insertions(+), 36 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index fb4b8fa9e27..f52d8d8d7e4 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -276,7 +276,9 @@ void Interrupt(NodeContext& node) InterruptHTTPRPC(); InterruptRPC(); InterruptREST(); - InterruptTorControl(); + if (node.tor_controller) { + node.tor_controller->Interrupt(); + } InterruptMapPort(); if (node.connman) node.connman->Interrupt(); @@ -319,7 +321,10 @@ void Shutdown(NodeContext& node) if (node.peerman && node.validation_signals) node.validation_signals->UnregisterValidationInterface(node.peerman.get()); if (node.connman) node.connman->Stop(); - StopTorControl(); + if (node.tor_controller) { + node.tor_controller->Join(); + node.tor_controller.reset(); + } if (node.background_init_thread.joinable()) node.background_init_thread.join(); // After everything has been shut down, but before things get flushed, stop the @@ -2187,7 +2192,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) "for the automatically created Tor onion service."), onion_service_target.ToStringAddrPort())); } - StartTorControl(onion_service_target); + node.tor_controller = std::make_unique(gArgs.GetArg("-torcontrol", DEFAULT_TOR_CONTROL), onion_service_target); } if (connOptions.bind_on_any) { diff --git a/src/node/context.cpp b/src/node/context.cpp index d7d01b494ee..164361601f9 100644 --- a/src/node/context.cpp +++ b/src/node/context.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/src/node/context.h b/src/node/context.h index 3a7488fd25f..848c872fd4a 100644 --- a/src/node/context.h +++ b/src/node/context.h @@ -25,6 +25,7 @@ class ChainstateManager; class ECC_Context; class NetGroupManager; class PeerManager; +class TorController; namespace interfaces { class Chain; class ChainClient; @@ -69,6 +70,7 @@ struct NodeContext { std::unique_ptr netgroupman; std::unique_ptr fee_estimator; std::unique_ptr peerman; + std::unique_ptr tor_controller; std::unique_ptr chainman; std::unique_ptr banman; ArgsManager* args{nullptr}; // Currently a raw pointer because the memory is not managed by this struct diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index e8e680d7906..ecc75f15ccf 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -735,35 +735,6 @@ fs::path TorController::GetPrivateKeyFile() return gArgs.GetDataDirNet() / "onion_v3_private_key"; } -/****** Thread ********/ - -/** - * TODO: TBD if introducing a global is the preferred approach here since we - * usually try to avoid them. We could let init manage the lifecycle or make - * this a part of NodeContext maybe instead. - */ -static std::unique_ptr g_tor_controller; - -void StartTorControl(CService onion_service_target) -{ - assert(!g_tor_controller); - g_tor_controller = std::make_unique(gArgs.GetArg("-torcontrol", DEFAULT_TOR_CONTROL), onion_service_target); -} - -void InterruptTorControl() -{ - if (!g_tor_controller) return; - LogInfo("tor: Thread interrupt"); - g_tor_controller->Interrupt(); -} - -void StopTorControl() -{ - if (!g_tor_controller) return; - g_tor_controller->Join(); - g_tor_controller.reset(); -} - CService DefaultOnionServiceTarget(uint16_t port) { struct in_addr onion_service_target; diff --git a/src/torcontrol.h b/src/torcontrol.h index 7dfc6207a9a..75b81b87b2d 100644 --- a/src/torcontrol.h +++ b/src/torcontrol.h @@ -31,10 +31,6 @@ constexpr int TOR_REPLY_OK{250}; constexpr int TOR_REPLY_UNRECOGNIZED{510}; constexpr int TOR_REPLY_SYNTAX_ERROR{512}; //!< Syntax error in command argument -void StartTorControl(CService onion_service_target); -void InterruptTorControl(); -void StopTorControl(); - CService DefaultOnionServiceTarget(uint16_t port); /** Reply from Tor, can be single or multi-line */