Skip to content

Commit 8a8edc8

Browse files
committed
Merge bitcoin/bitcoin#34741: refactor: Return std::optional from GetNameProxy/GetProxy
fa73ed4 refactor: Fix redundant conversion to std::string and then to std::string_view [performance-string-view-conversions] (MarcoFalke) fa270fd refactor: Return std::optional from GetProxy (MarcoFalke) faeac1a refactor: Return std::optional from GetNameProxy (MarcoFalke) Pull request description: Currently the getters have a mutable reference as inout param and return a bool to indicate success. This is confusing, because the success bool is redundant with the `IsValid()` state on the proxy object. So in theory, the functions could reset the mutable proxy object to an invalid state and return `void`. However, this would also be confusing, because devs can forget to check `IsValid()`. Fix all issues by using `std::optional<Proxy>`, where devs no longer have to check `IsValid()` manually, or a separate bool. Note that new code in the repo is already using `std::optional<Proxy>`, see `git grep 'std::optional<Proxy>' bitcoin-core/master`. Also, `std::optional<Proxy>` will enforce checking at compile time, whereas calling `Proxy::IsValid` is not enforced. ACKs for top commit: achow101: ACK fa73ed4 sedited: ACK fa73ed4 ViniciusCestarii: ACK fa73ed4 frankomosh: Code Review ACK fa73ed4. Good refactor, correctly replaces the bool + mutable reference output parameter pattern with `std::optional<Proxy>` across `GetProxy` and `GetNameProxy`. Semantics are preserved. Tree-SHA512: c6a1e1d1691958d2e6507e32e3484f96703fba03ccc710145ae2fb84b1254fb0e6e1d8d78e9b572daf5ea485247b73568704881762379b50bcf939a35494dd13
2 parents a5609fc + fa73ed4 commit 8a8edc8

8 files changed

Lines changed: 60 additions & 56 deletions

File tree

src/interfaces/node.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <cstdint>
2020
#include <functional>
2121
#include <memory>
22+
#include <optional>
2223
#include <string>
2324
#include <tuple>
2425
#include <vector>
@@ -123,7 +124,7 @@ class Node
123124
virtual void mapPort(bool enable) = 0;
124125

125126
//! Get proxy.
126-
virtual bool getProxy(Network net, Proxy& proxy_info) = 0;
127+
virtual std::optional<Proxy> getProxy(Network net) = 0;
127128

128129
//! Get number of connections.
129130
virtual size_t getNodeCount(ConnectionDirection flags) = 0;

src/net.cpp

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -439,20 +439,15 @@ CNode* CConnman::ConnectNode(CAddress addrConnect,
439439

440440
// Connect
441441
std::unique_ptr<Sock> sock;
442-
Proxy proxy;
443442
CService addr_bind;
444443
assert(!addr_bind.IsValid());
445444
std::unique_ptr<i2p::sam::Session> i2p_transient_session;
446445

447-
for (auto& target_addr: connect_to) {
446+
for (auto& target_addr : connect_to) {
448447
if (target_addr.IsValid()) {
449-
bool use_proxy;
450-
if (proxy_override.has_value()) {
451-
use_proxy = true;
452-
proxy = proxy_override.value();
453-
} else {
454-
use_proxy = GetProxy(target_addr.GetNetwork(), proxy);
455-
}
448+
const std::optional<Proxy> use_proxy{
449+
proxy_override.has_value() ? proxy_override : GetProxy(target_addr.GetNetwork()),
450+
};
456451
bool proxyConnectionFailed = false;
457452

458453
if (target_addr.IsI2P() && use_proxy) {
@@ -469,7 +464,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect,
469464
LOCK(m_unused_i2p_sessions_mutex);
470465
if (m_unused_i2p_sessions.empty()) {
471466
i2p_transient_session =
472-
std::make_unique<i2p::sam::Session>(proxy, m_interrupt_net);
467+
std::make_unique<i2p::sam::Session>(*use_proxy, m_interrupt_net);
473468
} else {
474469
i2p_transient_session.swap(m_unused_i2p_sessions.front());
475470
m_unused_i2p_sessions.pop();
@@ -489,8 +484,8 @@ CNode* CConnman::ConnectNode(CAddress addrConnect,
489484
addr_bind = conn.me;
490485
}
491486
} else if (use_proxy) {
492-
LogDebug(BCLog::PROXY, "Using proxy: %s to connect to %s\n", proxy.ToString(), target_addr.ToStringAddrPort());
493-
sock = ConnectThroughProxy(proxy, target_addr.ToStringAddr(), target_addr.GetPort(), proxyConnectionFailed);
487+
LogDebug(BCLog::PROXY, "Using proxy: %s to connect to %s\n", use_proxy->ToString(), target_addr.ToStringAddrPort());
488+
sock = ConnectThroughProxy(*use_proxy, target_addr.ToStringAddr(), target_addr.GetPort(), proxyConnectionFailed);
494489
} else {
495490
// no proxy needed (none set for target network)
496491
sock = ConnectDirectly(target_addr, conn_type == ConnectionType::MANUAL);
@@ -500,12 +495,14 @@ CNode* CConnman::ConnectNode(CAddress addrConnect,
500495
// the proxy, mark this as an attempt.
501496
addrman.get().Attempt(target_addr, fCountFailure);
502497
}
503-
} else if (pszDest && GetNameProxy(proxy)) {
504-
std::string host;
505-
uint16_t port{default_port};
506-
SplitHostPort(std::string(pszDest), port, host);
507-
bool proxyConnectionFailed;
508-
sock = ConnectThroughProxy(proxy, host, port, proxyConnectionFailed);
498+
} else if (pszDest) {
499+
if (const auto name_proxy = GetNameProxy()) {
500+
std::string host;
501+
uint16_t port{default_port};
502+
SplitHostPort(pszDest, port, host);
503+
bool proxyConnectionFailed;
504+
sock = ConnectThroughProxy(*name_proxy, host, port, proxyConnectionFailed);
505+
}
509506
}
510507
// Check any other resolved address (if any) if we fail to connect
511508
if (!sock) {
@@ -3120,9 +3117,10 @@ void CConnman::PrivateBroadcast::NumToOpenWait() const
31203117

31213118
std::optional<Proxy> CConnman::PrivateBroadcast::ProxyForIPv4or6() const
31223119
{
3123-
Proxy tor_proxy;
3124-
if (m_outbound_tor_ok_at_least_once.load() && GetProxy(NET_ONION, tor_proxy)) {
3125-
return tor_proxy;
3120+
if (m_outbound_tor_ok_at_least_once.load()) {
3121+
if (const auto tor_proxy = GetProxy(NET_ONION)) {
3122+
return tor_proxy;
3123+
}
31263124
}
31273125
return std::nullopt;
31283126
}
@@ -3479,10 +3477,11 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
34793477
return false;
34803478
}
34813479

3482-
Proxy i2p_sam;
3483-
if (GetProxy(NET_I2P, i2p_sam) && connOptions.m_i2p_accept_incoming) {
3484-
m_i2p_sam_session = std::make_unique<i2p::sam::Session>(gArgs.GetDataDirNet() / "i2p_private_key",
3485-
i2p_sam, m_interrupt_net);
3480+
if (connOptions.m_i2p_accept_incoming) {
3481+
if (const auto i2p_sam = GetProxy(NET_I2P)) {
3482+
m_i2p_sam_session = std::make_unique<i2p::sam::Session>(gArgs.GetDataDirNet() / "i2p_private_key",
3483+
*i2p_sam, m_interrupt_net);
3484+
}
34863485
}
34873486

34883487
// Randomize the order in which we may query seednode to potentially prevent connecting to the same one every restart (and signal that we have restarted)

src/netbase.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -706,13 +706,14 @@ bool SetProxy(enum Network net, const Proxy &addrProxy) {
706706
return true;
707707
}
708708

709-
bool GetProxy(enum Network net, Proxy &proxyInfoOut) {
709+
std::optional<Proxy> GetProxy(enum Network net)
710+
{
710711
assert(net >= 0 && net < NET_MAX);
711712
LOCK(g_proxyinfo_mutex);
712-
if (!proxyInfo[net].IsValid())
713-
return false;
714-
proxyInfoOut = proxyInfo[net];
715-
return true;
713+
if (!proxyInfo[net].IsValid()) {
714+
return std::nullopt;
715+
}
716+
return proxyInfo[net];
716717
}
717718

718719
bool SetNameProxy(const Proxy &addrProxy) {
@@ -723,12 +724,13 @@ bool SetNameProxy(const Proxy &addrProxy) {
723724
return true;
724725
}
725726

726-
bool GetNameProxy(Proxy &nameProxyOut) {
727+
std::optional<Proxy> GetNameProxy()
728+
{
727729
LOCK(g_proxyinfo_mutex);
728-
if(!nameProxy.IsValid())
729-
return false;
730-
nameProxyOut = nameProxy;
731-
return true;
730+
if (!nameProxy.IsValid()) {
731+
return std::nullopt;
732+
}
733+
return nameProxy;
732734
}
733735

734736
bool HaveNameProxy() {

src/netbase.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <cstdint>
1515
#include <functional>
1616
#include <memory>
17+
#include <optional>
1718
#include <string>
1819
#include <type_traits>
1920
#include <unordered_set>
@@ -179,7 +180,7 @@ std::string GetNetworkName(enum Network net);
179180
/** Return a vector of publicly routable Network names; optionally append NET_UNROUTABLE. */
180181
std::vector<std::string> GetNetworkNames(bool append_unroutable = false);
181182
bool SetProxy(enum Network net, const Proxy &addrProxy);
182-
bool GetProxy(enum Network net, Proxy &proxyInfoOut);
183+
std::optional<Proxy> GetProxy(enum Network net);
183184
bool IsProxy(const CNetAddr &addr);
184185
/**
185186
* Set the name proxy to use for all connections to nodes specified by a
@@ -199,7 +200,7 @@ bool IsProxy(const CNetAddr &addr);
199200
*/
200201
bool SetNameProxy(const Proxy &addrProxy);
201202
bool HaveNameProxy();
202-
bool GetNameProxy(Proxy &nameProxyOut);
203+
std::optional<Proxy> GetNameProxy();
203204

204205
using DNSLookupFn = std::function<std::vector<CNetAddr>(const std::string&, bool)>;
205206
extern DNSLookupFn g_dns_lookup;

src/node/interfaces.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ class NodeImpl : public Node
187187
args().WriteSettingsFile();
188188
}
189189
void mapPort(bool enable) override { StartMapPort(enable); }
190-
bool getProxy(Network net, Proxy& proxy_info) override { return GetProxy(net, proxy_info); }
190+
std::optional<Proxy> getProxy(Network net) override { return GetProxy(net); }
191191
size_t getNodeCount(ConnectionDirection flags) override
192192
{
193193
return m_context->connman ? m_context->connman->GetNodeCount(flags) : 0;

src/qt/clientmodel.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -287,10 +287,11 @@ void ClientModel::unsubscribeFromCoreSignals()
287287

288288
bool ClientModel::getProxyInfo(std::string& ip_port) const
289289
{
290-
Proxy ipv4, ipv6;
291-
if (m_node.getProxy((Network) 1, ipv4) && m_node.getProxy((Network) 2, ipv6)) {
292-
ip_port = ipv4.proxy.ToStringAddrPort();
293-
return true;
290+
const auto ipv4 = m_node.getProxy(NET_IPV4);
291+
const auto ipv6 = m_node.getProxy(NET_IPV6);
292+
if (ipv4 && ipv6) {
293+
ip_port = ipv4->proxy.ToStringAddrPort();
294+
return true;
294295
}
295296
return false;
296297
}

src/qt/optionsdialog.cpp

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -456,17 +456,14 @@ void OptionsDialog::updateDefaultProxyNets()
456456
proxyIpText = ui_proxy.ToStringAddrPort();
457457
}
458458

459-
Proxy proxy;
460-
bool has_proxy;
459+
const auto proxy_ipv4 = model->node().getProxy(NET_IPV4);
460+
ui->proxyReachIPv4->setChecked(proxy_ipv4 && proxy_ipv4->ToString() == proxyIpText);
461461

462-
has_proxy = model->node().getProxy(NET_IPV4, proxy);
463-
ui->proxyReachIPv4->setChecked(has_proxy && proxy.ToString() == proxyIpText);
462+
const auto proxy_ipv6 = model->node().getProxy(NET_IPV6);
463+
ui->proxyReachIPv6->setChecked(proxy_ipv6 && proxy_ipv6->ToString() == proxyIpText);
464464

465-
has_proxy = model->node().getProxy(NET_IPV6, proxy);
466-
ui->proxyReachIPv6->setChecked(has_proxy && proxy.ToString() == proxyIpText);
467-
468-
has_proxy = model->node().getProxy(NET_ONION, proxy);
469-
ui->proxyReachTor->setChecked(has_proxy && proxy.ToString() == proxyIpText);
465+
const auto proxy_onion = model->node().getProxy(NET_ONION);
466+
ui->proxyReachTor->setChecked(proxy_onion && proxy_onion->ToString() == proxyIpText);
470467
}
471468

472469
ProxyAddressValidator::ProxyAddressValidator(QObject *parent) :

src/rpc/net.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -613,14 +613,17 @@ static UniValue GetNetworksInfo()
613613
for (int n = 0; n < NET_MAX; ++n) {
614614
enum Network network = static_cast<enum Network>(n);
615615
if (network == NET_UNROUTABLE || network == NET_INTERNAL) continue;
616-
Proxy proxy;
617616
UniValue obj(UniValue::VOBJ);
618-
GetProxy(network, proxy);
619617
obj.pushKV("name", GetNetworkName(network));
620618
obj.pushKV("limited", !g_reachable_nets.Contains(network));
621619
obj.pushKV("reachable", g_reachable_nets.Contains(network));
622-
obj.pushKV("proxy", proxy.IsValid() ? proxy.ToString() : std::string());
623-
obj.pushKV("proxy_randomize_credentials", proxy.m_tor_stream_isolation);
620+
if (const auto proxy = GetProxy(network)) {
621+
obj.pushKV("proxy", proxy->ToString());
622+
obj.pushKV("proxy_randomize_credentials", proxy->m_tor_stream_isolation);
623+
} else {
624+
obj.pushKV("proxy", std::string());
625+
obj.pushKV("proxy_randomize_credentials", false);
626+
}
624627
networks.push_back(std::move(obj));
625628
}
626629
return networks;

0 commit comments

Comments
 (0)