Add account flags to account_info response: (#4459)

Previously, the object `account_data` in the `account_info` response
contained a single field `Flags` that contains flags of an account. API
consumers must perform bitwise operations on this field to retrieve the
account flags.

This change adds a new object, `account_flags`, at the top level of the
`account_info` response `result`. The object contains relevant flags of
the account. This makes it easier to write simple code to check a flag's
value.

The flags included may depend on the amendments that are enabled.

Fix #2457.
This commit is contained in:
drlongle
2023-03-30 20:46:18 +02:00
committed by GitHub
parent 8bfdbcbab5
commit 5ebcaf0a6c
3 changed files with 134 additions and 1 deletions

View File

@@ -46,7 +46,7 @@ public:
"Missing field 'account'.");
}
{
// account_info with a malformed account sting.
// account_info with a malformed account string.
auto const info = env.rpc(
"json",
"account_info",
@@ -491,6 +491,100 @@ public:
}
}
void
testAccountFlags(FeatureBitset const& features)
{
using namespace jtx;
Env env(*this, features);
Account const alice{"alice"};
env.fund(XRP(1000), alice);
auto getAccountFlag = [&env, &alice](std::string_view fName) {
auto const info = env.rpc(
"json",
"account_info",
R"({"account" : ")" + alice.human() + R"("})");
std::optional<bool> res;
if (info[jss::result][jss::status] == "success" &&
info[jss::result][jss::account_flags].isMember(fName.data()))
res.emplace(info[jss::result][jss::account_flags][fName.data()]
.asBool());
return res;
};
static constexpr std::
array<std::pair<std::string_view, std::uint32_t>, 7>
asFlags{
{{"defaultRipple", asfDefaultRipple},
{"depositAuth", asfDepositAuth},
{"disallowIncomingXRP", asfDisallowXRP},
{"globalFreeze", asfGlobalFreeze},
{"noFreeze", asfNoFreeze},
{"requireAuthorization", asfRequireAuth},
{"requireDestinationTag", asfRequireDest}}};
for (auto& asf : asFlags)
{
// Clear a flag and check that account_info returns results
// as expected
env(fclear(alice, asf.second));
env.close();
auto const f1 = getAccountFlag(asf.first);
BEAST_EXPECT(f1.has_value());
BEAST_EXPECT(!f1.value());
// Set a flag and check that account_info returns results
// as expected
env(fset(alice, asf.second));
env.close();
auto const f2 = getAccountFlag(asf.first);
BEAST_EXPECT(f2.has_value());
BEAST_EXPECT(f2.value());
}
static constexpr std::
array<std::pair<std::string_view, std::uint32_t>, 4>
disallowIncomingFlags{
{{"disallowIncomingCheck", asfDisallowIncomingCheck},
{"disallowIncomingNFTokenOffer",
asfDisallowIncomingNFTokenOffer},
{"disallowIncomingPayChan", asfDisallowIncomingPayChan},
{"disallowIncomingTrustline",
asfDisallowIncomingTrustline}}};
if (features[featureDisallowIncoming])
{
for (auto& asf : disallowIncomingFlags)
{
// Clear a flag and check that account_info returns results
// as expected
env(fclear(alice, asf.second));
env.close();
auto const f1 = getAccountFlag(asf.first);
BEAST_EXPECT(f1.has_value());
BEAST_EXPECT(!f1.value());
// Set a flag and check that account_info returns results
// as expected
env(fset(alice, asf.second));
env.close();
auto const f2 = getAccountFlag(asf.first);
BEAST_EXPECT(f2.has_value());
BEAST_EXPECT(f2.value());
}
}
else
{
for (auto& asf : disallowIncomingFlags)
{
BEAST_EXPECT(!getAccountFlag(asf.first));
}
}
}
void
run() override
{
@@ -498,6 +592,11 @@ public:
testSignerLists();
testSignerListsApiVersion2();
testSignerListsV2();
FeatureBitset const allFeatures{
ripple::test::jtx::supported_amendments()};
testAccountFlags(allFeatures);
testAccountFlags(allFeatures - featureDisallowIncoming);
}
};