-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Fix: Remove non-canonical fields from tx_json in API v3
#6448
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
base: develop
Are you sure you want to change the base?
Changes from 2 commits
4a31ee1
9b0e87a
cf2835e
cbabee1
249fb12
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -122,20 +122,49 @@ class AccountTx_test : public beast::unit_test::suite | |
| { | ||
| auto const& payment = j[jss::result][jss::transactions][1u]; | ||
|
|
||
| return (payment.isMember(jss::tx_json)) && | ||
| (payment[jss::tx_json][jss::TransactionType] == jss::Payment) && | ||
| (payment[jss::tx_json][jss::DeliverMax] == "10000000010") && | ||
| (!payment[jss::tx_json].isMember(jss::Amount)) && | ||
| (!payment[jss::tx_json].isMember(jss::hash)) && | ||
| (payment[jss::hash] == | ||
| "9F3085D85F472D1CC29627F260DF68EDE59D42D1D0C33E345" | ||
| "ECF0D4CE981D0A8") && | ||
| (payment[jss::validated] == true) && | ||
| (payment[jss::ledger_index] == 3) && | ||
| (payment[jss::ledger_hash] == | ||
| "5476DCD816EA04CBBA57D47BBF1FC58A5217CC93A5ADD79CB" | ||
| "580A5AFDD727E33") && | ||
| (payment[jss::close_time_iso] == "2000-01-01T00:00:10Z"); | ||
| if (apiVersion >= 3) | ||
| { | ||
| // In API v3, server-added lower-case fields must | ||
| // not be in tx_json | ||
| return (payment.isMember(jss::tx_json)) && | ||
| (payment[jss::tx_json][jss::TransactionType] == jss::Payment) && | ||
| (payment[jss::tx_json][jss::DeliverMax] == "10000000010") && | ||
| (!payment[jss::tx_json].isMember(jss::Amount)) && | ||
| (!payment[jss::tx_json].isMember(jss::hash)) && | ||
| (!payment[jss::tx_json].isMember(jss::date)) && | ||
| (!payment[jss::tx_json].isMember(jss::ledger_index)) && | ||
| (!payment[jss::tx_json].isMember(jss::ctid)) && | ||
| (payment[jss::hash] == | ||
| "9F3085D85F472D1CC29627F260DF68EDE59D42D1D0C33E345" | ||
| "ECF0D4CE981D0A8") && | ||
| (payment[jss::validated] == true) && | ||
| (payment[jss::ledger_index] == 3) && | ||
| (payment[jss::ledger_hash] == | ||
| "5476DCD816EA04CBBA57D47BBF1FC58A5217CC93A5ADD79CB" | ||
| "580A5AFDD727E33") && | ||
| (payment[jss::close_time_iso] == "2000-01-01T00:00:10Z"); | ||
| } | ||
|
Comment on lines
125
to
149
|
||
| else | ||
| { | ||
| // In API v2, date and ledger_index are still in | ||
| // tx_json for backwards compatibility | ||
| return (payment.isMember(jss::tx_json)) && | ||
| (payment[jss::tx_json][jss::TransactionType] == jss::Payment) && | ||
| (payment[jss::tx_json][jss::DeliverMax] == "10000000010") && | ||
| (!payment[jss::tx_json].isMember(jss::Amount)) && | ||
| (!payment[jss::tx_json].isMember(jss::hash)) && | ||
| (payment[jss::tx_json].isMember(jss::date)) && | ||
| (payment[jss::tx_json].isMember(jss::ledger_index)) && | ||
| (payment[jss::hash] == | ||
| "9F3085D85F472D1CC29627F260DF68EDE59D42D1D0C33E345" | ||
| "ECF0D4CE981D0A8") && | ||
| (payment[jss::validated] == true) && | ||
| (payment[jss::ledger_index] == 3) && | ||
| (payment[jss::ledger_hash] == | ||
| "5476DCD816EA04CBBA57D47BBF1FC58A5217CC93A5ADD79CB" | ||
| "580A5AFDD727E33") && | ||
| (payment[jss::close_time_iso] == "2000-01-01T00:00:10Z"); | ||
| } | ||
| } | ||
| else | ||
| return false; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -760,6 +760,23 @@ class Transaction_test : public beast::unit_test::suite | |
| result[jss::result][jss::ledger_hash] == | ||
| "B41882E20F0EC6228417D28B9AE0F33833645D35F6799DFB782AC97FC4BB51" | ||
| "D2"); | ||
|
|
||
| auto const& tx_json = result[jss::result][jss::tx_json]; | ||
| if (apiVersion >= 3) | ||
| { | ||
| // In API v3, server-added lower-case fields must not appear | ||
| // inside tx_json; they are at the result level. | ||
| BEAST_EXPECT(!tx_json.isMember(jss::date)); | ||
| BEAST_EXPECT(!tx_json.isMember(jss::ledger_index)); | ||
| BEAST_EXPECT(!tx_json.isMember(jss::ctid)); | ||
| } | ||
| else | ||
| { | ||
| // In API v2, date and ledger_index are still included in | ||
| // tx_json for backwards compatibility. | ||
| BEAST_EXPECT(tx_json.isMember(jss::date)); | ||
| BEAST_EXPECT(tx_json.isMember(jss::ledger_index)); | ||
| } | ||
|
Comment on lines
764
to
781
|
||
| } | ||
|
|
||
| for (auto memberIt = expected.begin(); memberIt != expected.end(); memberIt++) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -286,8 +286,12 @@ populateJsonResponse( | |
| auto const json_tx = (context.apiVersion > 1 ? jss::tx_json : jss::tx); | ||
| if (context.apiVersion > 1) | ||
| { | ||
| jvObj[json_tx] = txn->getJson( | ||
| JsonOptions::include_date | JsonOptions::disable_API_prior_V2, false); | ||
| auto const opts = context.apiVersion >= 3 | ||
| ? JsonOptions::disable_API_prior_V2 | | ||
| JsonOptions::disable_API_prior_V3 | ||
| : JsonOptions::include_date | | ||
| JsonOptions::disable_API_prior_V2; | ||
| jvObj[json_tx] = txn->getJson(opts, false); | ||
|
Comment on lines
291
to
294
|
||
| jvObj[jss::hash] = to_string(txn->getID()); | ||
| jvObj[jss::ledger_index] = txn->getLedger(); | ||
| jvObj[jss::ledger_hash] = | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -189,8 +189,14 @@ populateJsonResponse( | |
| auto const& sttx = result.txn->getSTransaction(); | ||
| if (context.apiVersion > 1) | ||
| { | ||
| constexpr auto optionsJson = | ||
| // In API v2, include_date and disable_API_prior_V2 are used to | ||
| // include date/ledger_index/ctid in tx_json. In API v3+, those | ||
| // fields are excluded from tx_json and are only at result level. | ||
| constexpr auto optionsV2 = | ||
| JsonOptions::include_date | JsonOptions::disable_API_prior_V2; | ||
| constexpr auto optionsV3 = | ||
| JsonOptions::disable_API_prior_V2 | JsonOptions::disable_API_prior_V3; | ||
| auto const optionsJson = context.apiVersion >= 3 ? optionsV3 : optionsV2; | ||
|
Comment on lines
+192
to
+199
|
||
| if (args.binary) | ||
| response[jss::tx_blob] = result.txn->getJson(optionsJson, true); | ||
| else | ||
|
|
||
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 section says “In API versions 1 and 2, the
tx_jsonfield …”, but API v1 responses usetx(nottx_json) in these handlers. Consider rewording to avoid implyingtx_jsonexists in v1 (e.g., refer to the transaction object intx/account_tx, or limit the statement to API v2).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 in cf2835e. The wording now says "In API version 2" (not "v1 and v2") since v1 uses
tx(nottx_json).