Skip to content

Conversation

@b-l-u-e
Copy link

@b-l-u-e b-l-u-e commented Jun 16, 2025

This PR fixes two related issues with address discovery when using explicit bind addresses in Bitcoin Core:

When using -bind=0.0.0.0:port (or -bind=::), the Discover() function was not being executed because the code only checked the bind_on_any flag. This led to two problems:

  • The node would not discover its own local addresses if an explicit "any" bind was used.
  • The functional test feature_bind_port_discover.py would fail, as it expects local addresses to be discovered in these cases.

This PR:

  1. Checks both bind_on_any and any bind addresses using IsBindAny()
    Ensures Discover() runs when binding to 0.0.0.0 or ::, even if specified explicitly.
  2. Ensures correct address discovery
    The node will now discover its own addresses when using explicit "any" binds, matching user expectations and fixing the test.
  3. Maintains backward compatibility
    The semantic meaning of bind_on_any is preserved as defined in net.h:

    "True if the user did not specify -bind= or -whitebind= and thus we should bind on 0.0.0.0 (IPv4) and :: (IPv6)"

  4. Updates the test to use dynamic ports
    The functional test feature_bind_port_discover.py is updated to use dynamic ports instead of hardcoded ones, improving reliability.

How this PR Differs from #31492

  • Preserves the semantic meaning of bind_on_any (see net.h).
  • Uses a simpler approach: checks IsBindAny() on bind addresses, without modifying GetListenPort().
  • Avoids code duplication with DefaultOnionServiceTarget().

References

Closes #31293

The #31336 has the overall test failure and requires both this PR and #33362 to be fully resolved.

@DrahtBot
Copy link
Contributor

DrahtBot commented Jun 16, 2025

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

Code Coverage & Benchmarks

For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/32757.

Reviews

See the guideline for information on the review process.

Type Reviewers
Stale ACK PeterWrighten, yuvicc, pinheadmz, mzumsande, vasild, frankomosh

If your review is incorrectly listed, please copy-paste <!--meta-tag:bot-skip--> into the comment that the bot should ignore.

Conflicts

No conflicts as of last run.

@yuvicc
Copy link
Contributor

yuvicc commented Jun 16, 2025

Concept ACK

Removing duplicate code from DefaultOnionServiceTarget() is better IMO

@b-l-u-e b-l-u-e force-pushed the net-fix-discover-bind-any branch from b17208d to 776b7ee Compare June 16, 2025 16:23
Copy link

@PeterWrighten PeterWrighten left a comment

Choose a reason for hiding this comment

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

utACK 776b7ee
I consider you could report error message when running in original codebase, and in comparison with this PR one. Or you can find related issue and declare to fix them, it could be clearer for reviewers.

Copy link
Contributor

@yuvicc yuvicc left a comment

Choose a reason for hiding this comment

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

lgtm ACK 776b7ee5855f7572798eff3014030bcc53aa7393

Copy link
Contributor

@vasild vasild left a comment

Choose a reason for hiding this comment

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

Approach ACK 776b7ee585

@b-l-u-e b-l-u-e force-pushed the net-fix-discover-bind-any branch from 776b7ee to 99f8a6b Compare July 4, 2025 05:45
@b-l-u-e
Copy link
Author

b-l-u-e commented Jul 4, 2025

vasild thanks for the suggestions...about the self.extra_args configuration.

In your patch, node 2 only has -whitebind=0.0.0.0 without any onion bind:

['-discover', f'-whitebind=0.0.0.0:{self.bind_ports[2]}'], # Explicit -whitebind=0.0.0.0

However, when I tried this configuration, I encountered port conflicts because the test framework automatically adds an onion bind to node 2, which conflicts with the port already used by node 1.

Test Results:

Without dummy onion bind (your suggested configuration):

Error: Unable to bind to 127.0.0.1:12866 on this computer. Bitcoin Core is probably already running.
Error: Failed to listen on any port. Use -listen=0 if you want this.

With dummy onion bind current implementation:

TestFramework (INFO): Tests successful

The issue is that when using only -whitebind=0.0.0.0, the test framework automatically adds an onion bind to the same node, causing a port conflict with other nodes in the test.

To avoid this, I added a dummy onion bind:

['-discover', f'-whitebind=0.0.0.0:{self.bind_ports[2]}', f'-bind=127.0.0.1:{self.bind_ports[2]+100}=onion']

This ensures the test runs successfully while still testing the intended -whitebind=0.0.0.0 functionality.

@DrahtBot
Copy link
Contributor

DrahtBot commented Jul 4, 2025

🚧 At least one of the CI tasks failed.
Task lint: https://github.com/bitcoin/bitcoin/runs/45342616996
LLM reason (✨ experimental): The CI failure is caused by lint errors due to trailing whitespace and missing trailing newline in the code.

Hints

Try to run the tests locally, according to the documentation. However, a CI failure may still
happen due to a number of reasons, for example:

  • Possibly due to a silent merge conflict (the changes in this pull request being
    incompatible with the current code in the target branch). If so, make sure to rebase on the latest
    commit of the target branch.

  • A sanitizer issue, which can only be found by compiling with the sanitizer and running the
    affected test.

  • An intermittent issue.

Leave a comment here, if you need help tracking down a confusing failure.

@DrahtBot DrahtBot removed the CI failed label Jul 4, 2025
@b-l-u-e b-l-u-e force-pushed the net-fix-discover-bind-any branch from 4fdc0b1 to ad3f60b Compare July 4, 2025 10:43
@b-l-u-e b-l-u-e requested a review from vasild July 4, 2025 10:55
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 ad3f60b0ea59dbbe7aedcfdcca1caddefffe6976

Built and tested on macos/arm64 and debian/x86. Reviewed code changes which are minimal, this PR searches bind settings for 0.0.0.0 specifically to call Discover() which attempts to add local addresses for peer advertising. Also adds test coverage using 1.1.1.1 and 2.2.2.2 which I was able to set up and check locally on both platforms. Also tested on main.

I would really like to know if its possible to run this test in CI as vasild suggested here and if so, should probably be added to this PR

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

ACK ad3f60b0ea59dbbe7aedcfdcca1caddefffe6976
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCAAdFiEE5hdzzW4BBA4vG9eM5+KYS2KJyToFAmh2awsACgkQ5+KYS2KJ
yTouuhAAmT1tLlOOKdhryZE9K+44Bcsn6prMoLono71Dzf+U+hkQpfxaCcwlI17c
hIW51zz/KZWTudgkDLSWU1RMhCDxMk8XFRdh47TD13OhOVrFJF3Al/uCrMFTXOB5
mPX2c7v6xOvx6DRlqZlCNDKKTOV1gPIM3+vyScmPA68Vh4ibxwzfYK9Lr0ss92fA
ceyCZttPOV6v57dazDn2Lm3siGWfS0+urnwf02TIlShklfW6+juz9AWfa8cmHw8E
GjO0D/r6BNW0TSeHSgt8jpxkVuGxl6opVkn+295hkZ4m9PM44eq7C1avK3yL9exl
LlsGdk9e/vsesJZne+hnppux1xivbfRbze0Z2J3fOpSdckU8mL8TpJlnyoRbQXAo
l3Cawmarwjm7sSQBRZsnAHNw6dN8qQ3ICkCPvK86UG8GLXhG76hcQBZY/NmwMqg7
hl8Np64L3bpH8dHU1Q/9gxHy6h3lPw9GNiOZFaQVvGQZicTzY7WxjhHcAevEHDvu
h9JxUBUPyroHxQkX2vDVBiyLM5pz8FtUOb7MWj5K0bFE1fg6IuY8XZog4BC/zWUL
eTLX330l883y2WoUrILAyrSe1B0HSt0SEh5yOqdwaBAuJ3lcvpht50D+0Z3wPvXU
FShlGSxgvUHBAaDSf/7aG3d48uYkoSKKnek5i65RZIG1oViucUE=
=snJ5
-----END PGP SIGNATURE-----

pinheadmz's public key is on openpgp.org

@DrahtBot DrahtBot requested review from PeterWrighten and yuvicc July 15, 2025 14:57
@b-l-u-e b-l-u-e force-pushed the net-fix-discover-bind-any branch from ad3f60b to 894fc0c Compare July 16, 2025 06:11
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.

Thanks for fixing the nit in the test.

In general, nit-fixes should be squashed (not added as an extra commit) so the final commit history is clean and perfect ;-)

Also I think you rebased on master which is ok, but it makes review slightly harder because my local copy of your branch is now dozens of commits different from the current state of the PR. I used git range-diff to isolate the changes which is why its not like, a super hard rule, but again in general, try not to rebase on master unless you have to (to fix a conflict, include other merged commits, etc)

@b-l-u-e b-l-u-e force-pushed the net-fix-discover-bind-any branch 2 times, most recently from 57588f7 to a9b7542 Compare July 17, 2025 00:23
@b-l-u-e b-l-u-e requested a review from pinheadmz July 17, 2025 10:14
Copy link
Contributor

@vasild vasild left a comment

Choose a reason for hiding this comment

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

Almost ACK a9b7542b6ea1af770d93cbbf5bb55dae6841334f

I encountered port conflicts because the test framework automatically adds an onion bind to node 2,

Hmm, I think it is not the test framework but bitcoind itself that adds the onion bind. To figure out how bitcoind is started, e.g. for nodes[2] I look at /tmp/bitcoin_func_test_.../node2/regtest/debug.log for the lines like:

...
Config file arg: [regtest] shrinkdebugfile="0"
Config file arg: [regtest] unsafesqlitesync="1"
Command-line arg: bind="127.0.0.1:23642=onion"
Command-line arg: datadir="/tmp/bitcoin_func_test_h7qvveos/node2"
...

which conflicts with the port already used by node 1

Are you sure it is nodes[1] and nodes[2] conflicting? What is the error message? What is the output of ./test/functional/combine_logs.py |grep 'Bound to'? I got nodes[2] to bind the whitebind and tor on the same port, see my comment below.

@b-l-u-e b-l-u-e force-pushed the net-fix-discover-bind-any branch from 8613ebd to 1dc6b1e Compare July 22, 2025 16:39
Copy link
Contributor

@vasild vasild left a comment

Choose a reason for hiding this comment

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

ACK 1dc6b1e8b04363107b4b44cbf42f8a25f2efabfe

Thank you!

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 1dc6b1e8b04363107b4b44cbf42f8a25f2efabfe

Built and tested on macos/arm64. Reviewed code, minimal changes since last ACK, addressing clean-ups in the test. Tested on mainnet and compared against master to check that local address was discovered when -bind=0.0.0.0

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

ACK 1dc6b1e8b04363107b4b44cbf42f8a25f2efabfe
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCAAdFiEE5hdzzW4BBA4vG9eM5+KYS2KJyToFAmiA9C8ACgkQ5+KYS2KJ
yTpmvhAAkvyMzMl7iYnSoSFwv/PJs0zGzXbr+iYzp8IrIoNNS7tTZj5S3a4uc6LA
i2aWgAG8NfEcW696R42h6bL2XTIRmLvxbYQyhpZAZRWK9oydK27e2sopsdQFJVxa
+wWcRqjhPLt7vOqzp/BkEQwlU60GLEZ7k52/xfs873F9MhU/u37DD2PkcNvf9nAQ
Y3fNlJYFEA1RBNIBLWTEwkYtKeWS+n2un+nj1APTqHH6rNHRODSYWe/LU2GG2et0
r2JTPEr0bADMi0P5+K8CZEUSsIcnDEcYc+UmayDEKvQu6kvZHXg0LQuNMHRlo7fM
uns5ZK5O+e4AVlBdICGRC70+qWL2C7WOd87gOFqsUYYyz1poYgnvEYHb+mHQh9Ti
juXof2FvxmV6cgdyZJtsAW78poT7Iwkb5Kn3767gum+Y4cGAAOUthVkwxFSZLBuI
j8T5oNC6AUcKegNhrwYD8uZJta/RNGW0Rzud1MQklE4lvmAwSKPJbDR9yHhuwh7R
XFaJmjIR7lE+RGEisQ3fO9FI8KmiUZgovHLaRzBITcTDINhtbyakWeanZHgqto8+
KCsIsoaM/Gk+QCvZifCfdrMxSuTickcCU8XQS53RhTgskAYxluQ4DFGputFi55T7
rXH1m+1hjgF0CmHF4PtiR8uApS1M8KmEnveepIUNbrrjxnTll6o=
=2P0/
-----END PGP SIGNATURE-----

pinheadmz's public key is on openpgp.org

Copy link
Contributor

@mzumsande mzumsande left a comment

Choose a reason for hiding this comment

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

Does the changed test succeed for others? I tried to follow the instructions and get

 test  2025-07-23T21:50:01.787971Z TestFramework (ERROR): Address 1.1.1.1 not found in node0's local addresses: [] 
 test  2025-07-23T21:50:01.788044Z TestFramework (ERROR): Assertion failed 
                                   Traceback (most recent call last):
                                     File "XXX/bitcoin/32757_bind0000/test/functional/test_framework/test_framework.py", line 195, in main
                                       self.run_test()
                                     File "XXX/32757_bind0000/build/test/functional/feature_bind_port_discover.py", line 97, in run_test
                                       assert False

It also fails on master with the different error assert found_addr1 like #31336 describes.
As an aside, ifconfig is deprecated by many linux versions and should probably be replaced by ip (though not necessary to do it here).

[Edit]: Using Ubuntu 24.04.2 LTS

@pinheadmz
Copy link
Member

Test worked for me on mac and failed as expected without 1.1.1.1 and 2.2.2.2

On my system the command was
ifconfig en0 alias 1.1.1.1

@mzumsande
Copy link
Contributor

mzumsande commented Jul 24, 2025

ifconfig en0 alias 1.1.1.1

ok, you don't add it to the loopback interface.
But the instructions for Linux
ifconfig lo:0 1.1.1.1/32 up && ifconfig lo:1 2.2.2.2/32 up # to set up
do that, while IFF_LOOPBACK addresses are being filtered out here. So I don't think the problem from #31336 is fixed by this as the OP says.

@achow101
Copy link
Member

Also seeing @mzumsande's observation if I add the addresses to loopback, but not if I add them to a different interface.

I think it's reasonable to filter out all loopback addresses, so the resolution is probably to just update the instructions to have the addresses bound to a non-loopback interface.

@pinheadmz
Copy link
Member

If @b-l-u-e is going to retouch to update the instructions in the test comment I'd also really like to see those instructions executed in a CI test as well.

@mzumsande
Copy link
Contributor

mzumsande commented Jul 24, 2025

For me it would also be ok to leave the resolution of #31336 for a separate PR - but this PR shouldn't claim to solve the issue then.

@b-l-u-e b-l-u-e force-pushed the net-fix-discover-bind-any branch 2 times, most recently from 51f8d08 to 210dd40 Compare July 25, 2025 05:19
@b-l-u-e
Copy link
Author

b-l-u-e commented Jul 25, 2025

found the issues raised and found the cause.

The test was failing because the instructions were wrong. The original instructions told users to use loopback interfaces (lo:0, lo:1), but the code filters out loopback addresses (line 340 in netif.cpp).

This is what issue #31336 reported - users following the instructions got empty local addresses.

mzumsande: identified that the test was failing with "Address 1.1.1.1 not found in node0's local addresses: []" and noticed that ifconfig is deprecated. he pointed out that the loopback filtering means this doesn't actually fix #31336.

pinheadmz: confirmed the test worked on macOS with non-loopback interfaces (ifconfig en0 alias 1.1.1.1) and failed as expected without the addresses.

achow101: confirmed mzumsande observation that loopback addresses don't work, but non-loopback addresses do work and suggested updating the instructions to use non-loopback interfaces.

I tested both scenarios

  • Non-loopback interface (wlo1): Test passes successfully
  • Loopback interface (lo): Test fails as expected (validates your concerns)

This makes the loopback filtering working as intended.

updated the test instructions to be more educational and flexible

  • Uses ip commands for Linux
  • Uses placeholder names instead of assuming specific interfaces
  • Provides instructions for Linux, macOS, and FreeBSD
  • Explains why loopback interfaces don't work

regarding #31336
This doesn't fix the core loopback filtering issue in #31336. However, it does fix the immediate problem where users following the test instructions get confused. The test works perfectly when users follow the correct instructions.

The test logic itself is correct - the problem was jthe instructions were wrong.

@Zeegaths
Copy link

Zeegaths commented Jul 27, 2025

I ran these commands on Ubuntu 22.04:

sudo ip addr add 1.1.1.1/32 dev wlo1
sudo ip addr add 2.2.2.2/32 dev wlo1

./build/bin/bitcoind -regtest -bind=0.0.0.0:18444 -discover -daemon
./build/bin/bitcoin-cli -regtest getnetworkinfo | grep -A 10 "localaddresses"

Result on master:
"localaddresses": [
],
"warnings": [
"This is a pre-release test build - use at your own risk - do not use for mining or merchant applications"
]

Result on PR:
"localaddresses": [
{
"address": "1.1.1.1",
"port": 18444,
"score": 1
},
{
"address": "2.2.2.2",
"port": 18444,
"score": 1
}

Conclusion:
PR successfully fixes the issue described in #31293. When using explicit -bind=0.0.0.0, the Discover() function now correctly runs and discovers local addresses, whereas on master it returns empty localaddresses.

Copy link
Contributor

@vasild vasild left a comment

Choose a reason for hiding this comment

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

ACK 210dd40

It suffices to prefix only the first line of the commit message with "test:".

@DrahtBot DrahtBot requested a review from pinheadmz September 9, 2025 08:47
@vasild
Copy link
Contributor

vasild commented Sep 11, 2025

I would really like to know if its possible to run this test in CI ...

IFF_LOOPBACK addresses are being filtered out here. So I don't think the problem from #31336 is fixed by this as the OP says.

Both resolved in #33362

@b-l-u-e
Copy link
Author

b-l-u-e commented Nov 3, 2025

Are you still working on this?

Yes am still working on this
Caught up on something else

@DrahtBot DrahtBot requested a review from mzumsande December 7, 2025 22:06
@b-l-u-e b-l-u-e force-pushed the net-fix-discover-bind-any branch from 210dd40 to e0463f3 Compare December 7, 2025 22:53
@b-l-u-e b-l-u-e requested a review from vasild December 7, 2025 22:56
Copy link
Contributor

@vasild vasild left a comment

Choose a reason for hiding this comment

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

ACK e0463f3

Copy link
Contributor

@frankomosh frankomosh 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 e0463f3

Maybe you could clarify the PR description to reflect that it closes #31293, and #31336 would only be fully resolved with #33362. I think this would accurately reflect that #31336 requires both PRs.

@b-l-u-e b-l-u-e force-pushed the net-fix-discover-bind-any branch from e0463f3 to 8c5f2b4 Compare January 5, 2026 17:59
@b-l-u-e b-l-u-e force-pushed the net-fix-discover-bind-any branch from 8c5f2b4 to 37855ae Compare January 5, 2026 19:00
@b-l-u-e b-l-u-e requested a review from frankomosh January 5, 2026 19:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Discover() will not run if listening on any address with an explicit bind=0.0.0.0

10 participants