FFFF config: allow setting -proxy per network by vasild · Pull Request #32425 · bitcoin/bitcoin · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

config: allow setting -proxy per network #32425

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

Merged
merged 2 commits into from
Jun 10, 2025

Conversation

vasild
Copy link
Contributor
@vasild vasild commented May 6, 2025

-proxy=addr:port specifies the proxy for all networks (except I2P). Previously only the Tor proxy could have been specified separately via ->.

Make it possible to specify separately the proxy for IPv4, IPv6, Tor and CJDNS by e.g. -proxy=addr:port=ipv6. Or remove the proxy for a given network, e.g. -proxy=0=cjdns.

Resolves: #24450

@DrahtBot
Copy link
Contributor
DrahtBot commented May 6, 2025

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Code Coverage & Benchmarks

For details see: https://corech 8000 eck.dev/bitcoin/bitcoin/pulls/32425.

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK pinheadmz, caesrcd, danielabrozzoni, 1440000bytes

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #32699 (docs: adds correct updated documentation links by Zeegaths)
  • #31974 (Drop testnet3 by Sjors)

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

Comment on lines -1192 to 1221
for ([[maybe_unused]] const auto& [arg, unix] : std::vector<std::pair<std::string, bool>>{
// arg name UNIX socket support
{"-i2psam", false},
{"-onion", true},
{"-proxy", true},
{"-rpcbind", false},
{"-torcontrol", false},
{"-whitebind", false},
{"-zmqpubhashblock", true},
{"-zmqpubhashtx", true},
{"-zmqpubrawblock", true},
{"-zmqpubrawtx", true},
{"-zmqpubsequence", true},
for ([[maybe_unused]] const auto& [param_name, unix, suffix_allowed] : std::vector<std::tuple<std::string, bool, bool>>{
// arg name UNIX socket support =suffix allowed
{"-i2psam", false, false},
{"-onion", true, false},
{"-proxy", true, true},
{"-bind", false, true},
{"-rpcbind", false, false},
{"-torcontrol", false, false},
{"-whitebind", false, false},
{"-zmqpubhashblock", true, false},
{"-zmqpubhashtx", true, false},
{"-zmqpubrawblock", true, false},
{"-zmqpubrawtx", true, false},
{"-zmqpubsequence", true, false},
}) {
Copy link
Contributor Author
@vasild vasild May 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: I sneaked in -bind here. I guess before it was omitted because this loop did not support =whatever suffix. Now it does.

Copy link
@caesrcd caesrcd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 6a9f046

I have reviewed the code, unit tests, and functional tests. I built the project and ran a node using the -proxy=0=cjdns parameter to verify the behavior. Confirmed that CJDNS correctly bypasses the general proxy as intended. Manual testing was performed on Arch Linux, and the node successfully connected over CJDNS directly without using the proxy.

Copy link
Member
@pablomartin4btc pablomartin4btc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the user sets -proxy=addr:port=tor then -> shouldn't be allowed, no? Otherwise one could set 2 diff proxies for Tor(?).

Also, in Tor's documentation:

-proxy=ip:port  Set the proxy server. If SOCKS5 is selected (default), this proxy
                server will be used to try to reach .onion addresses as well.

So, shouldn't -proxy=0=cjdns be the default if -cjdnsreachable when -proxy=addr:port?

@DrahtBot DrahtBot mentioned this pull request May 7, 2025
@laanwj laanwj added the P2P label May 7, 2025
@vasild vasild force-pushed the proxy_per_network branch from 6a9f046 to 2059eaa Compare May 7, 2025 12:19
@vasild
Copy link
Contributor Author
vasild commented May 7, 2025

6a9f04688f...2059eaa692: address suggestions

If the user sets -proxy=addr:port=tor then -> shouldn't be allowed, no? Otherwise one could set 2 diff proxies for Tor(?).

I think that is ok, assuming the expectation is that later options override earlier ones. For example, without this PR, -proxy=x -> is supposed to set the Tor proxy to y, overriding the earlier x. Updated tor.md to mention that.

So, shouldn't -proxy=0=cjdns be the default if -cjdnsreachable when -proxy=addr:port?

Could be, but I do not like these "automatically set x only if y and z are true, otherwise something else". That would also change the default behavior in a breaking way - for people that use -proxy which does support CJDNS it will stop working. Maybe there are no such users, but we can't know for sure.

@pablomartin4btc
Copy link
Member

Otherwise one could set 2 diff proxies for Tor(?).

I think that is ok, assuming the expectation is that later options override earlier ones. For example, without this PR, -proxy=x -> is supposed to set the Tor proxy to y, overriding the earlier x. Updated tor.md to mention that.

Ok.

So, shouldn't -proxy=0=cjdns be the default if -cjdnsreachable when -proxy=addr:port?

Could be, but I do not like these "automatically set x only if y and z are true, otherwise something else". That would also change the default behavior in a breaking way - for people that use -proxy which does support CJDNS it will stop working. Maybe there are no such users, but we can't know for sure.

Ok, but since the previous statement (-proxy=...) from Tor's doc combined with:

- Make automatic outbound connections only to .onion addresses.

Maybe we should give a warning at least (and perhaps suggesting: -proxy=0=cjdns) because that (-proxy=ip[:<port>] - -cjdnsreachable) would make CJDNS not to work (?).

I think a more long term solution could be to add the possibility of having a separate proxy for CJDNS, as suggested on the issue by other commenters there.

Copy link
@caesrcd caesrcd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 2059eaa

I have tested the code.

@vasild
Copy link
Contributor Author
vasild commented May 8, 2025

Maybe we should give a warning at least (and perhaps suggesting: -proxy=0=cjdns) because that (-proxy=ip[:<port>] - -cjdnsreachable) would make CJDNS not to work (?).

That would make automatic outbound connections to Tor peers only. Still manual outbound and inbound connections would work and be possible to/from CJDNS peers. Maybe a warning in the lines of "Automatic outbound connections will only be made to Tor peers, if you want to include CJDNS, then use - in addition". Or maybe not? In either case adding such a warning seems to be out of the scope of this PR whose purpose is to be able to specify proxy per network.

I think a more long term solution could be to add the possibility of having a separate proxy for CJDNS, as suggested on the issue by other commenters there.

That is made possible by this PR: -proxy=addr:port=cjdns.

8000

@1440000bytes
Copy link

Concept ACK

Multiple proxies for different networks would be useful. Might need release notes if this eventually gets merged.

Copy link
Member
@pinheadmz pinheadmz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 2059eaa

Built and ran all tests on macos/arm64. Reviewed both commits and left a few nits.
Played with the feature on mainnet, and connected to all networks:

         ipv4    ipv6   onion   cjdns   total   block  manual
in          0       0       0       0       0
out         1       1       2       7      11       0       7
total       1       1       2       7      11

Even used tor's ipv4 and unix sockets for separate proxies ;-)

bcd -debug=tor -debug=net -proxy=unix:/Users/matthewzipkin/tor/sock -proxy=127.0.0.1:9050=ipv6 -cjdnsreachable -proxy=0=cjdns

Show Signature
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

ACK 2059eaa692ff614c41dee50f4bc2d2946e5d42af
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCAAdFiEE5hdzzW4BBA4vG9eM5+KYS2KJyToFAmgiWz0ACgkQ5+KYS2KJ
yTp0Ag/+JZCDfs0ILvoCRuuUN74qNh1vlvS9eqie3d32quX4wjYE8ZQC4Ov18xlv
8nOCKzDu369bixp1N6HlQXqa41w0x0KbAshMHWsHwolKr5MumQTfOp6mcnMaD1J4
zbS1Jbyigs7x+ukeVLW22CH9I64GUGQuizmzuWA2/cR0ehFtkLsKyG/5HCSeQU4H
/VzzEGcYNeqKKroLKKswqbkcVSrzhz8I1P7ZOEMhYQ6kDTZ5YVKGhbqcb8n2S8nJ
Tr5GY72gx8WY+LwgLM3nuesus8jYSVKSwleWCGxm2uqKdAkLcBQajBnJy1kgIYO0
ieAMypz9OF8zYls6VvhuTZseTvMWIM0ai37/1YUS8R3Dk3c9habUhv2GoxEpHmZb
2vcJ133qtVRNj9ZWAy987lmXKz1m3imrH+SGGUdG0etaHjs6qz0JnFxv11/xTzaB
SBFc8nalkIG/RZqy72i3WskMdOxkywkVx2fzN5RYZdpxSb2krlaOVln3On60H8iW
Ewnk+MioS0s/1mvp+u31YG5GzRhqO4mCtQMG5IE2W+k58q1gMvq6uQtasgWGu9LX
ZihaLz2cxeHxCqQFaFP1rL54IB/2MWXWXOBCEp24JQT/LXAfq1sacikd1PzaI/T8
tVQcYWs1W3ZORKjqMhWaPEpXurz5mstul/zV/BkRcod6E9XgJPw=
=65/9
-----END PGP SIGNATURE-----

pinheadmz's public key is on openpgp.org

if (IsUnixSocketPath(proxy_str)) {
proxy = Proxy{proxy_str, /*tor_stream_isolation=*/proxyRandomize};
} else {
const std::optional<CService> addr{Lookup(proxy_str, DEFAULT_TOR_SOCKS_PORT, fNameLookup)};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4af5b4d

The default port here is a little funny since a user could set -proxy=127.0.0.1=cjdns right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that is the same in master so no change in behavior by this PR. In master it is using a magic number 9050 whereas here it uses the constant DEFAULT_TOR_SOCKS_PORT.

-proxy=127.0.0.1=cjdns would be interpreted as -proxy=127.0.0.1:9050=cjdns which might be the correct config, or if not then the user could use -proxy=127.0.0.1:1234=cjdns to specify another port.

Personally, I would favor a more dumb implementation that does not do such automations and guessings on behalf of the user. Such an implementation would require the port to always be provided and refuse to start if not.

vasild and others added 2 commits May 13, 2025 12:09
`-proxy=addr:port` specifies the proxy for all networks (except I2P).
Previously only the Tor proxy could have been specified separately via
`-

Make it possible to specify separately the proxy for IPv4, IPv6, Tor and
CJDNS by e.g. `-proxy=addr:port=ipv6`. Or remove the proxy for a given
network, e.g. `-proxy=0=cjdns`.

Resolves: bitcoin#24450
Also change the formatting of `tor.md` to have more horizonal space for
the text.

Co-authored-by: Matthew Zipkin <pinheadmz@gmail.com>
@vasild vasild force-pushed the proxy_per_network branch from 2059eaa to e98c51f Compare May 13, 2025 10:15
@vasild
Copy link
Contributor Author
vasild commented May 13, 2025

2059eaa692...e98c51fcce: address suggestions

Copy link
Member
@pinheadmz pinheadmz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK e98c51f

Trivial changes since last ACK. Built and tested again on mainnet, this time added i2p as well, connected to peers on every network we support. Tried various proxy settings.

The code change is small and mostly just contained in init.cpp. We used to call SetProxy() on every network type with the same proxy endpoint, this new code parses more fine-grained config options and sets separate proxies based on the options.

Show Signature
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

ACK e98c51fcce9ae3f441a416cab32a5c85756c6c64
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCAAdFiEE5hdzzW4BBA4vG9eM5+KYS2KJyToFAmgjTV8ACgkQ5+KYS2KJ
yToKAw/6AgyTgGUOnk+VxgZGTTFufgNES5uvasHJtpkvcNYf9boWGpVQXBxf9ePc
BR7ly5C1+Tmvv6X36FwLE+mhNbXHIK178lfWFs+CMMeeuEThwR7LapGSbdAZGa+l
RxXxAx49/Ns5wMnMXPS+7mDp3CKAk1HRm1u1AN5k99RcyXdG5QUqfCb5QctckTUZ
jS17RuzONdJxW34Xd+p2nfsbKYUBy0YQPfLyxjy4e3KaStmpQTtp0HIKampli4t4
GhJiD+Yxj3ohJHqMS7so7jFo6nXqYw9k8wNUdaZTySBwMk2vDzRYesoBuXQZqM+j
xV9KReg1zxbtJTtW4cC38Rr3qRJJm4AKUNQmybs5aDfT07UAe2Ocd+b2lX97Pg4L
EyFCneylgs9mY+XH6UJpbOMihGWjAzZ63dRGrnMEFwZuNOmSBCSqPgQNjqSyBnU1
Cwj8liKCzr+mYwgWSA1M57BJGc0ZYeIPOEi8NEBzwejtQN6ljESmtWXh3kgKcXyb
VE2e3KJvCTTtdjI8r6nk2cNGKDMwgzeJp1DAAMEj2xOT7rI0qYc1tdr4HUGhhl0w
TiCeCenZhgPyTocW0xVFTzAmvhm+WCHp6Epyucjo0hnK4esw965z2N3B+4tmCfMY
B6VJFHuUqaerSIlvFzI8QpJsP9UBUUe2VS+XXhBv1VnlNuGewDM=
=PiAP
-----END PGP SIGNATURE-----

pinheadmz's public key is on openpgp.org

@DrahtBot DrahtBot requested a review from caesrcd May 13, 2025 13:50
Copy link
@caesrcd caesrcd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reACK e98c51f

Copy link
Contributor
@danielabrozzoni danielabrozzoni left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review ACK e98c51f

I have reviewed the code, and it looks good to me.
I run the tests locally and did some very limited manual testing, mimicking the functional test behavior (passing in -proxy=...=network and checking the getnetworkinfo output)

Copy link
Member
@luke-jr luke-jr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably an improvement as-is, but might want to think through the name proxy logic

return InitError(strprintf(_("Unrecognized network in -proxy='%s': '%s'"), param_value, net_str));
}
}
if (ipv4_proxy.IsValid()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These conditions aren't needed. SetProxy itself just returns false if it's not valid.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. But I prefer to be explicit rather than feed SetProxy() an invalid value and rely on it doing the "right thing". It is not documented what SetProxy() would do with an invalid input, so I prefer to have these checks.

Comment on lines +1627 to +1630
} else if (net_str == "ipv4") {
ipv4_proxy = name_proxy = proxy;
} else if (net_str == "ipv6") {
ipv6_proxy = name_proxy = proxy;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this logic is ideal. If you set an all-network proxy, but then disable it for IPv6, you might be expecting name resolution to use the proxy. Or maybe not.

Copy link
Contributor Author
@vasild vasild May 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would require some convoluted juggling with the parameters. Like:

  1. -proxy=addr:port=ipv6 sets the "ipv6" and "name" proxy, so that just a single -proxy=1.2.3.4:5678=ipv6 works as expected. However:
  2. -proxy=0=ipv6 removes only the "ipv6" proxy and not the "name" proxy, so that what you describe works: -proxy=addr:port -proxy=0=ipv6.

Another option would be to provide a separate name proxy, e.g. -proxy=addr:port=name or -proxy=addr:port=dns. But then users will probably forget to set it and be surprised that -proxy=addr:port=ipv4 does DNS requests without of the proxy. Then it would be tempting for us to automatically set the "name" proxy from the "ipv4" or "ipv6" proxy which is another convoluted automation.

I prefer to keep it simple as it is now, without having mismatching enable/disable logic (1. and 2. above) or automatically setting parameters based on other parameters.

Proxy cjdns_proxy;
for (const std::string& param_value : args.GetArgs("-proxy")) {
const auto eq_pos{param_value.rfind('=')};
const std::string proxy_str{param_value.substr(0, eq_pos)}; // e.g. 127.0.0.1:9050=ipv4 -> 127.0.0.1:9050
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

string_view?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would make the string_view point to the temporary returned by substr(). That temporary is destroyed after the end of the statement, so the string_view remains with a dangling pointer. Like in the example in https://en.cppreference.com/w/cpp/string/basic_string/operator_basic_string_view which says "// Bad: holds a dangling pointer".

Or a small standalone program to demonstrate:

int main(int, char**)
{
    std::string s{"abcd"};
    std::string_view sv{s.substr(2)};
    std::cout << sv << "\n";
    return 0;
}

Compile with clang -fsanitize=address and run:

==13945==ERROR: AddressSanitizer: stack-use-after-scope on address ...

@1440000bytes
Copy link
1440000bytes commented May 19, 2025

Configured 2 tor proxies with different circuits for ipv4 and ipv6 and they are working as expected:

$ curl --socks5-hostname 127.0.0.1:9050 http://ipv4.icanhazip.com
45.90.185.109

$ curl --socks5-hostname [::1]:9053 http://ipv6.icanhazip.com
2605:6400:30:f174:1:1:1:1

Used these proxies to run bitcoind:

bitcoind -signet -proxy=127.0.0.1:9050=ipv4 -proxy=[::1]:9053=ipv6 

I see the proxies in getnetworkinfo and some outbound peers in getpeerinfo:

  {
      "name": "ipv4",
      "limited": false,
      "reachable": true,
      "proxy": "127.0.0.1:9050",
      "proxy_randomize_credentials": true
    },
    {
      "name": "ipv6",
      "limited": false,
      "reachable": true,
      "proxy": "[::1]:9053",
      "proxy_randomize_credentials": true
    },

However, I am getting an error when I stop bitcoind in the logs:

2025-05-19T22:28:07Z Shutdown: In progress...
2025-05-19T22:28:07Z addcon thread exit
2025-05-19T22:28:07Z dnsseed thread exit
2025-05-19T22:28:07Z msghand thread exit
2025-05-19T22:28:07Z net thread exit
2025-05-19T22:28:08Z [error] Error while reading proxy response

It could be because of unreliable Tor connectivity. I tried increasing the timeout in

std::chrono::milliseconds g_socks5_recv_timeout = 20s;
but it made no difference.

Copy link
@1440000bytes 1440000bytes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK e98c51f

Signature
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

ACK e98c51fcce9ae3f441a416cab32a5c85756c6c64
-----BEGIN PGP SIGNATURE-----

iHUEARYKAB0WIQSSUwYqT5LWNFkIXKYtIwUgISpZAQUCaCuzGQAKCRAtIwUgISpZ
AVt3AP98Co6T1/S4RqaIWypoL4NI1B1PhTPdRdFdvPP0sHWxIgD/SlBxLKNBIehf
tvLSnyIV9cvCBRefydIJCTf+dS06tAw=
=D/ae
-----END PGP SIGNATURE-----

Comment on lines +1599 to +1600
const auto eq_pos{param_value.rfind('=')};
const std::string proxy_str{param_value.substr(0, eq_pos)}; // e.g. 127.0.0.1:9050=ipv4 -> 127.0.0.1:9050
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In ca5781e "config: allow setting -proxy per network"

nit: Split()? (from src/util/string.h)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about this:

diff --git a/src/init.cpp b/src/init.cpp
index 77dc74f690..08ec964e25 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -1190,14 +1190,20 @@ bool CheckHostPortOptions(const ArgsManager& args) {
         {"-zmqpubhashtx",    true,                false},
         {"-zmqpubrawblock",  true,                false},
         {"-zmqpubrawtx",     true,                false},
         {"-zmqpubsequence",  true,                false},
     }) {
         for (const std::string& param_value : args.GetArgs(param_name)) {
-            const std::string param_value_hostport{
-                suffix_allowed ? param_value.substr(0, param_value.rfind('=')) : param_value};
+            const auto parts{util::SplitString(param_value, '=')};
+            if (!suffix_allowed && parts.size() >= 2) {
+                return InitError(strprintf(_("Invalid value for %s: contains '=': '%s'"), param_name, param_value));
+            }
+            if (parts.size() >= 3) {
+                return InitError(strprintf(_("Invalid value for %s: contains too many '=': '%s'"), param_name, param_value));
+            }
+            const auto param_value_hostport{parts.at(0)};
             std::string host_out;
             uint16_t port_out{0};
             if (!SplitHostPort(param_value_hostport, port_out, host_out)) {
 #ifdef HAVE_SOCKADDR_UN
                 // Allow unix domain sockets for some options e.g. unix:/some/file/path
                 if (!unix || !param_value.starts_with(ADDR_PREFIX_UNIX)) {
@@ -1568,20 +1574,20 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
     Proxy ipv4_proxy;
     Proxy ipv6_proxy;
     Proxy onion_proxy;
     Proxy name_proxy;
     Proxy cjdns_proxy;
     for (const std::string& param_value : args.GetArgs("-proxy")) {
-        const auto eq_pos{param_value.rfind('=')};
-        const std::string proxy_str{param_value.substr(0, eq_pos)}; // e.g. 127.0.0.1:9050=ipv4 -> 127.0.0.1:9050
+        const auto parts{util::SplitString(param_value, '=')};
+        const auto& proxy_str{parts.at(0)};
         std::string net_str;
-        if (eq_pos != std::string::npos) {
-            if (eq_pos + 1 == param_value.length()) {
+        if (parts.size() == 2) {
+            net_str = ToLower(parts[1]);
+            if (net_str.empty()) {
                 return InitError(strprintf(_("Invalid -proxy address or hostname, ends with '=': '%s'"), param_value));
             }
-            net_str = ToLower(param_value.substr(eq_pos + 1)); // e.g. 127.0.0.1:9050=ipv4 -> ipv4
         }
 
         Proxy proxy;
         if (!proxy_str.empty() && proxy_str != "0") {
             if (IsUnixSocketPath(proxy_str)) {
                 proxy = Proxy{proxy_str, /*tor_stream_isolation=*/proxyRandomize};
diff --git a/test/functional/feature_proxy.py b/test/functional/feature_proxy.py
index ba8a0212a6..651bdb8d4c 100755
--- a/test/functional/feature_proxy.py
+++ b/test/functional/feature_proxy.py
@@ -446,12 +446,22 @@ class ProxyTest(BitcoinTestFramework):
 
         self.log.info("Test passing trailing '=' raises expected init error")
         self.nodes[1].extra_args = ["-proxy=127.0.0.1:9050="]
         msg = "Error: Invalid -proxy address or hostname, ends with '=': '127.0.0.1:9050='"
         self.nodes[1].assert_start_raises_init_error(expected_msg=msg)
 
+        self.log.info("Test passing '=' raises expected init error when '=' is not allowed")
+        self.nodes[1].extra_args = ["-"]
+        msg = "Error: Invalid value for -onion: contains '=': 'a=b'"
+        self.nodes[1].assert_start_raises_init_error(expected_msg=msg)
+
+        self.log.info("Test passing too many '=' raises expected init error")
+        self.nodes[1].extra_args = ["-proxy=127.0.0.1:9050=ipv4=x"]
+        msg = "Error: Invalid value for -proxy: contains too many '=': '127.0.0.1:9050=ipv4=x'"
+        self.nodes[1].assert_start_raises_init_error(expected_msg=msg)
+
         self.log.info("Test passing unrecognized network raises expected init error")
         self.nodes[1].extra_args = ["-proxy=127.0.0.1:9050=foo"]
         msg = "Error: Unrecognized network in -proxy='127.0.0.1:9050=foo': 'foo'"
         self.nodes[1].assert_start_raises_init_error(expected_msg=msg)
 
         self.log.info("Test passing proxy only for IPv6")

Better? Append to #32727?

Comment on lines +1222 to +1224
for (const std::string& param_value : args.GetArgs(param_name)) {
const std::string param_value_hostport{
suffix_allowed ? param_value.substr(0, param_value.rfind('=')) : param_value};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In ca5781e "config: allow setting -proxy per network"

nit: I think using Split() would make this easier to read

luke-jr pushed a commit to luke-jr/bitcoin that referenced this pull request Jun 6, 2025
`-proxy=addr:port` specifies the proxy for all networks (except I2P).
Previously only the Tor proxy could have been specified separately via
`-

Make it possible to specify separately the proxy for IPv4, IPv6, Tor and
CJDNS by e.g. `-proxy=addr:port=ipv6`. Or remove the proxy for a given
network, e.g. `-proxy=0=cjdns`.

Resolves: bitcoin#24450

Github-Pull: bitcoin#32425
Rebased-From: ca5781e
@glozow
Copy link
Member
glozow commented Jun 10, 2025

Needs release note?

@glozow glozow merged commit 157bbd0 into bitcoin:master Jun 10, 2025
19 checks passed
@vasild vasild deleted the proxy_per_network branch June 11, 2025 08:38
vasild added a commit to vasild/bitcoin that referenced this pull request Jun 11, 2025
vasild added a commit to vasild/bitcoin that referenced this pull request Jun 11, 2025
@vasild
Copy link
Contributor Author
vasild commented Jun 11, 2025

Needs release note?

Right. Done in #32727

vasild added a commit to vasild/bitcoin that referenced this pull request Jun 13, 2025
Co-authored-by: Jan B <608446+janb84@users.noreply.github.com>
TheCharlatan added a commit to TheCharlatan/rust-bitcoinkernel that referenced this pull request Jun 14, 2025
…9e030d56343

d9e030d56343 kernel: Fix bitcoin-chainstate for windows
cc4ac564cc38 kernel: Add Purpose section to header documentation
bfdf605296ce kernel: Add pure kernel bitcoin-chainstate
35099f39b7ea kernel: Add functions to get the block hash from a block
fae94070a72e kernel: Add block index utility functions to C header
d5d377859785 kernel: Add function to read block undo data from disk to C header
43f6039b7b48 kernel: Add functions to read block from disk to C header
54cdfcdc68e6 kernel: Add function for copying block data to C header
18cab45358c3 kernel: Add functions for the block validation state to C header
033e86a06cbc kernel: Add validation interface to C header
9398f9ea4e14 kernel: Add interrupt function to C header
86340a490541 kernel: Add import blocks function to C header
f11dc01bba94 kernel: Add chainstate load options for in-memory dbs in C header
be9fc18dd54f kernel: Add options for reindexing in C header
7947a9b500fc kernel: Add block validation to C header
d5ace1f8ea96 kernel: Add chainstate loading when instantiating a ChainstateManager
47ff652cf08f kernel: Add chainstate manager option for setting worker threads
106898e0c25f kernel: Add chainstate manager object to C header
3eadf1ccbe1c kernel: Add notifications context option to C header
98b1454a987a kernel: Add chain params context option to C header
ca8d6ee344b7 kernel: Add kernel library context object
96f5ebe97748 kernel: Add logging to kernel library C header
906a19748152 kernel: Introduce initial kernel C header API
4b8ac9eacd1b Merge bitcoin/bitcoin#32680: ci: Rewrite test-each-commit as py script
157bbd0a07c0 Merge bitcoin/bitcoin#32425: config: allow setting -proxy per network
ebec7bf3895c Merge bitcoin/bitcoin#32572: doc: Remove stale sections in dev notes
011a8c5f0168 Merge bitcoin/bitcoin#32696: doc: make `-DWITH_ZMQ=ON` explicit on `build-unix.md`
fe39050a66c7 Merge bitcoin/bitcoin#32678: guix: warn and abort when SOURCE_DATE_EPOCH is set
692fe280c232 Merge bitcoin/bitcoin#32713: doc: fuzz: fix AFL++ link
c1d4253d316e Merge bitcoin/bitcoin#32711: doc: add missing packages for BSDs (cmake, gmake, curl) to depends/README.md
89526deddf87 doc: add missing packages for BSDs (cmake, gmake, curl) to depends/README.md
a39b7071cfb4 doc: fuzz: fix AFL++ link
dff208bd5a14 Merge bitcoin/bitcoin#32708: rpc, doc: update `listdescriptors` RCP help
d978a43d054d Merge bitcoin/bitcoin#32408: tests: Expand HTTP coverage to assert libevent behavior
f3bbc746647d Merge bitcoin/bitcoin#32406: policy: uncap datacarrier by default
b44514b87633 rpc, doc: update `listdescriptors` RCP help
32d4e92b9ac8 doc: make `-DWITH_ZMQ=ON` explicit on `build-unix.md`
e2174378aa8a Merge bitcoin/bitcoin#32539: init: Configure reachable networks before we start the RPC server
2053c4368472 Merge bitcoin/bitcoin#32675: test: wallet: cover wallet passphrase with a null char
fa9cfdf3be75 ci: [doc] fix url redirect
fac60b9c4839 ci: Rewrite test-each-commit as py script
ae024137bda9 Merge bitcoin/bitcoin#32496: depends: drop `ltcg` for Windows Qt
6a2ff6790929 Merge bitcoin/bitcoin#32679: doc: update tor docs to use bitcoind binary from path
fd4399cb9c69 Merge bitcoin/bitcoin#32602: fuzz: Add target for coins database
f94167512dc9 Merge bitcoin/bitcoin#32676: test: apply microsecond precision to test framework logging
0dcb45290cf8 Merge bitcoin/bitcoin#32607: rpc: Note in fundrawtransaction doc, fee rate is for package
4ce53495e5e1 doc: update tor docs to use bitcoind binary from path
a5e98dc3ae63 Merge bitcoin/bitcoin#32651: cmake: Replace deprecated `qt6_add_translation` with `qt6_add_lrelease`
9653ebc05360 depends: remove support for Windows Qt LTO builds
7cfbb8575e1f test: wallet: cover wallet passphrase with a null char
5c4a0f8009ce guix: warn and abort when SOURCE_DATE_EPOCH is set
4af72d8b0892 Merge bitcoin/bitcoin#32647: build: add -Wthread-safety-pointer
a980918f51d7 Merge bitcoin/bitcoin#32568: depends: use "mkdir -p" when installing xproto
ed179e0a6528 test: apply microsecond precision to test framework logging
e872a566f251 Merge bitcoin/bitcoin#32644: doc: miscellaneous changes
e50312eab0b5 doc: fix typos
c797e50ddae9 ci: update codespell to 2.4.1
21ee656337b0 doc: Remove obselete link in notificator.cpp
ee4406c04af0 doc: update URLs
2d819fa4dff9 Merge bitcoin/bitcoin#29032: signet: omit commitment for some trivial challenges
f999c3775c12 Merge bitcoin/bitcoin#32449: wallet: init, don't error out when loading legacy wallets
f98e1aaf34e3 rpc: Note in fundrawtransaction doc, fee rate is for package
1c6602399be6 Merge bitcoin/bitcoin#32662: doc: Remove build instruction for running `clang-tidy`
4b1b36acb48f doc: Remove build instruction for running `clang-tidy`
9e105107bf52 Merge bitcoin/bitcoin#32656: depends: don't install & then delete sqlite pkgconf
72a5aa9b791e depends: don't install & then delete sqlite pkgconf
18cf727429e9 cmake: Replace deprecated `qt6_add_translation` with `qt6_add_lrelease`
83bfe1485c37 build: add -Wthread-safety-pointer
e639ae05315e Update leveldb subtree to latest upstream
240a4fb95d5b Squashed 'src/leveldb/' changes from 113db4962b..aba469ad6a
a189d636184b add release note for datacarriersize default change
a141e1bf501b Add more OP_RETURN mempool acceptance functional tests
0b4048c73385 datacarrier: deprecate startup arguments for future removal
63091b79e70b test: remove unnecessary -datacarriersize args from tests
9f36962b07ef policy: uncap datacarrier by default
4b1d48a6866b Merge bitcoin/bitcoin#32598: walletdb: Log additional exception error messages for corrupted wallets
b933813386ef Merge bitcoin/bitcoin#32619: wallet, rpc, gui: List legacy wallets with a message about migration
053bda5d9fb3 Merge bitcoin/bitcoin#32460: fs: remove `_POSIX_C_SOURCE` defining
9393aeeca4b1 Merge bitcoin/bitcoin#32641: Update libmultiprocess subtree to fix clang-tidy errors
5471e29d0570 Merge bitcoin/bitcoin#32304: test: test MAX_SCRIPT_SIZE for block validity
9f6565488fc1 Merge commit '154af1eea1170f5626aa1c5f19cc77d1434bcc9d' into HEAD
154af1eea117 Squashed 'src/ipc/libmultiprocess/' changes from 35944ffd23fa..27c7e8e5a581
c540ede1cbca Merge bitcoin/bitcoin#32633: windows: Use predefined `RC_INVOKED` macro instead of custom one
cfc42ae5b7ef fuzz: add a target for the coins database
55f1c2ac8beb windows: Use predefined `RC_INVOKED` macro instead of custom one
14c16e81598a Merge bitcoin/bitcoin#32582: log: Additional compact block logging
aad5938c49f9 Merge bitcoin/bitcoin#32516: test: add MAX_DISCONNECTED_TX_POOL_BYTES, chainlimits coverage
1062df81eec7 Merge bitcoin/bitcoin#32634: build: Add resource file and manifest to `bitcoin.exe`
83df64d7491b log: Stats when fulfilling GETBLOCKTXN
370c59261269 Merge bitcoin/bitcoin#32630: test: fix sync function in rpc_psbt.py
dbb2d4c3d547 windows: Add application manifest to `bitcoin.exe`
df82c2dc17e3 windows: Add resource file for `bitcoin.exe`
3733ed2dae3d log: Size of missing tx'es when reconstructing compact block
4df4df45d7bc test: fix sync function in rpc_psbt.py
84aa484d45e2 test: fix transaction_graph_test reorg test
eaf44f376784 test: check chainlimits respects on reorg
47894367b583 functional test: add MAX_DISCONNECTED_TX_POOL_BYTES coverage
f3a444c45fb4 gui: Disallow loading legacy wallets
09955172f38a wallet, rpc: Give warning in listwalletdir for legacy wallets
ad9a13fc424e walletdb: Log additional exception error messages for corrupted wallets
46e14630f7fe fuzz: move the coins_view target's body into a standalone function
56d878c4650c fuzz: avoid underflow in coins_view target
36bcee05dc71 log: Log start of compact block initialization.
24e5fd3bedce fs: remove _POSIX_C_SOURCE defining
f16c8c67bf13 tests: Expand HTTP coverage to assert libevent behavior
fac00d4ed361 doc: Move CI-must-pass requirement into readme section
fab79c1a250d doc: Clarify and move "hygienic commit" note
fac8b0519799 doc: Clarify strprintf size specifier note
faaf34ad7253 doc: Remove section about RPC alias via function pointer
2222d61e1ce5 doc: Remove section about RPC arg names in table
fa00b8c02c9d doc: Remove section about include guards
fad6cd739b63 doc: Remove dev note section on includes
fa6623d85af1 doc: Remove file name section
7777fb8bc749 doc: Remove shebang section
faf65f05312b doc: Remove .gitignore section
faf2094f2511 doc: Remove note about removed ParsePrechecks
fa69c5b170f5 doc: Remove -disablewallet from dev notes
df9ebbf659d5 depends: use "mkdir -p" when installing xproto
6ee32aaaca4a test: signet tool genpsbt and solvepsbt commands
0a99d99fe4cb signet: miner skips PSBT step for OP_TRUE
cdfb70e5a6a9 signet: split decode_psbt miner helper
86e1111239cd test: verify node skips loading legacy wallets during startup
12ff4be9c724 test: ensure -rpcallowip is compatible with RFC4193
c02bd3c1875a config: Explain RFC4193 and CJDNS interaction in help and init error
f728b6b11100 init: Configure reachable networks before we start the RPC server
9f94de5bb54f wallet: init, don't error out when loading legacy wallets
e98c51fcce9a doc: update tor.md to mention the new -proxy=addr:port=tor
ca5781e23a8f config: allow setting -proxy per network
b1ea542ae651 test: test MAX_SCRIPT_SIZE for block validity
REVERT: 9f83f8b46c84 kernel: build monolithic static lib
REVERT: 1417e0b3b1b0 kernel: Fix bitcoin-chainstate for windows
REVERT: 4f07590a8bd6 kernel: Add Purpose section to header documentation
REVERT: 58c01a82c163 kernel: Add pure kernel bitcoin-chainstate
REVERT: 0416a292f545 kernel: Add functions to get the block hash from a block
REVERT: 8d25dfd1b2a2 kernel: Add block index utility functions to C header
REVERT: eacf99dd3c28 kernel: Add function to read block undo data from disk to C header
REVERT: 3c012048c2f1 kernel: Add functions to read block from disk to C header
REVERT: 85f5264462e0 kernel: Add function for copying block data to C header
REVERT: f136ca589153 kernel: Add functions for the block validation state to C header
REVERT: 9d7e19ee522d kernel: Add validation interface to C header
REVERT: 51555301a882 kernel: Add interrupt function to C header
REVERT: 61c4ac9c8e1f kernel: Add import blocks function to C header
REVERT: 4153ab77084e kernel: Add chainstate load options for in-memory dbs in C header
REVERT: cb128288a0d9 kernel: Add options for reindexing in C header
REVERT: 7ead2a92be50 kernel: Add block validation to C header
REVERT: 9262ce715448 kernel: Add chainstate loading when instantiating a ChainstateManager
REVERT: 594b060da476 kernel: Add chainstate manager option for setting worker threads
REVERT: 7384b7325d5f kernel: Add chainstate manager object to C header
REVERT: 7920e23c22b8 kernel: Add notifications context option to C header
REVERT: c0a86769e784 kernel: Add chain params context option to C header
REVERT: 3769d12882f9 kernel: Add kernel library context object
REVERT: f7b435493bd7 kernel: Add logging to kernel library C header
REVERT: 62d0122c7ed0 kernel: Introduce initial kernel C header API

git-subtree-dir: libbitcoinkernel-sys/bitcoin
git-subtree-split: d9e030d56343bb452d86169f77ddfb64f7160235
vasild added a commit to vasild/bitcoin that referenced this pull request Jun 20, 2025
Co-authored-by: Jan B <608446+janb84@users.noreply.github.com>
vasild B621 added a commit to vasild/bitcoin that referenced this pull request Jun 25, 2025
Co-authored-by: Jan B <608446+janb84@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Apparently CJDNS network does not work with Tor on mainnet.
0