feature_bind_extra.py test fails in test_runner if new nodes are added #33250

issue w0xlt openend this issue on August 24, 2025
  1. w0xlt commented at 6:00 am on August 24, 2025: contributor

    When new nodes are added to the feature_bind_extra.py test, it succeeds if run individually, but fails if run via test_runner with the error message:

     0TestFramework (ERROR): Unexpected exception
     1Traceback (most recent call last):
     2  File "/home/node/test/functional/test_framework/test_framework.py", line 191, in main
     3    self.setup()
     4  File "/home/node/test/functional/test_framework/test_framework.py", line 349, in setup
     5    self.setup_network()
     6  File "/home/node/build/test/functional/feature_bind_extra.py", line 100, in setup_network
     7    self.setup_nodes()
     8  File "/home/node/test/functional/test_framework/test_framework.py", line 462, in setup_nodes
     9    self.start_nodes()
    10  File "/home/node/test/functional/test_framework/test_framework.py", line 603, in start_nodes
    11    node.wait_for_rpc_connection()
    12  File "/home/node/test/functional/test_framework/test_node.py", line 284, in wait_for_rpc_connection
    13    raise FailedToStartError(self._node_msg(
    14test_framework.test_node.FailedToStartError: [node 4] bitcoind exited with status 1 during initialization. Error: Unable to bind to 127.0.0.1:13388 on this computer. Bitcoin Core is probably already running.
    15Error: Failed to listen on any port. Use -listen=0 if you want this.
    

    I noticed this when creating more tests for #33231

    It seems to be related to multiple nodes concurrently using the same port, but I’m not sure if it’s expected behavior or if it should happen.

    Specifically for the feature_bind_extra.py test, it can be resolved by reusing the same node. Multiple nodes were being created unnecessarily. I fixed this in the first commit of #33231 (https://github.com/bitcoin/bitcoin/pull/33231/commits/6b448e2eab007c9abd9f6be3c96a533641a73abc). This makes this test more efficient and prevents the error from occurring, but it does not address the underlying problem (if there is one).

    To reproduce the error, that’s the patch:

     0diff --git a/test/functional/feature_bind_extra.py b/test/functional/feature_bind_extra.py
     1index 6b53de188f..9aac53f064 100755
     2--- a/test/functional/feature_bind_extra.py
     3+++ b/test/functional/feature_bind_extra.py
     4@@ -27,7 +27,7 @@ class BindExtraTest(BitcoinTestFramework):
     5         # Avoid any -bind= on the command line. Force the framework to avoid
     6         # adding -bind=127.0.0.1.
     7         self.bind_to_localhost_only = False
     8-        self.num_nodes = 3
     9+        self.num_nodes = 6
    10 
    11     def skip_test_if_missing_module(self):
    12         # Due to OS-specific network stats queries, we only run on Linux.
    13@@ -69,6 +69,33 @@ class BindExtraTest(BitcoinTestFramework):
    14         )
    15         port += 1
    16 
    17+        # Node1, both -bind=... and -bind=...=onion.
    18+        self.expected.append(
    19+            [
    20+                [f"-bind=127.0.0.1:{port}", f"-bind=127.0.0.1:{port + 1}=onion"],
    21+                [(loopback_ipv4, port), (loopback_ipv4, port + 1)]
    22+            ],
    23+        )
    24+        port += 2
    25+
    26+        # Node1, both -bind=... and -bind=...=onion.
    27+        self.expected.append(
    28+            [
    29+                [f"-bind=127.0.0.1:{port}", f"-bind=127.0.0.1:{port + 1}=onion"],
    30+                [(loopback_ipv4, port), (loopback_ipv4, port + 1)]
    31+            ],
    32+        )
    33+        port += 2
    34+
    35+        # Node1, both -bind=... and -bind=...=onion.
    36+        self.expected.append(
    37+            [
    38+                [f"-bind=127.0.0.1:{port}", f"-bind=127.0.0.1:{port + 1}=onion"],
    39+                [(loopback_ipv4, port), (loopback_ipv4, port + 1)]
    40+            ],
    41+        )
    42+        port += 2
    43+
    44         self.extra_args = list(map(lambda e: e[0], self.expected))
    45         self.setup_nodes()
    
  2. maflcko commented at 9:09 am on August 24, 2025: member
    There is a limit on the number of nodes MAX_NODES and ports that can be used per test. You’ll have to stay under it, or increase the limit.
  3. w0xlt commented at 4:57 am on August 26, 2025: contributor
    But MAX_NODES has a value of 12. In the above patch, the number of nodes has been increased to 6.
  4. maflcko commented at 8:35 am on August 26, 2025: member
    The test is re-using “unused” p2p ports after the 6 nodes. On master it is using 4 ports and you are using another 6, so 6+4+6=16, which is greater than 12, no?
  5. w0xlt commented at 5:22 pm on August 26, 2025: contributor

    I haven’t fully reviewed this code yet, but at first glance it seems that if the issue were related to the P2P port, the assert condition in test/functional/test_framework/util.py should have failed.

    0def p2p_port(n):
    1    assert n <= MAX_NODES
    2    return PORT_MIN + n + (MAX_NODES * PortSeed.n) % (PORT_RANGE - 1 - MAX_NODES)
    

    Anyway, it doesn’t seem like much of a concern, and since the PR doesn’t touch the test further, I’ll close this for now.

  6. w0xlt closed this on Aug 26, 2025

  7. maflcko commented at 5:37 pm on August 26, 2025: member

    The assert is not hit, because you are just setting port+=2, not by calling p2p_port(node_number+N).

    My recommendation would be to call p2p_port, so that the assert is hit in your code.

    edit: and on master

  8. maflcko reopened this on Aug 26, 2025

  9. bitcoin deleted a comment on Aug 27, 2025


w0xlt maflcko


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2025-09-02 12:13 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me