-
Notifications
You must be signed in to change notification settings - Fork 37.7k
[WIP] net: return result from addnode RPC #30381
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
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. Code CoverageFor detailed information about the code coverage, see the test coverage report. ReviewsSee the guideline for information on the review process.
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update. ConflictsReviewers, this pull request conflicts with the following ones:
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. |
I did experiment with not throwing This does mean that the |
Before these changes:
After:
|
This lets us propagate errors back to `CConnman::AddConnection()` and the `addnode` RPC in the future. Co-authored-by: Amiti Uttarwar <amiti@uttarwar.org>
Return the status of `AddConnection()` to the `addconnection()` RPC. Also rename RPCErrorCode 34 to align with the behaviour it signifies. Co-authored-by: Amiti Uttarwar <amiti@uttarwar.org>
When we call the `addnode` RPC, previous behaviour was to return an RPC error in some situations, but otherwise return null. This commit changes that behaviour to instead return an `RPCResult` from calls to `addnode`. This will include the address the result relates to, and additionally either a `result` or an `error` field. The presence of these fields can be used to determine success, or error respectively.
14312c3
to
4c19971
Compare
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.
There's a lot of stuff happening in one commit:
- behaviour change: allow removing a v2 connection when
!node_v2transport
- behaviour change: explicitly throwing a a
JSONRPCError
when opening the connection for aonetry
fails, instead of returning NULL (which makes it indistinguishable from a success operation) - behaviour change: always returning a results object with input values and
result==success
- clang-tidy fixes
I would suggest breaking things up a bit and describing the rationale for each.
Some initial thoughts/questions about each of the above points, addressed individually:
- can you talk more about the rationale here?
- this seems like a useful improvement, not being able to distinguish between a failure and success case is problematic
- this seems like unnecessary API breakage for a one-off change (not just the return type, also the changed error messages) with no clear benefit to the user: they already know the
operation
andaddress
fields, and theresult
field is alwaystrue
. I think (ideally consistently) returning newly created objects as a response can be a useful pattern, but doing it as a one-off I'm not really enthusiastic about.
More general thoughts:
- if we're going to return something, the peer id seems like actual useful (new) information?
- it seems not very elegant to have the input fields named
node
andcommand
, and then call themaddress
andoperation
in the result, when they are the exact same thing?
} | ||
|
||
if (command == "add") | ||
{ | ||
std::string error_message; |
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: is this necessary?
Right, I wanted to open this up specifically while WIP as I ended up less-sure about the idea of the change in general (nor the implementation approach). The final commit does indeed need breaking up, but I wanted to get feedback on the mechanics of the whole change before investing more time into it, so thank you very much for your detailed review!
This was actually done to align with the helptext: Line 317 in bd5d168
-v2transport ).
Correct, this is basically the main aim of the PR; to clarify whether we are returning successfully or not. As mentioned in 2nd post above, initially I removed some (or all) of the
I agree this is redundant as mentioned in comment
Will be happy to implement this instead, so we have a useful return value.
ok
The rationale is directly from #20552
Do you have any suggestions on another way to determine success or failure without a breaking API change? I suppose we could guarantee thrown errors on every fail-case, and retain NULL as indicating success? That could work, but feels less intuitive to me personally.
Agreed. I will sort those out. Thanks again! ❤️ |
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, I'd find this useful.
|
||
if (command == "onetry") { | ||
if (!connman.OpenNetworkConnection(CAddress(), false, {}, node_arg.c_str(), ConnectionType::MANUAL, use_v2transport)) { | ||
throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Unable to open connection"); |
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.
Suggest Unable to open connection to <peer address>
RPCResult::Type::OBJ, "", "", | ||
{ | ||
{RPCResult::Type::STR, "operation", "The operation called (onetry/add/remove)"}, | ||
{RPCResult::Type::STR, "result", "The result of the operation (success/failed)"}, |
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.
Agree with @stickies-v that returning the peer id would be more useful than the result.
Sorry, I should have phrased this more clearly, the initial thoughts I mentioned were numbered to be addressing the same numbered elements from the paragraph above. So specifically the rationale for "behaviour change: allow removing a v2 connection when !node_v2transport", which I now understand is just to get it in line with the documentation.
I'm okay with breaking API changes when they're meaningful, such as to address the issue outlined in #20552. My point was about changing the API for no good reason, such as the currently proposed new result, or the changes in error messages such as |
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
There is definitely value in ensuring errors are provided to the user (e.g. no longer failing silently for unsuccessful onetry
).
I could see there being value in returning the peer id, but think that might be better off for a follow up PR. This one could focus on fixing the problem of masking the error (and prevent discussion on a return object vs null from impacting what is otherwise a relatively straightforward bug fix).
If this PR remains scoped to returning the returning an object then deprecatedrpc
should be implemented (giving users the ability to use the old return behavior temporarily). Something like -deprecatedrpc=addnode
.
The return value seems entirely redundant. Maybe it should just be the new peer id (Object-encapsulated for future extension), and make |
Concept ACK When Isn't one of the |
Sounds useful. Didn't re-read the discussion, but I'm not sure that no connection should throw, in favor of returning an "error" field (or "errors" object). @willcl-ark do you plan to update here soon? |
🐙 This pull request conflicts with the target branch and needs rebase. |
Closing for now until I can circle back. |
c6eca6f doc: add guidance for RPC to developer notes (tdb3) Pull request description: Adds guidance statements to the RPC interface section of the developer notes with examples of when to implement `-deprecatedrpc=`. Wanted to increase awareness of preferred RPC implementation approaches for newer contributors. This implements some of what's discussed in #29912 (comment) Opinions may differ, so please don't be shy. We want to make RPC as solid/safe as possible. Examples of discussions where guidelines/context might have added value: #30212 (comment) #29845 (comment) #30381 (review) #29954 (comment) #30410 (review) #30713 #30381 #29060 (review) ACKs for top commit: l0rinc: ACK c6eca6f fjahr: ACK c6eca6f maflcko: lgtm ACK c6eca6f jonatack: ACK c6eca6f Tree-SHA512: 01a98a8dc0eb91762b225d3278cdb4a5e380ceb7486fd096b4ad9122bed859cea8584d8996d3dce51272fdb792f4a793a1bd1c5445efeb87f0a30f9b6e59a790
Fixes: #20552
Picks up a branch from by @amitiuttarwar which adds a success response to
addnode
RPC.It adds a new return object to
addnode
RPC indicating that the call was successful: