Move signer_list in JSON response for api_version 2:

See https://github.com/ripple/xrpl-dev-portal/issues/938 for context.
This commit is contained in:
Fraser Waters
2021-02-13 18:22:39 +00:00
committed by manojsdoshi
parent 96f11c786e
commit 10d73655bc
3 changed files with 131 additions and 2 deletions

View File

@@ -7,6 +7,10 @@ This document contains the release notes for `rippled`, the reference server imp
Have new ideas? Need help with setting up your node? Come visit us [here](https://github.com/ripple/rippled/issues/new/choose) Have new ideas? Need help with setting up your node? Come visit us [here](https://github.com/ripple/rippled/issues/new/choose)
# Change log
- API version 2 will now return `signer_lists` in the root of the `account_info` response, no longer nested under `account_data`.
# Releases # Releases
## Version 1.7.2 ## Version 1.7.2

View File

@@ -109,8 +109,19 @@ doAccountInfo(RPC::JsonContext& context)
if (sleSigners) if (sleSigners)
jvSignerList.append(sleSigners->getJson(JsonOptions::none)); jvSignerList.append(sleSigners->getJson(JsonOptions::none));
result[jss::account_data][jss::signer_lists] = // Documentation states this is returned as part of the account_info
std::move(jvSignerList); // response, but previously the code put it under account_data. We
// can move this to the documentated location from apiVersion 2
// onwards.
if (context.apiVersion == 1)
{
result[jss::account_data][jss::signer_lists] =
std::move(jvSignerList);
}
else
{
result[jss::signer_lists] = std::move(jvSignerList);
}
} }
// Return queue info if that is requested // Return queue info if that is requested
if (queue) if (queue)

View File

@@ -188,6 +188,119 @@ public:
} }
} }
// Test the "signer_lists" argument in account_info, with api_version 2.
void
testSignerListsApiVersion2()
{
using namespace jtx;
Env env{*this, envconfig([](std::unique_ptr<Config> c) {
c->loadFromString("\n[beta_rpc_api]\n1\n");
return c;
})};
Account const alice{"alice"};
env.fund(XRP(1000), alice);
auto const withoutSigners = std::string("{ ") +
"\"api_version\": 2, \"account\": \"" + alice.human() + "\"}";
auto const withSigners = std::string("{ ") +
"\"api_version\": 2, \"account\": \"" + alice.human() + "\", " +
"\"signer_lists\": true }";
// Alice has no SignerList yet.
{
// account_info without the "signer_lists" argument.
auto const info = env.rpc("json", "account_info", withoutSigners);
BEAST_EXPECT(info.isMember(jss::result));
BEAST_EXPECT(!info[jss::result].isMember(jss::signer_lists));
}
{
// account_info with the "signer_lists" argument.
auto const info = env.rpc("json", "account_info", withSigners);
BEAST_EXPECT(info.isMember(jss::result));
auto const& data = info[jss::result];
BEAST_EXPECT(data.isMember(jss::signer_lists));
auto const& signerLists = data[jss::signer_lists];
BEAST_EXPECT(signerLists.isArray());
BEAST_EXPECT(signerLists.size() == 0);
}
// Give alice a SignerList.
Account const bogie{"bogie"};
Json::Value const smallSigners = signers(alice, 2, {{bogie, 3}});
env(smallSigners);
{
// account_info without the "signer_lists" argument.
auto const info = env.rpc("json", "account_info", withoutSigners);
BEAST_EXPECT(info.isMember(jss::result));
BEAST_EXPECT(!info[jss::result].isMember(jss::signer_lists));
}
{
// account_info with the "signer_lists" argument.
auto const info = env.rpc("json", "account_info", withSigners);
BEAST_EXPECT(info.isMember(jss::result));
auto const& data = info[jss::result];
BEAST_EXPECT(data.isMember(jss::signer_lists));
auto const& signerLists = data[jss::signer_lists];
BEAST_EXPECT(signerLists.isArray());
BEAST_EXPECT(signerLists.size() == 1);
auto const& signers = signerLists[0u];
BEAST_EXPECT(signers.isObject());
BEAST_EXPECT(signers[sfSignerQuorum.jsonName] == 2);
auto const& signerEntries = signers[sfSignerEntries.jsonName];
BEAST_EXPECT(signerEntries.size() == 1);
auto const& entry0 = signerEntries[0u][sfSignerEntry.jsonName];
BEAST_EXPECT(entry0[sfSignerWeight.jsonName] == 3);
}
// Give alice a big signer list
Account const demon{"demon"};
Account const ghost{"ghost"};
Account const haunt{"haunt"};
Account const jinni{"jinni"};
Account const phase{"phase"};
Account const shade{"shade"};
Account const spook{"spook"};
Json::Value const bigSigners = signers(
alice,
4,
{
{bogie, 1},
{demon, 1},
{ghost, 1},
{haunt, 1},
{jinni, 1},
{phase, 1},
{shade, 1},
{spook, 1},
});
env(bigSigners);
{
// account_info with the "signer_lists" argument.
auto const info = env.rpc("json", "account_info", withSigners);
BEAST_EXPECT(info.isMember(jss::result));
auto const& data = info[jss::result];
BEAST_EXPECT(data.isMember(jss::signer_lists));
auto const& signerLists = data[jss::signer_lists];
BEAST_EXPECT(signerLists.isArray());
BEAST_EXPECT(signerLists.size() == 1);
auto const& signers = signerLists[0u];
BEAST_EXPECT(signers.isObject());
BEAST_EXPECT(signers[sfSignerQuorum.jsonName] == 4);
auto const& signerEntries = signers[sfSignerEntries.jsonName];
BEAST_EXPECT(signerEntries.size() == 8);
for (unsigned i = 0u; i < 8; ++i)
{
auto const& entry = signerEntries[i][sfSignerEntry.jsonName];
BEAST_EXPECT(entry.size() == 2);
BEAST_EXPECT(entry.isMember(sfAccount.jsonName));
BEAST_EXPECT(entry[sfSignerWeight.jsonName] == 1);
}
}
}
// Test the "signer_lists" argument in account_info, version 2 API. // Test the "signer_lists" argument in account_info, version 2 API.
void void
testSignerListsV2() testSignerListsV2()
@@ -604,6 +717,7 @@ public:
{ {
testErrors(); testErrors();
testSignerLists(); testSignerLists();
testSignerListsApiVersion2();
testSignerListsV2(); testSignerListsV2();
testSimpleGrpc(); testSimpleGrpc();
testErrorsGrpc(); testErrorsGrpc();