change sfSponsor to STAccount, Sponsor flags as global flags

This commit is contained in:
tequ
2026-01-27 12:38:01 +09:00
parent ce8049a17f
commit 88e870b1c6
9 changed files with 47 additions and 61 deletions

View File

@@ -40,12 +40,12 @@ namespace xrpl {
// Universal Transaction flags:
constexpr std::uint32_t tfFullyCanonicalSig = 0x80000000;
constexpr std::uint32_t tfInnerBatchTxn = 0x40000000;
constexpr std::uint32_t tfUniversal = tfFullyCanonicalSig | tfInnerBatchTxn;
constexpr std::uint32_t tfSponsorFee = 0x20000000;
constexpr std::uint32_t tfSponsorReserve = 0x10000000;
constexpr std::uint32_t tfUniversal = tfFullyCanonicalSig | tfInnerBatchTxn | tfSponsorFee | tfSponsorReserve;
constexpr std::uint32_t tfUniversalMask = ~tfUniversal;
// Sponsor flags (Global):
constexpr std::uint32_t tfSponsorFee = 0x00000001;
constexpr std::uint32_t tfSponsorReserve = 0x00000002;
constexpr std::uint32_t tfSponsorMask = ~(tfSponsorFee | tfSponsorReserve);
// AccountSet flags:

View File

@@ -334,7 +334,8 @@ TYPED_SFIELD(sfCounterparty, ACCOUNT, 26)
TYPED_SFIELD(sfSponsorAccount, ACCOUNT, 27)
TYPED_SFIELD(sfHighSponsorAccount, ACCOUNT, 28)
TYPED_SFIELD(sfLowSponsorAccount, ACCOUNT, 29)
TYPED_SFIELD(sfSponsee, ACCOUNT, 30)
TYPED_SFIELD(sfSponsor, ACCOUNT, 30)
TYPED_SFIELD(sfSponsee, ACCOUNT, 31)
// vector of 256-bit
TYPED_SFIELD(sfIndexes, VECTOR256, 1, SField::sMD_Never)
@@ -399,8 +400,7 @@ UNTYPED_SFIELD(sfRawTransaction, OBJECT, 34)
UNTYPED_SFIELD(sfBatchSigner, OBJECT, 35)
UNTYPED_SFIELD(sfBook, OBJECT, 36)
UNTYPED_SFIELD(sfCounterpartySignature, OBJECT, 37, SField::sMD_Default, SField::notSigning)
UNTYPED_SFIELD(sfSponsor, OBJECT, 38)
UNTYPED_SFIELD(sfSponsorSignature, OBJECT, 39, SField::sMD_Default, SField::notSigning)
UNTYPED_SFIELD(sfSponsorSignature, OBJECT, 38, SField::sMD_Default, SField::notSigning)
// array of objects (common)
// ARRAY/1 is reserved for end of array

View File

@@ -1118,8 +1118,7 @@ calculateReserve(std::shared_ptr<SLE const> const& sle, Fees const& fees)
bool
isReserveSponsored(STTx const& tx)
{
auto const sponsor = tx.getFieldObject(sfSponsor);
return sponsor.isFlag(tfSponsorReserve);
return tx.isFlag(tfSponsorReserve);
}
bool
@@ -1201,11 +1200,9 @@ checkInsufficientReserve(
std::optional<AccountID>
getTxReserveSponsorAccountID(STTx const& tx)
{
if (tx.isFieldPresent(sfSponsor))
if (tx.isFieldPresent(sfSponsor) && tx.isFlag(tfSponsorReserve))
{
auto const sponsorObj = tx.getFieldObject(sfSponsor);
if (sponsorObj.isFlag(tfSponsorReserve))
return sponsorObj.getAccountID(sfAccount);
return tx.getAccountID(sfSponsor);
}
return {};
}

View File

@@ -162,13 +162,6 @@ InnerObjectFormats::InnerObjectFormats()
{sfSigners, soeOPTIONAL},
});
add(sfSponsor.jsonName.c_str(),
sfSponsor.getCode(),
{
{sfAccount, soeREQUIRED},
{sfFlags, soeREQUIRED},
});
add(sfSponsorSignature.jsonName.c_str(),
sfSponsorSignature.getCode(),
{

View File

@@ -7,6 +7,7 @@
#include <xrpl/basics/strHex.h>
#include <xrpl/protocol/Feature.h>
#include "test/jtx/envconfig.h"
#include "test/jtx/sponsor.h"
namespace xrpl {
@@ -62,12 +63,19 @@ public:
Account const sponsor("sponsor");
env.fund(XRP(10000), alice, sponsor);
// check Sponsor field
env(noop(alice),
fee(XRP(1)),
sponsor::as(sponsor),
sig(sfSponsorSignature, sponsor),
ter(temDISABLED));
// check Sponsor flags
for (auto flag :
{tfSponsorFee, tfSponsorReserve, tfSponsorFee | tfSponsorReserve})
env(noop(alice), fee(XRP(1)), txflags(flag), ter(temINVALID_FLAG));
// check Sponsor transactions
env(sponsor::transfer(alice), ter(temDISABLED));
env(sponsor::set(sponsor, 0), ter(temDISABLED));
}
@@ -226,7 +234,7 @@ public:
// Signature doesn't exist
auto tx = noop(alice);
tx[sfSponsor.jsonName][sfAccount.jsonName] = sponsor.human();
tx[sfSponsor.jsonName] = sponsor.human();
tx[sfSponsorSignature.jsonName][sfSigningPubKey.jsonName] =
strHex(sponsor.pk().slice());
@@ -350,9 +358,6 @@ public:
// Invalid Flags
env(noop(alice), sponsor::as(sponsor, 4), ter(temINVALID_FLAG));
env(noop(alice),
sponsor::as(sponsor, tfSponsorMask),
ter(temINVALID_FLAG));
}
void

View File

@@ -96,8 +96,8 @@ sponseeAcc::operator()(Env& env, JTx& jt) const
void
as::operator()(Env& env, JTx& jt) const
{
jt.jv[sfSponsor.jsonName][sfAccount.jsonName] = sponsor_.human();
jt.jv[sfSponsor.jsonName][sfFlags.jsonName] = flags;
jt.jv[sfSponsor.jsonName] = sponsor_.human();
jt.jv[sfFlags.jsonName] = jt.jv[sfFlags.jsonName].asUInt() | flags;
}
Json::Value

View File

@@ -651,8 +651,8 @@ class Simulate_test : public beast::unit_test::suite
tx[jss::Account] = env.master.human();
tx[jss::TransactionType] = jss::AccountSet;
tx[sfDomain] = newDomain;
tx[sfSponsor.jsonName][sfAccount.jsonName] = sponsor.human();
tx[sfSponsor.jsonName][sfFlags.jsonName] = tfSponsorFee;
tx[sfSponsor.jsonName] = sponsor.human();
tx[sfFlags.jsonName] = tfSponsorFee;
tx[sfSponsorSignature.jsonName] = Json::objectValue;
// test with autofill

View File

@@ -332,9 +332,8 @@ SponsorshipTransfer::doApply()
if (tx.isFieldPresent(sfSponsor))
{
auto const sponsorObj = tx.getFieldObject(sfSponsor);
auto const oldSponsor = objSle->getAccountID(sponsorField);
auto const newSponsor = sponsorObj[sfAccount];
auto const newSponsor = tx.getAccountID(sfSponsor);
// decrement old sponsoring count if exists
if (auto const oldSponsorSle =
view().peek(keylet::account(oldSponsor)))
@@ -398,9 +397,8 @@ SponsorshipTransfer::doApply()
if (tx.isFieldPresent(sfSponsor))
{
// transfer account sponsor
auto const sponsorObj = tx.getFieldObject(sfSponsor);
// increment new sponsoring count
auto const newSponsor = sponsorObj[sfAccount];
auto const newSponsor = tx.getAccountID(sfSponsor);
auto const newSponsorSle = view().peek(keylet::account(newSponsor));
setSponsorFieldU32(newSponsorSle, sfSponsoringAccountCount, 1);

View File

@@ -73,6 +73,14 @@ preflight0(PreflightContext const& ctx, std::uint32_t flagMask)
return temINVALID_FLAG;
}
if (!ctx.rules.enabled(featureSponsor) &&
ctx.tx.getFlags() & ~tfSponsorMask)
{
JLOG(ctx.j.debug()) << "preflight0: Sponsor flags set without Sponsor "
"amendment enabled";
return temINVALID_FLAG;
}
return tesSUCCESS;
}
@@ -206,20 +214,11 @@ Transactor::preflight1(PreflightContext const& ctx, std::uint32_t flagMask)
"Inner batch transaction must have a parent batch ID.");
// Sponsor checks
if (hasSponsor)
if (hasSponsor && ctx.tx.getAccountID(sfSponsor) == id)
{
auto const sponsor = ctx.tx.getFieldObject(sfSponsor);
if (sponsor[sfAccount] == ctx.tx[sfAccount])
{
JLOG(ctx.j.debug()) << "preflight1: Sponsor account cannot be the "
"same as the transaction originator";
return temMALFORMED;
}
if (sponsor.getFlags() & tfSponsorMask)
{
JLOG(ctx.j.debug()) << "preflight1: Invalid sponsor flags";
return temINVALID_FLAG;
}
JLOG(ctx.j.debug()) << "preflight1: Sponsor account cannot be the "
"same as the transaction originator";
return temMALFORMED;
}
return tesSUCCESS;
@@ -321,21 +320,18 @@ Transactor::checkSponsor(ReadView const& view, STTx const& tx)
if (hasSponsorSignature)
return tesSUCCESS;
auto const txSponsor = tx.getFieldObject(sfSponsor);
auto const sponsorAcc = txSponsor.getAccountID(sfAccount);
auto const sponseeAcc = tx.getAccountID(sfAccount);
auto const sponsorSle = view.read(keylet::sponsor(sponsorAcc, sponseeAcc));
auto const sponsorSle = view.read(keylet::sponsor(
tx.getAccountID(sfSponsor), tx.getAccountID(sfAccount)));
// sponsorship object missing for pre-funded tx
if (!sponsorSle)
return terNO_SPONSORSHIP;
if (txSponsor.isFlag(tfSponsorFee) &&
if (tx.isFlag(tfSponsorFee) &&
sponsorSle->isFlag(lsfSponsorshipRequireSignForFee))
return terNO_SPONSORSHIP;
if (txSponsor.isFlag(tfSponsorReserve) &&
if (tx.isFlag(tfSponsorReserve) &&
sponsorSle->isFlag(lsfSponsorshipRequireSignForReserve))
return terNO_SPONSORSHIP;
@@ -807,8 +803,7 @@ Transactor::checkSign(
if (!sigObject.isFieldPresent(sfSponsor))
return tefINTERNAL; // LCOV_EXCL_LINE
auto const sponsorObj = sigObject.getFieldObject(sfSponsor);
auto const sponsorAcc = sponsorObj.getAccountID(sfAccount);
auto const sponsorAcc = sigObject.getAccountID(sfSponsor);
auto const sponsorSignature =
sigObject.getFieldObject(sfSponsorSignature);
if (auto const ret = checkSign(
@@ -1247,13 +1242,12 @@ Transactor::reset(XRPAmount fee)
FeePayer
Transactor::getFeePayer(ReadView const& view, STTx const& tx)
{
if (tx.isFieldPresent(sfSponsor) &&
tx.getFieldObject(sfSponsor).isFlag(tfSponsorFee))
auto const id = tx.getAccountID(sfAccount);
if (tx.isFieldPresent(sfSponsor) && tx.isFlag(tfSponsorFee))
{
auto const sponsor = tx.getFieldObject(sfSponsor);
auto const sponsor = tx.getAccountID(sfSponsor);
auto const hasSignature = tx.isFieldPresent(sfSponsorSignature);
auto const sponsorKeylet = keylet::sponsor(
sponsor.getAccountID(sfAccount), tx.getAccountID(sfAccount));
auto const sponsorKeylet = keylet::sponsor(sponsor, id);
if (hasSignature)
{
@@ -1263,8 +1257,7 @@ Transactor::getFeePayer(ReadView const& view, STTx const& tx)
sponsorKeylet, sfFeeAmount, FeePayerType::SponsorPreFunded};
// co-signed
auto const sponsorAccountKeylet =
keylet::account(sponsor.getAccountID(sfAccount));
auto const sponsorAccountKeylet = keylet::account(sponsor);
return FeePayer{
sponsorAccountKeylet, sfBalance, FeePayerType::SponsorCoSigned};
}
@@ -1281,7 +1274,7 @@ Transactor::getFeePayer(ReadView const& view, STTx const& tx)
return FeePayer{delegatorKeylet, sfBalance, FeePayerType::Delegate};
}
auto const accountKeylet = keylet::account(tx.getAccountID(sfAccount));
auto const accountKeylet = keylet::account(id);
return FeePayer{accountKeylet, sfBalance, FeePayerType::Account};
}