-
Notifications
You must be signed in to change notification settings - Fork 38.1k
Add updatepeer RPC #10160
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
Add updatepeer RPC #10160
Conversation
I'm not sure I like the idea of adding a command that changes the implied state of a peer via its attributes, rather than performing actions explicitly. The whitelist side-effects are especially hazy, see the brief discussion here: #10051 (comment). |
@jnewbery: |
Ah... an there is already the |
@jonasschnelli see #2729 and #6271 for history of the @theuni - I agree that whitelisting is a mess and should be broken out into bits for controlling individual behaviours. Hence my original comment: "I have a feeling we may want to make the whitelisting behaviour more granular and I don't want to commit us to a public API that we can't then change." I was thinking of your comment in #10051 but couldn't find the reference.
I don't understand what this means in the context of whitelisting. The idea is to update the peer's whitelist behaviour. What would performing actions explicitly entail? |
Closing in favour of #10143 for the immediate need (disconnect node by id), but I think this could still be a useful RPC in the future. |
Reopening with just the ability to update:
The net_processing functionality for the v0.15.0.2 PRs is disabled for manual connections, so this PR could be helpful for testing those changes. |
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. Will test.
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.
Is null instead.
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.
If not then raise invalid parameter?
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.
Missing test for invalid node.
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.
Not null instead.
172e302
to
c799a6c
Compare
Thanks for the review @promag . I've addressed all your comments. |
whitelisting via rpc?? BIG BIG concept ACK. I am excited. It will make configuration of services depending on Bitcoin Core RPC and P2P so much easier. |
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.
Nit, rename PR to Add updatepeer RPC. Squash [RPC] Allow manual_connection to be updated using updatepeer
into [RPC] Add updatenode RPC
.
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.
if (!...) {
throw ...;
}
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.
Nit, > 1
.
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.
Nit, same line or { }
.
src/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.
Nit, missing spaces after for
.
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.
Same as above.
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.
Nit, space after 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.
Same validation of getpeerinfo
.
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.
Needs release notes.
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.
Actually I think this is more correct:
- raise
RPC_INVALID_PARAMETER
ifnode_id < 0
; - raise
RPC_INVALID_ADDRESS_OR_KEY
if!GetNodeStats(...)
.
Note: if you do this then add a test for 1st case.
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.
I don't think it's too important, but feel free to open a follow-up PR if you think it's required.
test/functional/net.py
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.
Missing failure tests for getpeerinfo (maybe unrelated to this PR).
@promag nits addressed in latest commit. |
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.
utACK after squash.
Nit, how about updatepeer id setting value (setting value ...)
:
updatepeer 1 whitelisted true
updatepeer 1 manual_connection false
It works well without named arguments with the cli, and scales well for other settings.
Note, I always prefer named arguments, specially in these calls. But we do support index arguments and this approach doesn't help for future settings.
src/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.
Nit, missing space after for
. Same below.
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.
fixed
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.
Remove lock or am I missing something?
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.
you're right - I don't think this is required
I agree with @promag |
This is a different scheme from all of the existing RPCs. I expect that there would need to be changes to the rpc framework to make this work. It doesn't make sense to me have a completely different scheme for just this RPC method, since we already have named arguments. If you disagree, perhaps you could implement the scheme you're talking about in a new branch? |
@jnewbery how so? This is just 3 differents parameters of 3 strings. The way you are doing now, if there is like 60 settings for one peer, we will have 60 parameters to this function. This does not seem very maintainable. In such case even |
@jnewbery you too agree that this is by design bad for positional arguments (considering the possible settings can be extended). Another approach is to use something like FWIW I already gave my utACK 😄 |
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.
See my above comment, by fetching once the node at the start of this method, you can remove all those if
as you already know if the CNode with such id already exist. It makes things a bit easier to test and prevent monkey coding each time we want to add a new field.
This RPC error is also untestable as it makes you reproduce a difficult race condition. (need to drop the node after the previosu GetNodeStates but before this call)
src/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 method would also be removed if fetching CNode was done at the updatepeer level.
@jnewbery do you need more help on this PR? I am really interested into seeing it merged. |
@NicolasDorier: Sorry for dropping this - I've rebased on master and squashed all nits. I'm not sure about your suggestion for locking in updatepeer and fetching the |
@jnewbery in this case, I would suggest to have a method on CConman |
I'm still with @theuni on this one, not super happy with the idea of changing properties about peers that net_processing/net both consider "constant". Would prefer we add some (undocumented?) options to addnode (or a new RPC) which lets you control the flags of a peer as you create a connection. |
@theuni's comment was:
I don't understand what's meant by 'performing actions explicitly', but I'm happy to modify this PR if there are concrete suggestions.
Can you articulate what makes you not happy? Being able to change the properties of a connection without having to delete/recreate that object is generally very useful, since cycling a connection has many side-effects. As far as I can see, the only stateful impact of starting with
I can't see any other reason to be concerned about updating |
I might be slightly more OK with changing fWhitelisted on a peer after its up, as that may be useful "in the real world" outside of tests, but I'm super not a fan of changing manual_connection. One thing @theuni and I have talked about is being more aggressive about CNode representing a "connection handle" where its potentially allowed to have a few constant members which are general information about the connection, eg whether it was automatically or manually added, the remote address, etc.
I'm not sure what side-effects there are that couldn't be reproduced on a new connection after cycling the connection. It ends up being an unrealistic test if you dont do that anyway. Maybe I'm just missing the motivation of cases that wouldnt be better tested by cycling a connection? |
You're describing things that may happen in future changes in abstract terms, particularly when you talk about between-message-stateful behaviour.
This is undoubtedly useful for testing, but I could also imagine it being useful, for example in a business that has more than one bitcoin node and wants to be able to manage their network topology. Thinking forward a bit more, I think it'd also be beneficial to break out the whitelist behaviour to be more granular, and again be able to update those properties dynamically. |
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.
Haven't been following discussion in much detail but if the problem is fAddNode
having both const and non-const interpretations, maybe it should just be split into two variables: m_connection_type
that would be const and record origin of connection and m_preferred_peer
that would be mutable.
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.
utACK
Needs rebase.
src/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.
Could you maybe make an (optionally inline) method find_node_by_id
that the above methods use? Looks a bit copy-pastey.
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.
refactored out
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.
Nit: No period at end (seems to be the norm). Also add this to the first line ("getpeerinfo \"id\"\n"
)
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.
fixed
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.
"updatepeer \"id\" ( \"whitelisted\" \"manual_connection\" )\n"
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.
Nit: node_id
is an int
, so %d
not %u
.
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.
fixed
16900c5
to
fd18f4e
Compare
Fixed @kallewoof review comments. |
…N(). This commit refactors getpeerinfo() to call a helper function NodeStatsToJSON() to build a JSON object with peer information.
GetNodeStats() can now be called for a single node.
The getpeerinfo RPC can now be called for a single node by specifying the node id.
This commit adds an updatepeer RPC for updating a single peer node. Currently, updatepeer can be used to update the whitelisting and manual_connection settings for the node. It could potentially be extended in future to allow updating other attributes of the peer node.
There doesn't seem to much appetite for this. Closing. |
I liked it :( |
Marked "up for grabs". (Conversation is locked, so a new pull will need to be opened either way). |
Adds an
updatepeer
RPC to update peer config and carry out actions on the peer by NodeId. At the moment, the actions are just changing whether the peer is whitelisted and whether the peer is a manual_connection (previously called an addnode). Future possible actions would be changing banscore, banning, and so on.This is designed to be called using named arguments, but due to the RPC infrastructure can also be called with positional arguments (although doing so would be very fiddly).
I've set the category to hidden for now. We may want to make the whitelisting behaviour more granular in future and I don't want to commit us to a public API that we can't then change.