Skip to content

Commit

Permalink
Fix ledger_data to return an empty list: (#4398)
Browse files Browse the repository at this point in the history
Change `ledger_data` to return an empty list when all entries are
filtered out.

When the `type` field is specified for the `ledger_data` method, it is
possible that no objects of the specified type are found. This can even
occur if those objects exist, but not in the section that the server
checked while serving your request. Previously, the `state` field of the
response has the value `null`, instead of an empty array `[]`. By
changing this to an empty array, the response is the same data type so
that clients can handle it consistently.

For example, in Python, `for entry in state` should now work correctly.
It would raise an exception if `state` is `null` (or `None`). 

This could break client code that explicitly checks for null. However,
this fix aligns the response with the documentation, where the `state`
field is an array.

Fix #4392.
  • Loading branch information
drlongle authored Mar 30, 2023
1 parent 5ebcaf0 commit 2f3f6dc
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 9 deletions.
4 changes: 4 additions & 0 deletions src/ripple/rpc/handlers/LedgerData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ doLedgerData(RPC::JsonContext& context)
return jvResult;
}
Json::Value& nodes = jvResult[jss::state];
if (nodes.type() == Json::nullValue)
{
nodes = Json::Value(Json::arrayValue);
}

auto e = lpLedger->sles.end();
for (auto i = lpLedger->sles.upper_bound(key); i != e; ++i)
Expand Down
37 changes: 28 additions & 9 deletions src/test/rpc/LedgerData_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,34 @@ class LedgerData_test : public beast::unit_test::suite
auto const USD = gw["USD"];
env.fund(XRP(100000), gw);

auto makeRequest = [&env](Json::StaticString const& type) {
Json::Value jvParams;
jvParams[jss::ledger_index] = "current";
jvParams[jss::type] = type;
return env.rpc(
"json",
"ledger_data",
boost::lexical_cast<std::string>(jvParams))[jss::result];
};

// Assert that state is an empty array.
for (auto const& type :
{jss::amendments,
jss::check,
jss::directory,
jss::fee,
jss::offer,
jss::signer_list,
jss::state,
jss::ticket,
jss::escrow,
jss::payment_channel,
jss::deposit_preauth})
{
auto const jrr = makeRequest(type);
BEAST_EXPECT(checkArraySize(jrr[jss::state], 0));
}

int const num_accounts = 10;

for (auto i = 0; i < num_accounts; i++)
Expand Down Expand Up @@ -372,15 +400,6 @@ class LedgerData_test : public beast::unit_test::suite
env.close();

// Now fetch each type
auto makeRequest = [&env](Json::StaticString t) {
Json::Value jvParams;
jvParams[jss::ledger_index] = "current";
jvParams[jss::type] = t;
return env.rpc(
"json",
"ledger_data",
boost::lexical_cast<std::string>(jvParams))[jss::result];
};

{ // jvParams[jss::type] = "account";
auto const jrr = makeRequest(jss::account);
Expand Down

0 comments on commit 2f3f6dc

Please sign in to comment.