update account_objects for sponsorship

This commit is contained in:
tequ
2025-09-20 11:44:47 +09:00
parent 5dc63b64eb
commit 613fe48d54
5 changed files with 75 additions and 5 deletions

View File

@@ -582,6 +582,7 @@ JSS(source_currencies); // in: PathRequest, RipplePathFind
JSS(source_tag); // out: AccountChannels
JSS(sponsee); // in: LedgerEntry
JSS(sponsor); // in: LedgerEntry
JSS(sponsored); // in: AccountObjects
JSS(stand_alone); // out: NetworkOPs
JSS(standard_deviation); // out: get_aggregate_price
JSS(start); // in: TxHistory

View File

@@ -630,6 +630,7 @@ public:
BEAST_EXPECT(acctObjsIsSize(acctObjs(gw, jss::amm), 0));
BEAST_EXPECT(acctObjsIsSize(acctObjs(gw, jss::did), 0));
BEAST_EXPECT(acctObjsIsSize(acctObjs(gw, jss::permissioned_domain), 0));
BEAST_EXPECT(acctObjsIsSize(acctObjs(gw, jss::sponsorship), 0));
// we expect invalid field type reported for the following types
BEAST_EXPECT(acctObjsTypeIsInvalid(acctObjs(gw, jss::amendments)));
@@ -983,6 +984,39 @@ public:
BEAST_EXPECT(ticket[sfTicketSequence.jsonName].asUInt() == seq + 1);
}
{
// Create a sponsorship
env(sponsor::set(
alice,
gw,
tfSponsorshipSetRequireSignForFee,
200,
XRP(100),
drops(10)));
env.close();
// Find the sponsorship.
for (auto acct : {alice, gw})
{
Json::Value const resp = acctObjs(acct, jss::sponsorship);
BEAST_EXPECT(acctObjsIsSize(resp, 1));
auto const& sponsorship =
resp[jss::result][jss::account_objects][0u];
BEAST_EXPECT(sponsorship[sfOwner.jsonName] == alice.human());
BEAST_EXPECT(sponsorship[sfSponsee.jsonName] == gw.human());
BEAST_EXPECT(
sponsorship[sfFlags.jsonName].asUInt() ==
tfSponsorshipSetRequireSignForFee);
BEAST_EXPECT(
sponsorship[sfReserveCount.jsonName].asUInt() == 200);
BEAST_EXPECT(
sponsorship[sfFeeAmount.jsonName].asUInt() == 100000000);
BEAST_EXPECT(sponsorship[sfMaxFee.jsonName].asUInt() == 10);
}
}
{
// See how "deletion_blockers_only" handles gw's directory.
Json::Value params;
@@ -997,7 +1031,8 @@ public:
jss::NFTokenPage.c_str(),
jss::RippleState.c_str(),
jss::PayChannel.c_str(),
jss::PermissionedDomain.c_str()};
jss::PermissionedDomain.c_str(),
jss::Sponsorship.c_str()};
std::sort(v.begin(), v.end());
return v;
}();

View File

@@ -157,6 +157,7 @@ getAccountObjects(
uint256 dirIndex,
uint256 entryIndex,
std::uint32_t const limit,
std::optional<bool> const sponsored,
Json::Value& jvResult)
{
// check if dirIndex is valid
@@ -169,6 +170,13 @@ getAccountObjects(
return it != typeFilter.end();
};
auto sponsoredMatchesFilter = [](bool const sponsored,
std::optional<AccountID> const& sponsor) {
if (sponsored)
return sponsor.has_value();
return !sponsor.has_value();
};
// if dirIndex != 0, then all NFTs have already been returned. only
// iterate NFT pages if the filter says so AND dirIndex == 0
bool iterateNFTPages =
@@ -297,11 +305,23 @@ getAccountObjects(
{
auto const sleNode = ledger.read(keylet::child(*iter));
if (!typeFilter.has_value() ||
typeMatchesFilter(typeFilter.value(), sleNode->getType()))
{
bool canAppend = true;
if (typeFilter.has_value() &&
!typeMatchesFilter(typeFilter.value(), sleNode->getType()))
canAppend = false;
std::optional<AccountID> const sponsor =
sleNode->isFieldPresent(sfSponsorAccount)
? sleNode->getAccountID(sfSponsorAccount)
: std::optional<AccountID>(std::nullopt);
if (sponsored.has_value() &&
!sponsoredMatchesFilter(sponsored.value(), sponsor))
canAppend = false;
if (canAppend)
jvObjects.append(sleNode->getJson(JsonOptions::none));
}
if (++i == mlimit)
{

View File

@@ -109,6 +109,7 @@ getAccountObjects(
uint256 dirIndex,
uint256 entryIndex,
std::uint32_t const limit,
std::optional<bool> const sponsored,
Json::Value& jvResult);
/** Get ledger by hash

View File

@@ -43,6 +43,7 @@ namespace ripple {
type: <string> // optional, defaults to all account objects types
limit: <integer> // optional
marker: <opaque> // optional, resume previous query
sponsored: <boolean> // optional, defaults to null
}
*/
@@ -226,6 +227,7 @@ doAccountObjects(RPC::JsonContext& context)
{jss::mptoken, ltMPTOKEN},
{jss::permissioned_domain, ltPERMISSIONED_DOMAIN},
{jss::vault, ltVAULT},
{jss::sponsorship, ltSPONSORSHIP},
};
typeFilter.emplace();
@@ -284,6 +286,16 @@ doAccountObjects(RPC::JsonContext& context)
return RPC::invalid_field_error(jss::marker);
}
std::optional<bool> sponsored;
if (params.isMember(jss::sponsored))
{
auto const& sponsoredJv = params[jss::sponsored];
if (!sponsoredJv.isBool())
return RPC::expected_field_error(jss::sponsored, "boolean");
sponsored = sponsoredJv.asBool();
}
if (!RPC::getAccountObjects(
*ledger,
accountID,
@@ -291,6 +303,7 @@ doAccountObjects(RPC::JsonContext& context)
dirIndex,
entryIndex,
limit,
sponsored,
result))
return RPC::invalid_field_error(jss::marker);