rpc, p2p: allow `disconnectnode` with subnet #26576

pull brunoerg wants to merge 3 commits into bitcoin:master from brunoerg:2022-11-disconnectnode-subnet changing 3 files +23 −2
  1. brunoerg commented at 4:07 PM on November 25, 2022: contributor

    Since disconnectnode function allows to be used with a subnet, e.g.: https://github.com/bitcoin/bitcoin/blob/38d06e1561013f4ca845fd5ba6ffcc64de67f9c0/src/net.h#L826-L829 https://github.com/bitcoin/bitcoin/blob/38d06e1561013f4ca845fd5ba6ffcc64de67f9c0/src/net.cpp#L2589-L2601

    This PR adds support for subnet in address parameter in disconnectnode RPC. When passing a string with / in address, it is gonna recognize it as a subnet.. It allows us to disconnect multiple nodes from all ports on the same IP. The only way to do it before was banning them for 1sec which seems a bad UX.

    Also, when there are multiples nodes connected to a node in a functional test and we want to disconnect them all, we could call disconnectnode with a subnet instead of calling disconnect_nodes multiple times. A simple example:

    -        for i in range(1, 6):
    -            self.disconnect_nodes(i, 0)
    -
    +        self.nodes[0].disconnectnode(address="127.0.0.1/24")
    +        self.wait_until(lambda: len(self.nodes[0].getpeerinfo()) == 0, timeout=10)
    
  2. rpc, p2p: allow `disconnectnode` with subnet b2e3edc61c
  3. test: add coverage for `subnet` in `disconnectnode` RPC ad39ede8ed
  4. DrahtBot commented at 4:07 PM on November 25, 2022: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

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

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK josibake
    Concept ACK ghost

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

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #26863 (test: merge banning test from p2p_disconnect_ban to rpc_setban by brunoerg)

    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.

  5. andrewtoth commented at 4:45 PM on November 25, 2022: contributor

    This changes the behavior of disconnectnode to potentially disconnect multiple nodes. It's unclear to me what the use case is for this change. When would we want to disconnect nodes by subnet instead of passing in address/port?

  6. brunoerg commented at 6:35 PM on November 25, 2022: contributor

    This changes the behavior of disconnectnode to potentially disconnect multiple nodes. It's unclear to me what the use case is for this change. When would we want to disconnect nodes by subnet instead of passing in address/port?

    I think this is the same logic for setban, banning or disconnecing by subnet is a good way to ban multiple nodes from a range of addresses, or when we want to disconnect from nodes running at the same addr but different ports (obs: passing 127.0.0.1 to address in disconnectnodes don't disconnect the node 127.0.0.1:8333, you must specify the port, that's one of the reasons subnet can be useful.

    E.g.:

    diff --git a/test/functional/p2p_disconnect_ban.py b/test/functional/p2p_disconnect_ban.py
    index 0acb5abac..f90a14cdb 100755
    --- a/test/functional/p2p_disconnect_ban.py
    +++ b/test/functional/p2p_disconnect_ban.py
    @@ -13,7 +13,7 @@ from test_framework.util import (
     
     class DisconnectBanTest(BitcoinTestFramework):
         def set_test_params(self):
    -        self.num_nodes = 2
    +        self.num_nodes = 3
             self.supports_cli = False
     
         def run_test(self):
    @@ -27,7 +27,7 @@ class DisconnectBanTest(BitcoinTestFramework):
             self.log.info("Test setban and listbanned RPCs")
     
             self.log.info("setban: successfully ban single IP address")
    -        assert_equal(len(self.nodes[1].getpeerinfo()), 2)  # node1 should have 2 connections to node0 at this point
    +        assert_equal(len(self.nodes[1].getpeerinfo()), 3)  # node1 should have 2 connections to node0 at this point
             self.nodes[1].setban(subnet="127.0.0.1", command="add")
             self.wait_until(lambda: len(self.nodes[1].getpeerinfo()) == 0, timeout=10)
             assert_equal(len(self.nodes[1].getpeerinfo()), 0)  # all nodes must be disconnected at this point
    @@ -123,6 +123,7 @@ class DisconnectBanTest(BitcoinTestFramework):
             assert not [node for node in self.nodes[0].getpeerinfo() if node['id'] == id1]
     
             self.log.info("disconnectnode: successfully disconnect node by subnet")
    +        self.connect_nodes(0, 2)
             self.nodes[0].disconnectnode(address='127.0.0.1/24')
             self.wait_until(lambda: len(self.nodes[0].getpeerinfo()) == 0, timeout=10)
    
  7. in doc/release-notes-26576.md:4 in fcd014a6bd outdated
       0 | @@ -0,0 +1,5 @@
       1 | +Updated RPCs
       2 | +----------
       3 | +
       4 | +- RPC `disconnectnodes` now accepts a subnet into `address`
    


    dergoegge commented at 4:05 PM on November 26, 2022:
    - RPC `disconnectnode` now accepts a subnet into `address`
    
  8. dergoegge commented at 4:18 PM on November 26, 2022: member

    ~0 I don't really see the use case here. What would be the reason for disconnecting by subnet besides banning spammy peers? In that case setban seems more appropriate.

    This also seems out of scope for the disconnectnode rpc as it is meant (judging by the name and api right now) to disconnect a single node.

  9. ghost commented at 4:56 PM on November 26, 2022: none

    Concept ACK

  10. ghost commented at 4:59 PM on November 26, 2022: none

    What would be the reason for disconnecting by subnet besides banning spammy peers? In that case setban seems more appropriate.

    Its about providing options. Alice could disconnect a subnet and Bob could could ban same subnet for 1 hour.

  11. dergoegge commented at 5:03 PM on November 26, 2022: member

    Alice could disconnect a subnet and Bob could could ban same subnet for 1 hour.

    Alice could just ban for a couple seconds to achieve the same, no?

  12. ghost commented at 5:05 PM on November 26, 2022: none

    Alice could disconnect a subnet and Bob could could ban same subnet for 1 hour.

    Alice could just ban for a couple seconds to achieve the same, no?

    Yes. Although I am not aware if its possible using bitcoin-qt (GUI)

  13. doc: add release note for 26576 23f4c2cb45
  14. brunoerg force-pushed on Nov 28, 2022
  15. brunoerg commented at 2:05 PM on November 29, 2022: contributor

    What would be the reason for disconnecting by subnet besides banning spammy peers? In that case setban seems more appropriate.

    I use addnode a lot and I usually have lots of manual connections, so disconnecting by subnet could help in the case I am connected with nodes from the same ip but different ports and wanna disconnect them all (just a simple example, there are other cases).

  16. dergoegge commented at 2:15 PM on November 29, 2022: member

    @brunoerg you can already achieve that by using setban.

    e.g.

    bitcoin-cli setban <subnet> add 1
    

    disconnects you from a subnet by banning it for 1 second.

  17. brunoerg commented at 3:42 PM on November 29, 2022: contributor

    disconnects you from a subnet by banning it for 1 second.

    It seems a bad UX for me, if I want to disconnect, what comes to my mind is the disconnectnode command, seems weird to me to ban them for 1 sec when I just want to disconnect them.

  18. brunoerg marked this as ready for review on Nov 29, 2022
  19. achow101 requested review from maflcko on Apr 25, 2023
  20. achow101 requested review from josibake on Apr 25, 2023
  21. maflcko removed review request from maflcko on Apr 27, 2023
  22. josibake commented at 10:58 AM on May 3, 2023: member

    Concept ACK

    I would recommend updating the description with a more clear use case, as I also wasn't convinced this was a good change until I read through the discussion and saw your comments @brunoerg

    This also seems out of scope for the disconnectnode rpc as it is meant (judging by the name and api right now) to disconnect a single node.

    Counter argument: as mentioned in the description, DisconnectNode supports subnet as an argument:

    https://github.com/bitcoin/bitcoin/blob/38d06e1561013f4ca845fd5ba6ffcc64de67f9c0/src/net.h#L826-L829

    so why not make the RPC expose the full functionality? I think I'd be more annoyed if I saw that DisconnectNode supported subnet in the code, but the RPC wouldn't let me use it.

    I think disconnecting from all ports on the same IP seems like a compelling enough use case for a very small change.

    EDIT:

    (just a simple example, there are other cases).

    It would be great to see some of these listed in the description as well

  23. brunoerg commented at 7:20 PM on May 3, 2023: contributor

    @josibake thank you, I just updated the description.

    so why not make the RPC expose the full functionality? I think I'd be more annoyed if I saw that DisconnectNode supported subnet in the code, but the RPC wouldn't let me use it.

    I think disconnecting from all ports on the same IP seems like a compelling enough use case for a very small change.

    Yea, I only opened this one because the change would be really small, and since DisconnectNode supports subnet, it might worth.

  24. in src/rpc/net.cpp:397 in 23f4c2cb45
     393 | @@ -394,7 +394,7 @@ static RPCHelpMan disconnectnode()
     394 |                  "\nStrictly one out of 'address' and 'nodeid' can be provided to identify the node.\n"
     395 |                  "\nTo disconnect by nodeid, either set 'address' to the empty string, or call using the named 'nodeid' argument only.\n",
     396 |                  {
     397 | -                    {"address", RPCArg::Type::STR, RPCArg::DefaultHint{"fallback to nodeid"}, "The IP address/port of the node"},
     398 | +                    {"address", RPCArg::Type::STR, RPCArg::DefaultHint{"fallback to nodeid"}, "The IP address/port of the node or subnet"},
    


    josibake commented at 7:54 AM on May 4, 2023:

    it would be great to add an example for subnets in the help section below.

  25. in doc/release-notes-26576.md:4 in 23f4c2cb45
       0 | @@ -0,0 +1,5 @@
       1 | +Updated RPCs
       2 | +----------
       3 | +
       4 | +- RPC `disconnectnode` now accepts a subnet into `address`
    


    josibake commented at 7:58 AM on May 4, 2023:

    The release notes could be a bit more detailed, maybe mentioning that this aligns DisconnectNode and the disconnectnode rpc. It's nice to have at least a summary of the motivation in the release notes.


    luke-jr commented at 2:48 AM on July 27, 2023:

    maybe mentioning that this aligns DisconnectNode and the disconnectnode rpc.

    Internal APIs really don't seem like they belong here


    brunoerg commented at 9:01 PM on August 3, 2023:

    I don't think it's worth to mention this in a release note, seems like a specific code nuance to be exposed. Isn't it?

  26. in src/rpc/net.cpp:427 in 23f4c2cb45
     423 | +            } else {
     424 | +                throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid subnet");
     425 | +            }
     426 | +        } else {
     427 | +            success = connman.DisconnectNode(address_arg.get_str());
     428 | +        }
    


    luke-jr commented at 2:54 AM on July 27, 2023:

    Why not drop this entirely? Seems like a bug specifying an IP won't disconnect all nodes connecting from that IP...


    luke-jr commented at 2:55 AM on July 27, 2023:

    In fact, maybe this should be split into a bugfix commit before adding subnet support.


    brunoerg commented at 11:24 PM on August 3, 2023:

    I don't think it's really a bug. It seems like this was the expected behavior (due to examples and docs - e.g. having to specify port). However, I also think it should be able to disconnect all nodes from an IP. I'm gonna address it.

  27. luke-jr changes_requested
  28. achow101 commented at 5:15 PM on September 20, 2023: member

    This PR does not seem to have conceptual support. Please leave a comment if you would like this to be reopened.

  29. achow101 closed this on Sep 20, 2023

  30. maflcko commented at 5:16 PM on September 20, 2023: member

    disconnects you from a subnet by banning it for 1 second.

    It seems a bad UX for me, if I want to disconnect, what comes to my mind is the disconnectnode command, seems weird to me to ban them for 1 sec when I just want to disconnect them.

    Maybe update the doc to mention the alternative command for this use case?

  31. brunoerg commented at 9:01 AM on September 21, 2023: contributor

    Maybe update the doc to mention the alternative command for this use case?

    SGTM

  32. luke-jr referenced this in commit 6d2bc57f0e on Jun 13, 2024
  33. luke-jr referenced this in commit dc36f2b555 on Jun 13, 2024
  34. bitcoin locked this on Sep 20, 2024

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: 2026-05-02 15:13 UTC

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