Right! Here is a diff for that:
0diff --git i/src/torcontrol.cpp w/src/torcontrol.cpp
1index b948de3e5b..77227112b2 100644
2--- i/src/torcontrol.cpp
3+++ w/src/torcontrol.cpp
4@@ -420,20 +420,20 @@ void TorController::get_socks_cb(TorControlConnection& _conn, const TorControlRe
5 // If NET_ONION is not reachable, then none of -proxy or -onion was given.
6 // Since we are here, then -torcontrol and -torpassword were given.
7 g_reachable_nets.Add(NET_ONION);
8 }
9 }
10
11-static std::string MakeAddOnionCmd(const std::string& private_key, const std::string& target, bool enable_pow)
12+std::string TorController::make_add_onion_cmd(bool enable_pow) const
13 {
14 // Note that the 'virtual' port is always the default port to avoid decloaking nodes using other ports.
15 return strprintf("ADD_ONION %s%s Port=%i,%s",
16 private_key,
17 enable_pow ? " PoWDefensesEnabled=1" : "",
18 Params().GetDefaultPort(),
19- target);
20+ m_target.ToStringAddrPort());
21 }
22
23 void TorController::add_onion_cb(TorControlConnection& _conn, const TorControlReply& reply, bool pow_was_enabled)
24 {
25 if (reply.code == TOR_REPLY_OK) {
26 LogDebug(BCLog::TOR, "ADD_ONION successful (PoW defenses %s)", pow_was_enabled ? "enabled" : "disabled");
27@@ -462,13 +462,13 @@ void TorController::add_onion_cb(TorControlConnection& _conn, const TorControlRe
28 AddLocal(service, LOCAL_MANUAL);
29 // ... onion requested - keep connection open
30 } else if (reply.code == TOR_REPLY_UNRECOGNIZED) {
31 LogWarning("tor: Add onion failed with unrecognized command (You probably need to upgrade Tor)");
32 } else if (pow_was_enabled && reply.code == TOR_REPLY_SYNTAX_ERROR) {
33 LogDebug(BCLog::TOR, "ADD_ONION failed with PoW defenses, retrying without");
34- _conn.Command(MakeAddOnionCmd(private_key, m_target.ToStringAddrPort(), /*enable_pow=*/false),
35+ _conn.Command(make_add_onion_cmd(/*enable_pow=*/false),
36 [this](TorControlConnection& conn, const TorControlReply& reply) {
37 add_onion_cb(conn, reply, /*pow_was_enabled=*/false);
38 });
39 } else {
40 LogWarning("tor: Add onion failed; error code %d", reply.code);
41 }
42@@ -487,13 +487,13 @@ void TorController::auth_cb(TorControlConnection& _conn, const TorControlReply&
43
44 // Finally - now create the service
45 if (private_key.empty()) { // No private key, generate one
46 private_key = "NEW:ED25519-V3"; // Explicitly request key type - see issue [#9214](/bitcoin-bitcoin/9214/)
47 }
48 // Request onion service, redirect port.
49- _conn.Command(MakeAddOnionCmd(private_key, m_target.ToStringAddrPort(), /*enable_pow=*/true),
50+ _conn.Command(make_add_onion_cmd(/*enable_pow=*/true),
51 [this](TorControlConnection& conn, const TorControlReply& reply) {
52 add_onion_cb(conn, reply, /*pow_was_enabled=*/true);
53 });
54 } else {
55 LogWarning("tor: Authentication failed");
56 }
57diff --git i/src/torcontrol.h w/src/torcontrol.h
58index b8a1d6540b..1d4f1581fd 100644
59--- i/src/torcontrol.h
60+++ w/src/torcontrol.h
61@@ -139,12 +139,14 @@ private:
62 /** ClientNonce for SAFECOOKIE auth */
63 std::vector<uint8_t> clientNonce;
64
65 public:
66 /** Callback for GETINFO net/listeners/socks result */
67 void get_socks_cb(TorControlConnection& conn, const TorControlReply& reply);
68+ /** Create the "ADD_ONION ..." command with enabled PoW defenses if `enable_pow` is `true`. */
69+ std::string make_add_onion_cmd(bool enable_pow) const;
70 /** Callback for ADD_ONION result */
71 void add_onion_cb(TorControlConnection& conn, const TorControlReply& reply, bool pow_was_enabled);
72 /** Callback for AUTHENTICATE result */
73 void auth_cb(TorControlConnection& conn, const TorControlReply& reply);
74 /** Callback for AUTHCHALLENGE result */
75 void authchallenge_cb(TorControlConnection& conn, const TorControlReply& reply);
I think this is worth including, but this PR has a few ACKs already. Include it?