-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
APIv2(ledger_entry): return "invalidParams" when fields missing #4552
APIv2(ledger_entry): return "invalidParams" when fields missing #4552
Conversation
wouldn't this be a small breaking change? |
How is it that so ? I have updated the existing unit test as well. I was told that we do not want unknownOption at all but the API currently returns it. I might be missing something, do you think I should be updating something else also to make it a non-breaking change if it is a breaking change ? |
Take it with a grain of salt, but it seems |
But I think it would be okay if |
Do you think we should be deprecating the |
|
…lidParams error is returned in v2 while keeping unknownOption error for v1
Thanks @intelliot ! Here are the results of the changes made: Input: Output: Input: Output: |
Currently, a bunch of |
Yes, a new issue (or better - a PR) makes sense. |
src/ripple/rpc/impl/RPCHelpers.h
Outdated
constexpr unsigned int apiMaximumSupportedVersion = 1; | ||
constexpr unsigned int apiMaximumSupportedVersion = 2; | ||
constexpr unsigned int apiBetaVersion = 2; |
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.
As I wrote over on #4571, once a version of rippled
is released with apiMaximumSupportedVersion
is set to 2, then we are saying that API v2 is Done. Once that happens we can not legitimately make any further changes to API version 2. To the best of my knowledge, API version 2 is still in beta, under active development, and still changing.
Now, if you (and #4571 and #4568) are saying that version 2 is done, let's talk about version 2 being done.
If you want a node to properly handle API v2 requests, the correct way to do that, for now, is with the [beta_rpc_api]
config option. And if you want to do it in unit tests, set it up in the config similar to how it's done in https://github.com/XRPLF/rippled/blob/develop/src/test/rpc/AccountInfo_test.cpp#L209-L212, or just by setting cfg.BETA_RPC_API=true;
directly.
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 for the feedback. I'll fix this.
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. Please see also #4573.
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.
Perfect, I'll have a look at it!
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.
Hi @ximinez , this seems a bit problematic. In the test, api_version 2
is specified in the payload which means that when let's say api_version 3
is released (ofc, not soon but whenever it does) - the test will no longer run on api_version 3
unless this particular behaviour changes and we rewrite the test for it. However ideally, would we not want the new test to run for all versions >= 2 unless the particular behaviour is changed for the next versions ofc ? I may be wrong, but I just wanted to clarify.
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.
Also now since we are using beta_version and not changing the max supported version, it does not matter for this PR. But I found a weird behaviour when I changed apiMaximumSupportedVersion
version to 2. It immediately failed a bunch of tests because the unit-tests started running on apiMaximumSupportedVersion
by default which is inconsistent with this. I found this. It is not important right now probably, but this might be a bug and we might need to fix this when api_version 2
is done?
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 does not give me a good impression of our versioning scheme. Makes me think this is why version 2 has not released.
Do we have guidelines that answer these questions?
- How should we write code that is conditional on version and robust in the face of future versions?
- What do we call the set of versions that is tested? What do we call the set of versions that is enabled during operation?
- How do we configure which versions are in these sets?
- How can we ensure that all to-be-tested versions are actually tested? How can we ensure that code that is not conditional on version maintains its behavior across versions?
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.
Tagging @intelliot to see if he has any views on this. :)
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.
It's the same as the way APIs are versioned in other API servers, unrelated to rippled.
You write code that is conditional by using conditions. When future versions are created, you have to update the code. Where updates are required depends on the changes being made in the API. The name for the set of versions that is tested is decided the same way as all other names in the code: propose something, and let other people propose alternatives. The same applies for the set of versions that are enabled during operation: you give it a name that makes sense to you, and is the best name you can think of, given limited time and knowledge. Similarly, you propose code that configures which versions are in these sets. And you have to write code that ensures all available versions are actually tested. The purpose of unit tests is to catch breakages when the API version changes, so it is good (and it is a sign of unit tests serving their intended purpose) when tests break in the face of breaking changes in the API. At that point, you update the tests so that they test the previous API version, and the current one.
If you have any other answers to your questions, go ahead and and share them.
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.
@ximinez gave some good answers in our internal Slack:
- You mean like a name? I have no idea. As I said above, the tests should be over minimum to beta, and the set that's enabled during operation (by default) is minimum to maximum.
- They are defined by the variables in
RPCHelpers.h
.- My thinking is that once #4573 is merged, any tests that care about versions should loop from
apiMinimumSupportedVersion
toapiBetaVersion
and run the tests across all versions. The tests would then have to be written with conditional code to handle the expected results across all versions. This is different than how a lot of the existing tests are written where there's one function for v1 and one for v2, which I agree with you is not sustainable.
He did not answer the first question in my opinion. I think it should be done with zero version equalities, only version inequalities. In fact, I think we can prescribe a pattern to be strictly-enforced:
if (version < FEATURE_X_VERSION) {
// old behavior
} else {
// new behavior
}
if (version >= FEATURE_X_VERSION) {
// new behavior where old behavior was just "do nothing"
}
if (version < FEATURE_X_VERSION) {
// old behavior where new behavior is "stop doing that"
}
…hod for these tests have an additional parameter to add the apiVersion
Introduce a new variadic template helper function, `forAllApiVersions`, that accepts callables to execute a set of functions over a range of versions - from RPC::apiMinimumSupportedVersion to RPC::apiBetaVersion. This avoids the duplication of code. Context: XRPLF#4552
Introduce a new variadic template helper function, `forAllApiVersions`, that accepts callables to execute a set of functions over a range of versions - from RPC::apiMinimumSupportedVersion to RPC::apiBetaVersion. This avoids the duplication of code. Context: XRPLF#4552
Introduce a new variadic template helper function, `forAllApiVersions`, that accepts callables to execute a set of functions over a range of versions - from RPC::apiMinimumSupportedVersion to RPC::apiBetaVersion. This avoids the duplication of code. Context: XRPLF#4552
Introduce a new variadic template helper function, `forAllApiVersions`, that accepts callables to execute a set of functions over a range of versions - from RPC::apiMinimumSupportedVersion to RPC::apiBetaVersion. This avoids the duplication of code. Context: XRPLF#4552
Introduce a new variadic template helper function, `forAllApiVersions`, that accepts callables to execute a set of functions over a range of versions - from RPC::apiMinimumSupportedVersion to RPC::apiBetaVersion. This avoids the duplication of code. Context: XRPLF#4552
Introduce a new variadic template helper function, `forAllApiVersions`, that accepts callables to execute a set of functions over a range of versions - from RPC::apiMinimumSupportedVersion to RPC::apiBetaVersion. This avoids the duplication of code. Context: XRPLF#4552
Introduce a new variadic template helper function, `forAllApiVersions`, that accepts callables to execute a set of functions over a range of versions - from RPC::apiMinimumSupportedVersion to RPC::apiBetaVersion. This avoids the duplication of code. Context: XRPLF#4552 Signed-off-by: Manoj Doshi <mdoshi@ripple.com>
Introduce a new variadic template helper function, `forAllApiVersions`, that accepts callables to execute a set of functions over a range of versions - from RPC::apiMinimumSupportedVersion to RPC::apiBetaVersion. This avoids the duplication of code. Context: XRPLF#4552 Signed-off-by: Manoj Doshi <mdoshi@ripple.com>
Introduce a new variadic template helper function, `forAllApiVersions`, that accepts callables to execute a set of functions over a range of versions - from RPC::apiMinimumSupportedVersion to RPC::apiBetaVersion. This avoids the duplication of code. Context: XRPLF#4552
Introduce a new variadic template helper function, `forAllApiVersions`, that accepts callables to execute a set of functions over a range of versions - from RPC::apiMinimumSupportedVersion to RPC::apiBetaVersion. This avoids the duplication of code. Context: XRPLF#4552
Introduce a new variadic template helper function, `forAllApiVersions`, that accepts callables to execute a set of functions over a range of versions - from RPC::apiMinimumSupportedVersion to RPC::apiBetaVersion. This avoids the duplication of code. Context: XRPLF#4552
Introduce a new variadic template helper function, `forAllApiVersions`, that accepts callables to execute a set of functions over a range of versions - from RPC::apiMinimumSupportedVersion to RPC::apiBetaVersion. This avoids the duplication of code. Context: XRPLF#4552
Introduce a new variadic template helper function, `forAllApiVersions`, that accepts callables to execute a set of functions over a range of versions - from RPC::apiMinimumSupportedVersion to RPC::apiBetaVersion. This avoids the duplication of code. Context: XRPLF#4552
Introduce a new variadic template helper function, `forAllApiVersions`, that accepts callables to execute a set of functions over a range of versions - from RPC::apiMinimumSupportedVersion to RPC::apiBetaVersion. This avoids the duplication of code. Context: XRPLF#4552
Introduce a new variadic template helper function, `forAllApiVersions`, that accepts callables to execute a set of functions over a range of versions - from RPC::apiMinimumSupportedVersion to RPC::apiBetaVersion. This avoids the duplication of code. Context: XRPLF#4552
Introduce a new variadic template helper function, `forAllApiVersions`, that accepts callables to execute a set of functions over a range of versions - from RPC::apiMinimumSupportedVersion to RPC::apiBetaVersion. This avoids the duplication of code. Context: XRPLF#4552
Introduce a new variadic template helper function, `forAllApiVersions`, that accepts callables to execute a set of functions over a range of versions - from RPC::apiMinimumSupportedVersion to RPC::apiBetaVersion. This avoids the duplication of code. Context: XRPLF#4552
Introduce a new variadic template helper function, `forAllApiVersions`, that accepts callables to execute a set of functions over a range of versions - from RPC::apiMinimumSupportedVersion to RPC::apiBetaVersion. This avoids the duplication of code. Context: XRPLF#4552
Introduce a new variadic template helper function, `forAllApiVersions`, that accepts callables to execute a set of functions over a range of versions - from RPC::apiMinimumSupportedVersion to RPC::apiBetaVersion. This avoids the duplication of code. Context: XRPLF#4552
…F#4552) Improve error handling for ledger_entry by returning an "invalidParams" error when one or more request fields are specified incorrectly, or one or more required fields are missing. For example, if none of of the following fields is provided, then the API should return an invalidParams error: * index, account_root, directory, offer, ripple_state, check, escrow, payment_channel, deposit_preauth, ticket Prior to this commit, the API returned an "unknownOption" error instead. Since the error was actually due to invalid parameters, rather than unknown options, this error was misleading. Since this is an API breaking change, the "invalidParams" error is only returned for requests using api_version: 2 and above. To maintain backward compatibility, the "unknownOption" error is still returned for api_version: 1. Related: XRPLF#4573 Fix XRPLF#4303
Introduce a new variadic template helper function, `forAllApiVersions`, that accepts callables to execute a set of functions over a range of versions - from RPC::apiMinimumSupportedVersion to RPC::apiBetaVersion. This avoids the duplication of code. Context: XRPLF#4552
…F#4552) Improve error handling for ledger_entry by returning an "invalidParams" error when one or more request fields are specified incorrectly, or one or more required fields are missing. For example, if none of of the following fields is provided, then the API should return an invalidParams error: * index, account_root, directory, offer, ripple_state, check, escrow, payment_channel, deposit_preauth, ticket Prior to this commit, the API returned an "unknownOption" error instead. Since the error was actually due to invalid parameters, rather than unknown options, this error was misleading. Since this is an API breaking change, the "invalidParams" error is only returned for requests using api_version: 2 and above. To maintain backward compatibility, the "unknownOption" error is still returned for api_version: 1. Related: XRPLF#4573 Fix XRPLF#4303
Introduce a new variadic template helper function, `forAllApiVersions`, that accepts callables to execute a set of functions over a range of versions - from RPC::apiMinimumSupportedVersion to RPC::apiBetaVersion. This avoids the duplication of code. Context: XRPLF#4552
The command line API still uses `apiMaximumSupportedVersion`. The unit test RPCs use `apiMinimumSupportedVersion` if unspecified. Context: - XRPLF#4568 - XRPLF#4552
High Level Overview of Change
Fix for #4303; Replacing
unknownOption
error withinvalidParams
inledger_entry
in APIv2
Type of Change
Before / After
Test Input Payload 1:
{ "method":"ledger_entry", "params":[ { "ledger_index":"validated" } ] }
Before:
{ "result":{ "error":"unknownOption", "ledger_hash":"CA38067ED8FCDCFDE8CAB00A7F83BD90FE0B75D4906D42CCA13EE02B15EC1D10", "ledger_index":29063797, "request":{ "command":"ledger_entry", "ledger_index":"validated" }, "status":"error", "validated":true } }
After: remains same as before.
Test Input Payload 2:
{ "method":"ledger_entry", "params":[ { "api_version": 2, "ledger_index":"validated" } ] }
Before: Not supported
After:
{"result":{"error":"invalidParams","ledger_hash":"2532DD58AF4FDC24EAD3F713280C91781C9A0C9CA1DB51EF9BA8946B1D3C1B4E","ledger_index":29343470,"request":{"api_version":2,"command":"ledger_entry","ledger_index":"validated"},"status":"error","validated":true}}