feat: XLS-68: Sponsor, #5887 continuation (#7350)

Co-authored-by: tequ <git@tequ.dev>
Co-authored-by: yinyiqian1 <yqian@ripple.com>
Co-authored-by: Mayukha Vadari <mvadari@ripple.com>
Co-authored-by: Mayukha Vadari <mvadari@gmail.com>
Co-authored-by: xrplf-ai-reviewer[bot] <266832837+xrplf-ai-reviewer[bot]@users.noreply.github.com>
Co-authored-by: Peter Chen <34582813+PeterChen13579@users.noreply.github.com>
Co-authored-by: Zhiyuan Wang <96991820+Kassaking7@users.noreply.github.com>
Co-authored-by: Ayaz Salikhov <asalikhov@ripple.com>
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
Co-authored-by: Zhiyuan Wang <1830604455@qq.com>
This commit is contained in:
Olek
2026-07-10 17:58:19 -04:00
committed by GitHub
parent c7adb215ed
commit fd2cc6dcb3
170 changed files with 13151 additions and 660 deletions

View File

@@ -197,7 +197,7 @@ AMMTestBase::testAMM(std::function<void(jtx::AMM&, jtx::Env&)> const& cb, TestAM
XRPAmount
AMMTest::reserve(jtx::Env& env, std::uint32_t count)
{
return env.current()->fees().accountReserve(count);
return env.current()->fees().accountReserve(count, 1);
}
XRPAmount

View File

@@ -271,6 +271,33 @@ Env::ownerCount(Account const& account) const
return sle->getFieldU32(sfOwnerCount);
}
std::uint32_t
Env::sponsoredOwnerCount(Account const& account) const
{
auto const sle = le(account);
if (!sle)
Throw<std::runtime_error>("missing account root");
return sle->getFieldU32(sfSponsoredOwnerCount);
}
std::uint32_t
Env::sponsoringOwnerCount(Account const& account) const
{
auto const sle = le(account);
if (!sle)
Throw<std::runtime_error>("missing account root");
return sle->getFieldU32(sfSponsoringOwnerCount);
}
std::uint32_t
Env::sponsoringAccountCount(Account const& account) const
{
auto const sle = le(account);
if (!sle)
Throw<std::runtime_error>("missing account root");
return sle->getFieldU32(sfSponsoringAccountCount);
}
std::uint32_t
Env::seq(Account const& account) const
{

View File

@@ -94,6 +94,24 @@ ownerCount(Env const& env, Account const& account)
return env.ownerCount(account);
}
std::uint32_t
sponsoredOwnerCount(Env const& env, Account const& account)
{
return env.sponsoredOwnerCount(account);
}
std::uint32_t
sponsoringOwnerCount(Env const& env, Account const& account)
{
return env.sponsoringOwnerCount(account);
}
std::uint32_t
sponsoringAccountCount(Env const& env, Account const& account)
{
return env.sponsoringAccountCount(account);
}
/* Path finding */
/******************************************************************************/
void

View File

@@ -64,7 +64,8 @@ Msig::operator()(Env& env, JTx& jt) const
{
auto const mySigners = signers;
auto callback = [subField = subField, mySigners, &env](Env&, JTx& jtx) {
// Where to put the signature. Supports sfCounterPartySignature.
// Where to put the signature. Supports sfCounterPartySignature and
// sfSponsorSignature.
auto& sigObject = subField ? jtx[*subField] : jtx.jv;
// The signing pub key is only required at the top level.

View File

@@ -44,6 +44,24 @@ Owners::operator()(Env& env) const
env.test.expect(env.le(account_)->getFieldU32(sfOwnerCount) == value_);
}
void
SponsoredOwners::operator()(Env& env) const
{
env.test.expect(env.le(account_)->getFieldU32(sfSponsoredOwnerCount) == value_);
}
void
SponsoringOwners::operator()(Env& env) const
{
env.test.expect(env.le(account_)->getFieldU32(sfSponsoringOwnerCount) == value_);
}
void
SponsoringAccountCount::operator()(Env& env) const
{
env.test.expect(env.le(account_)->getFieldU32(sfSponsoringAccountCount) == value_);
}
} // namespace test::jtx
} // namespace xrpl

View File

@@ -18,7 +18,7 @@ Sig::operator()(Env&, JTx& jt) const
// VFALCO Inefficient pre-C++14
auto const account = *account_;
auto callback = [subField = subField_, account](Env&, JTx& jtx) {
// Where to put the signature. Supports sfCounterPartySignature.
// Where to put the signature. Supports sfCounterPartySignature and sfSponsorSignature.
auto& sigObject = subField ? jtx[*subField] : jtx.jv;
jtx::sign(jtx.jv, account, sigObject);

View File

@@ -0,0 +1,98 @@
#include <test/jtx/sponsor.h>
#include <test/jtx/Account.h>
#include <test/jtx/Env.h>
#include <test/jtx/JTx.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/json/json_value.h>
#include <xrpl/json/to_string.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STAmount.h>
#include <xrpl/protocol/TxFlags.h>
#include <xrpl/protocol/jss.h>
#include <cstdint>
#include <optional>
namespace xrpl::test::jtx::sponsor {
json::Value
set(jtx::Account const& account,
uint32_t flags,
std::optional<uint32_t> const reserveCount,
std::optional<STAmount> const feeAmount,
std::optional<STAmount> const maxFee)
{
json::Value jv;
jv[jss::TransactionType] = jss::SponsorshipSet;
jv[jss::Account] = account.human();
jv[sfFlags.jsonName] = flags;
if (reserveCount)
jv[sfRemainingOwnerCount.jsonName] = *reserveCount;
if (feeAmount)
jv[sfFeeAmount.jsonName] = feeAmount->getJson(JsonOptions::Values::None);
if (maxFee)
jv[sfMaxFee.jsonName] = maxFee->getJson(JsonOptions::Values::None);
return jv;
}
json::Value
del(jtx::Account const& account)
{
json::Value jv;
jv[jss::TransactionType] = jss::SponsorshipSet;
jv[jss::Account] = account.human();
jv[sfFlags.jsonName] = tfDeleteObject;
return jv;
}
json::Value
transfer(jtx::Account const& account, uint32_t flags, std::optional<uint256> const& index)
{
json::Value jv;
jv[jss::TransactionType] = jss::SponsorshipTransfer;
jv[jss::Account] = account.human();
jv[sfFlags.jsonName] = flags;
if (index)
jv[sfObjectID.jsonName] = to_string(*index);
return jv;
}
void
CounterpartySponsor::operator()(Env& env, JTx& jt) const
{
jt.jv[sfCounterpartySponsor.jsonName] = sponsor_.human();
}
void
SponseeAcc::operator()(Env& env, JTx& jt) const
{
jt.jv[sfSponsee.jsonName] = sponsee_.human();
}
void
As::operator()(Env& env, JTx& jt) const
{
jt.jv[sfSponsor.jsonName] = sponsor_.human();
jt.jv[sfSponsorFlags.jsonName] = flags_;
}
json::Value
ledgerEntry(jtx::Env& env, jtx::Account const& sponsor, jtx::Account const& sponsee)
{
json::Value jvParams;
jvParams[jss::ledger_index] = jss::validated;
jvParams[jss::sponsorship][jss::sponsor] = sponsor.human();
jvParams[jss::sponsorship][jss::sponsee] = sponsee.human();
return env.rpc("json", "ledger_entry", to_string(jvParams));
}
STAmount
sponsorshipFeeBalance(jtx::Env& env, jtx::Account const& sponsor, jtx::Account const& sponsee)
{
return env.le(keylet::sponsorship(sponsor, sponsee))->getFieldAmount(sfFeeAmount).xrp();
}
} // namespace xrpl::test::jtx::sponsor