-
Notifications
You must be signed in to change notification settings - Fork 38.7k
[net] Allow disconnectnode RPC to be called with node id #10143
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
Conversation
|
Concept ACK. Though if we're going to be exposing this value to our apis, we need to define it sanely first. ATM it's just an int, so it's tricky encode/decode it safely. I'd prefer change it to a uint32_t first, so that we can use ParseUInt32 here. |
|
Concept ACK, I've wanted this many times before... but I'm concerned about the nodeid--- right now if it wraps bad things happen, and it will be harder to fix if we've made it a part of the API. |
|
edit: Decided I didn't like this thought and bailed. Meant to cancel, closed instead. Sorry! |
|
I suppose it would be prudent to
The last one is what happens all over the place, and is fine as long as we ensure that the values really are unique. To do so, we can either:
Obviously the first is cleaner, and would probably end up being simpler too. |
|
See theuni@57ea0cc for the wrapping/defining changes. Still need to verify the first two points above, though. @jnewbery If you don't object, I'll go ahead and PR that as a prerequisite for this one. |
src/rpc/net.cpp
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concept ACK, but please make this API explicit.
-
APIs that switch based on magic heuristics on how a value 'looks'. Initially this seems user friendly, but it will quickly grow to maintainable, insecure monsters of obscure rules. It should be made completely explicit.
-
Also: do not encode integers as strings and use functions like std::stoi. Just use .get_int() if you need an int value and leave the encoding of values up to the RPC mechanism.
The most straightforward way would be to just add a function disconnectnodebyid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I agree that APIs shouldn't be magic. I thought it wouldn't be too problematic here because there can't be any ambiguity at all between nodeIds and IP addresses (and disconnectnode() is already a bit magic - it can take either IPv4 or IPv6 addresses).
I don't like the proliferation of additional RPCs that perform a very small function if we can avoid it.
How about we add a new argument to this RPC called "nodeId"? The RPC can be called with strictly one of the arguments. There's no magic or ambiguity, and the node disconnection logic is contained within one RPC.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about we add a new argument to this RPC called "nodeId"? The RPC can be called with strictly one of the arguments. There's no magic or ambiguity, and the node disconnection logic is contained within one RPC.
Sounds reasonable to me. To be clear: anything that doesn't encode the integer as a string is more reasonable to me than this (another reason: because it allows passing the 'id' value literally without having to string-encode it in the client). I don't have a strong opinion whether it should be one or multiple RPCs.
This value is already exposed in APIs since |
|
Found myself wanting this for disconnect after reading debug.log many times, annoying to have to getpeerinfo for it. |
|
@theuni - of course, no objection at all! |
Well you can write an IPv4 address as a decimal integer... I guess we're excluding that (very uncommon) usage? |
+1. Exactly. This is exactly why these things get ugly. There's always overlaps in representations that you may not be thinking about in the initial design, then get realized later. Let's just take the sane route here and make the ambiguity impossible. |
Yep, fine. |
|
ok, another idea. I think it's reasonable that people might want to update node by id in other ways (ie switching whitelisting on and off, changing ban score, etc). How would you feel about an updatenode RPC to do those things? To begin with it will allow disconnecting and turning whitelisting on/off, and it can be added to later if people think further functionality is useful. I already have a branch with an updatenode RPC here: jnewbery@5bbe24f . Adding a 'disconnect' argument to it is trivial. We should keep this RPC hidden in order to not commit ourselves to a public API that we might want to change later (eg if we break out whitelisting into more granular behaviour at some point). Thoughts? |
|
I've added an |
|
I don't think 'updatepeer X disconnect' is clearer than 'disconnectnode'. Having the RPC call as the verb is easier to use and remember. We have an example of a very bad multiplexed call in the API: |
|
Yes, I'll reimplement this as an additional argument to disconnectnode. Longer term, my thinking around updatepeer is that it'd be handy as a swiss army knife for peer interop. We may wish to disconnect/ban/whitelist/change other attributes/etc for peers, and having a single RPC that does all of that would be a sensible API, and certainly better than a different RPC for each attribute. On the other hand, I do agree that 'disconnect' is a verb, so naturally |
5469596 to
3ed1bef
Compare
|
I've pushed a version where disconnectnode now takes two arguments: address and nodeid. Strictly one argument must be given. (note: with named arguments, you can just supply a single argument, with positional arguments you need to set 'address' to the empty string if you want to use 'nodeid'). I changed the name of the existing argument from 'node' to 'address', since it only takes address. I think that's the right thing to do since the current name is misleading, but we'll need release notes to document the API change. This should only be merged after @theuni's branch here: theuni@57ea0cc. |
src/rpc/net.cpp
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Second argument is missing here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Help text now fixed. I'll squash the commit when this is ready for merge.
|
While you can write an IP as a decimal number, you can't specify an IP plus port in such a manner. Makes perfect sense to say String = IP and Number = nodeid IMO. Don't care too strongly if the current (two arguments) approach is used, but I wouldn't call it sane. :p |
|
@luke-jr thanks for the review. I agree that the two arguments approach looks a bit odd when used as positional arguments, but it makes perfect sense when using named arguments: call the RPC with address= if you want to disconnect by address, or call with nodeid= if you want to disconnect by nodeid. The fact that it works at all with positional arguments is more a historical quirk of bitcoin's RPC rather than a feature.I think any of the three approaches I've implemented are fine (overloading one argument, having a second argument or having a separate 'update peer' RPC). I really just want the functionality somewhere, and I'm happy to go along with the consensus view for where the best place to put it is. |
|
(aside, the addnode thing isn't that nuts if you thing of it as a shortening of "addednodelist ", which is what it actually is :) ) |
Yes, it makes sense if you're a scholar of Bitcoin Core code archaeology :) It'd be nice if |
src/rpc/net.cpp
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is yet another breaking change. Needs rationale and mention in the release notes. Maybe backport.
JSONRPCException: Unknown named parameter address (-8)
Github-Pull: bitcoin#10143 Rebased-From: d6564a2
Github-Pull: bitcoin#10143 Rebased-From: 395561b
Github-Pull: bitcoin#10143 Rebased-From: 12de2f2
Github-Pull: bitcoin#10143 Rebased-From: 5cc3ee2
… branch 'disconnect_ban_fixes-0.14' into 0.14.2_fixes
disconnectnode() can currently only be called with the IP address/port of the node the user wishes to connect. This commit allows the node to be disconnected using the nodeid returned by getpeerinfo(). Github-Pull: bitcoin#10143 Rebased-From: 23e6e64
Github-Pull: bitcoin#10143 Rebased-From: d54297f
… node id d54297f [tests] disconnect_ban: add tests for disconnect-by-nodeid (John Newbery) 5cc3ee2 [tests] disconnect_ban: remove dependency on urllib (John Newbery) 12de2f2 [tests] disconnect_ban: use wait_until instead of sleep (John Newbery) 2077fda [tests] disconnect_ban: add logging (John Newbery) 395561b [tests] disconnectban test - only use two nodes (John Newbery) e367ad5 [tests] rename nodehandling to disconnectban (John Newbery) d6564a2 [tests] fix nodehandling.py flake8 warnings (John Newbery) 23e6e64 Allow disconnectnode() to be called with node id (John Newbery) Tree-SHA512: a371bb05a24a91cdb16a7ac4fbb091d5d3bf6554b29bd69d74522cb7523d3f1c5b1989d5e7b03f3fc7369fb727098dd2a549de551b731dd480c121d9517d3576
The disconnectnode RPC can currently only be called with the IP address/port
of the node the user wishes to connect. This commit allows the node to
be disconnected using the nodeid returned by getpeerinfo().