refactor: Return std::optional from GetProxy
What changed, and why it matters
This commit is a straightforward code cleanup: it changes the GetProxy function so that instead of returning true/false and writing a proxy value into a caller-provided variable, it returns the proxy value directly using std::optional when a proxy exists, or nothing when it doesn't. All callers are updated to match the new pattern. There is no change to security behavior, network logic, or user-facing functionality.
No security action needed. This is a safe refactoring commit. Normal code review and CI testing are sufficient.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch refactors GetProxy from an output-parameter style (bool GetProxy(Network, Proxy&)) to a std::optional-returning style (std::optional
Changed components
src/netbase.cpp GetProxy implementationsrc/interfaces/node.h Node interface getProxy methodsrc/node/interfaces.cpp Node interface implementationsrc/net.cpp CConnman::ConnectNode, PrivateBroadcast::ProxyForIPv4or6, CConnman::Startsrc/qt/clientmodel.cpp getProxyInfosrc/qt/optionsdialog.cpp updateDefaultProxyNetssrc/rpc/net.cpp GetNetworksInfoInspect captured patch +45 / −44
diff --git a/src/interfaces/node.h b/src/interfaces/node.h
index 6a051d8d..f6d8209f 100644
--- a/src/interfaces/node.h
+++ b/src/interfaces/node.h
@@ -19,6 +19,7 @@
#include <cstdint>
#include <functional>
#include <memory>
+#include <optional>
#include <string>
#include <tuple>
#include <vector>
@@ -123,7 +124,7 @@ public:
virtual void mapPort(bool enable) = 0;
//! Get proxy.
- virtual bool getProxy(Network net, Proxy& proxy_info) = 0;
+ virtual std::optional<Proxy> getProxy(Network net) = 0;
//! Get number of connections.
virtual size_t getNodeCount(ConnectionDirection flags) = 0;
diff --git a/src/net.cpp b/src/net.cpp
index 9dd95dab..2c20c4aa 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -438,16 +438,11 @@ CNode* CConnman::ConnectNode(CAddress addrConnect,
assert(!addr_bind.IsValid());
std::unique_ptr<i2p::sam::Session> i2p_transient_session;
- for (auto& target_addr: connect_to) {
+ for (auto& target_addr : connect_to) {
if (target_addr.IsValid()) {
- bool use_proxy;
- Proxy proxy;
- if (proxy_override.has_value()) {
- use_proxy = true;
- proxy = proxy_override.value();
- } else {
- use_proxy = GetProxy(target_addr.GetNetwork(), proxy);
- }
+ const std::optional<Proxy> use_proxy{
+ proxy_override.has_value() ? proxy_override : GetProxy(target_addr.GetNetwork()),
+ };
bool proxyConnectionFailed = false;
if (target_addr.IsI2P() && use_proxy) {
@@ -464,7 +459,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect,
LOCK(m_unused_i2p_sessions_mutex);
if (m_unused_i2p_sessions.empty()) {
i2p_transient_session =
- std::make_unique<i2p::sam::Session>(proxy, m_interrupt_net);
+ std::make_unique<i2p::sam::Session>(*use_proxy, m_interrupt_net);
} else {
i2p_transient_session.swap(m_unused_i2p_sessions.front());
m_unused_i2p_sessions.pop();
@@ -484,8 +479,8 @@ CNode* CConnman::ConnectNode(CAddress addrConnect,
addr_bind = conn.me;
}
} else if (use_proxy) {
- LogDebug(BCLog::PROXY, "Using proxy: %s to connect to %s\n", proxy.ToString(), target_addr.ToStringAddrPort());
- sock = ConnectThroughProxy(proxy, target_addr.ToStringAddr(), target_addr.GetPort(), proxyConnectionFailed);
+ LogDebug(BCLog::PROXY, "Using proxy: %s to connect to %s\n", use_proxy->ToString(), target_addr.ToStringAddrPort());
+ sock = ConnectThroughProxy(*use_proxy, target_addr.ToStringAddr(), target_addr.GetPort(), proxyConnectionFailed);
} else {
// no proxy needed (none set for target network)
sock = ConnectDirectly(target_addr, conn_type == ConnectionType::MANUAL);
@@ -3114,9 +3109,10 @@ void CConnman::PrivateBroadcast::NumToOpenWait() const
std::optional<Proxy> CConnman::PrivateBroadcast::ProxyForIPv4or6() const
{
- Proxy tor_proxy;
- if (m_outbound_tor_ok_at_least_once.load() && GetProxy(NET_ONION, tor_proxy)) {
- return tor_proxy;
+ if (m_outbound_tor_ok_at_least_once.load()) {
+ if (const auto tor_proxy = GetProxy(NET_ONION)) {
+ return tor_proxy;
+ }
}
return std::nullopt;
}
@@ -3472,10 +3468,11 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
return false;
}
- Proxy i2p_sam;
- if (GetProxy(NET_I2P, i2p_sam) && connOptions.m_i2p_accept_incoming) {
- m_i2p_sam_session = std::make_unique<i2p::sam::Session>(gArgs.GetDataDirNet() / "i2p_private_key",
- i2p_sam, m_interrupt_net);
+ if (connOptions.m_i2p_accept_incoming) {
+ if (const auto i2p_sam = GetProxy(NET_I2P)) {
+ m_i2p_sam_session = std::make_unique<i2p::sam::Session>(gArgs.GetDataDirNet() / "i2p_private_key",
+ *i2p_sam, m_interrupt_net);
+ }
}
// 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)
diff --git a/src/netbase.cpp b/src/netbase.cpp
index f7339a33..5ac7d22a 100644
--- a/src/netbase.cpp
+++ b/src/netbase.cpp
@@ -706,13 +706,14 @@ bool SetProxy(enum Network net, const Proxy &addrProxy) {
return true;
}
-bool GetProxy(enum Network net, Proxy &proxyInfoOut) {
+std::optional<Proxy> GetProxy(enum Network net)
+{
assert(net >= 0 && net < NET_MAX);
LOCK(g_proxyinfo_mutex);
- if (!proxyInfo[net].IsValid())
- return false;
- proxyInfoOut = proxyInfo[net];
- return true;
+ if (!proxyInfo[net].IsValid()) {
+ return std::nullopt;
+ }
+ return proxyInfo[net];
}
bool SetNameProxy(const Proxy &addrProxy) {
diff --git a/src/netbase.h b/src/netbase.h
index 27e1e59d..88cc6981 100644
--- a/src/netbase.h
+++ b/src/netbase.h
@@ -14,6 +14,7 @@
#include <cstdint>
#include <functional>
#include <memory>
+#include <optional>
#include <string>
#include <type_traits>
#include <unordered_set>
@@ -179,7 +180,7 @@ std::string GetNetworkName(enum Network net);
/** Return a vector of publicly routable Network names; optionally append NET_UNROUTABLE. */
std::vector<std::string> GetNetworkNames(bool append_unroutable = false);
bool SetProxy(enum Network net, const Proxy &addrProxy);
-bool GetProxy(enum Network net, Proxy &proxyInfoOut);
+std::optional<Proxy> GetProxy(enum Network net);
bool IsProxy(const CNetAddr &addr);
/**
* Set the name proxy to use for all connections to nodes specified by a
diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp
index 84fd5bb7..a8d91bf6 100644
--- a/src/node/interfaces.cpp
+++ b/src/node/interfaces.cpp
@@ -187,7 +187,7 @@ public:
args().WriteSettingsFile();
}
void mapPort(bool enable) override { StartMapPort(enable); }
- bool getProxy(Network net, Proxy& proxy_info) override { return GetProxy(net, proxy_info); }
+ std::optional<Proxy> getProxy(Network net) override { return GetProxy(net); }
size_t getNodeCount(ConnectionDirection flags) override
{
return m_context->connman ? m_context->connman->GetNodeCount(flags) : 0;
diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp
index cd7d9e32..8c1598e7 100644
--- a/src/qt/clientmodel.cpp
+++ b/src/qt/clientmodel.cpp
@@ -287,10 +287,11 @@ void ClientModel::unsubscribeFromCoreSignals()
bool ClientModel::getProxyInfo(std::string& ip_port) const
{
- Proxy ipv4, ipv6;
- if (m_node.getProxy((Network) 1, ipv4) && m_node.getProxy((Network) 2, ipv6)) {
- ip_port = ipv4.proxy.ToStringAddrPort();
- return true;
+ const auto ipv4 = m_node.getProxy(NET_IPV4);
+ const auto ipv6 = m_node.getProxy(NET_IPV6);
+ if (ipv4 && ipv6) {
+ ip_port = ipv4->proxy.ToStringAddrPort();
+ return true;
}
return false;
}
diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp
index 12446206..f68e5825 100644
--- a/src/qt/optionsdialog.cpp
+++ b/src/qt/optionsdialog.cpp
@@ -456,17 +456,14 @@ void OptionsDialog::updateDefaultProxyNets()
proxyIpText = ui_proxy.ToStringAddrPort();
}
- Proxy proxy;
- bool has_proxy;
+ const auto proxy_ipv4 = model->node().getProxy(NET_IPV4);
+ ui->proxyReachIPv4->setChecked(proxy_ipv4 && proxy_ipv4->ToString() == proxyIpText);
- has_proxy = model->node().getProxy(NET_IPV4, proxy);
- ui->proxyReachIPv4->setChecked(has_proxy && proxy.ToString() == proxyIpText);
+ const auto proxy_ipv6 = model->node().getProxy(NET_IPV6);
+ ui->proxyReachIPv6->setChecked(proxy_ipv6 && proxy_ipv6->ToString() == proxyIpText);
- has_proxy = model->node().getProxy(NET_IPV6, proxy);
- ui->proxyReachIPv6->setChecked(has_proxy && proxy.ToString() == proxyIpText);
-
- has_proxy = model->node().getProxy(NET_ONION, proxy);
- ui->proxyReachTor->setChecked(has_proxy && proxy.ToString() == proxyIpText);
+ const auto proxy_onion = model->node().getProxy(NET_ONION);
+ ui->proxyReachTor->setChecked(proxy_onion && proxy_onion->ToString() == proxyIpText);
}
ProxyAddressValidator::ProxyAddressValidator(QObject *parent) :
diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp
index 5c54e207..66be9824 100644
--- a/src/rpc/net.cpp
+++ b/src/rpc/net.cpp
@@ -617,14 +617,17 @@ static UniValue GetNetworksInfo()
for (int n = 0; n < NET_MAX; ++n) {
enum Network network = static_cast<enum Network>(n);
if (network == NET_UNROUTABLE || network == NET_INTERNAL) continue;
- Proxy proxy;
UniValue obj(UniValue::VOBJ);
- GetProxy(network, proxy);
obj.pushKV("name", GetNetworkName(network));
obj.pushKV("limited", !g_reachable_nets.Contains(network));
obj.pushKV("reachable", g_reachable_nets.Contains(network));
- obj.pushKV("proxy", proxy.IsValid() ? proxy.ToString() : std::string());
- obj.pushKV("proxy_randomize_credentials", proxy.m_tor_stream_isolation);
+ if (const auto proxy = GetProxy(network)) {
+ obj.pushKV("proxy", proxy->ToString());
+ obj.pushKV("proxy_randomize_credentials", proxy->m_tor_stream_isolation);
+ } else {
+ obj.pushKV("proxy", std::string());
+ obj.pushKV("proxy_randomize_credentials", false);
+ }
networks.push_back(std::move(obj));
}
return networks;
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.