test SponsorshipRequire flags

This commit is contained in:
tequ
2025-09-15 22:48:40 +09:00
parent 2a27280f1a
commit 5ac7bbf51b
3 changed files with 89 additions and 33 deletions

View File

@@ -118,19 +118,12 @@ public:
env(sponsor::set(sponsor, sponsor, 0), ter(temMALFORMED));
// Invalid feeAmount
env(sponsor::set_fee(
sponsor, alice, tfSponsorshipClearRequireSignForFee, XRP(1)),
ter(temMALFORMED));
for (auto amt : {XRP(-1), XRP(0), USD(1)})
{
env(sponsor::set_fee(sponsor, alice, 0, amt), ter(temBAD_AMOUNT));
}
// Invalid reserveCount
env(sponsor::set_reserve(
sponsor, alice, tfSponsorshipClearRequireSignForReserve, 1),
ter(temMALFORMED));
env(sponsor::set_reserve(sponsor, alice, 0, 0), ter(temMALFORMED));
// Invalid Delete operation
@@ -686,6 +679,38 @@ public:
sponsorFeeBalance(sponsor, alice) == sponsorFee - feeAmt);
}
}
// test lsfSponsorshipRequireSignForFee
{
Env env{*this, testable_amendments()};
Account const alice("alice");
Account const bob("bob");
Account const sponsor("sponsor");
env.fund(XRP(10000), alice, bob, sponsor);
env.close();
// set flag
env(sponsor::set_fee(
sponsor, alice, tfSponsorshipSetRequireSignForFee, XRP(10)));
env.close();
env(pay(alice, bob, XRP(100)),
fee(XRP(10)),
sponsor::as(sponsor, tfSponsorFee),
ter(terNO_SPONSORSHIP));
env.close();
// clear flag
env(sponsor::set_fee(
sponsor, alice, tfSponsorshipClearRequireSignForFee, XRP(10)));
env.close();
env(pay(alice, bob, XRP(100)),
fee(XRP(10)),
sponsor::as(sponsor, tfSponsorFee),
ter(tesSUCCESS));
env.close();
}
}
void
@@ -741,6 +766,42 @@ public:
}
}
void
testRequireFlag()
{
testcase("SponsorshipRequireSignForReserve");
using namespace test::jtx;
Env env{*this, testable_amendments()};
Account const alice("alice");
Account const bob("bob");
Account const sponsor("sponsor");
env.fund(XRP(10000), alice, bob, sponsor);
env.close();
// set flag
env(sponsor::set_reserve(
sponsor, alice, tfSponsorshipSetRequireSignForReserve, 10));
env.close();
env(check::create(alice, bob, XRP(100)),
fee(XRP(10)),
sponsor::as(sponsor, tfSponsorReserve),
ter(terNO_SPONSORSHIP));
env.close();
// clear flag
env(sponsor::set_reserve(
sponsor, alice, tfSponsorshipClearRequireSignForReserve, 1));
env.close();
env(check::create(alice, bob, XRP(100)),
fee(XRP(10)),
sponsor::as(sponsor, tfSponsorReserve),
ter(tesSUCCESS));
env.close();
}
void
testCheck()
{
@@ -1269,6 +1330,7 @@ public:
void
testSponsorReserve()
{
testRequireFlag();
testCheck();
testOfffer();
testTicket();

View File

@@ -82,9 +82,6 @@ SponsorshipSet::preflight(PreflightContext const& ctx)
if (ctx.tx.isFieldPresent(sfFeeAmount))
{
if (ctx.tx.getFlags() & tfSponsorshipClearRequireSignForFee)
return temMALFORMED;
auto const feeAmount = ctx.tx.getFieldAmount(sfFeeAmount);
if (!isXRP(feeAmount))
@@ -108,9 +105,6 @@ SponsorshipSet::preflight(PreflightContext const& ctx)
if (ctx.tx.isFieldPresent(sfReserveCount))
{
if (ctx.tx.getFlags() & tfSponsorshipClearRequireSignForReserve)
return temMALFORMED;
auto const reserveCount = ctx.tx.getFieldU32(sfReserveCount);
// TODO: max reserveCount?
if (reserveCount < 1)
@@ -158,12 +152,13 @@ TER
SponsorshipSet::doApply()
{
auto const sponseeAcc = ctx_.tx[sfSponsee];
auto const keylet = keylet::sponsor(account_, sponseeAcc);
auto const sponsorAcc = ctx_.tx.isFieldPresent(sfSponsorAccount)
? ctx_.tx.getAccountID(sfSponsorAccount)
: account_;
auto const keylet = keylet::sponsor(sponsorAcc, sponseeAcc);
auto const sponsorAccSle = ctx_.view().peek(keylet::account(sponsorAcc));
if (!sponsorAccSle)
return tecINTERNAL;
@@ -222,7 +217,6 @@ SponsorshipSet::doApply()
(*newSle)[sfOwner] = sponsorAcc;
(*newSle)[sfSponsee] = sponseeAcc;
(*newSle)[sfFlags] = ctx_.tx.getFlags();
if (feeAmount)
{
(*sponsorAccSle)[sfBalance] -= *feeAmount;
@@ -237,6 +231,15 @@ SponsorshipSet::doApply()
(*newSle)[sfReserveCount] = *reserveCount;
}
auto flags = 0;
if (ctx_.tx.isFlag(tfSponsorshipSetRequireSignForFee))
flags |= lsfSponsorshipRequireSignForFee;
if (ctx_.tx.isFlag(tfSponsorshipSetRequireSignForReserve))
flags |= lsfSponsorshipRequireSignForReserve;
(*newSle)[sfFlags] = flags;
auto const sponsorPage = view().dirInsert(
keylet::ownerDir(sponsorAcc), keylet, describeOwnerDir(sponsorAcc));
(*newSle)[sfOwnerNode] = *sponsorPage;

View File

@@ -259,35 +259,26 @@ Transactor::checkSponsor(ReadView const& view, STTx const& tx)
auto const sponsorAcc = txSponsor.getAccountID(sfAccount);
auto const sponseeAcc = tx.getAccountID(sfAccount);
auto const hasSignature = txSponsor.isFieldPresent(sfTxnSignature) ||
auto const hasSponsorSignature = txSponsor.isFieldPresent(sfTxnSignature) ||
!txSponsor.getFieldVL(sfSigningPubKey).empty() ||
txSponsor.isFieldPresent(sfSigners);
auto const sponsorSle = view.read(keylet::sponsor(sponsorAcc, sponseeAcc));
if (!hasSignature)
if (!hasSponsorSignature)
{
auto const sponsorSle =
view.read(keylet::sponsor(sponsorAcc, sponseeAcc));
// pre funded
if (!sponsorSle)
return tecNO_SPONSOR_PERMISSION;
}
else
{
// co-signed
if (!sponsorSle)
return tesSUCCESS;
return terNO_SPONSORSHIP;
if (txSponsor.isFlag(tfSponsorFee) &&
sponsorSle->isFlag(lsfSponsorshipRequireSignForFee))
{
if (!hasSignature)
return tecNO_SPONSOR_PERMISSION;
}
return terNO_SPONSORSHIP;
if (txSponsor.isFlag(tfSponsorReserve) &&
sponsorSle->isFlag(lsfSponsorshipRequireSignForReserve))
{
if (!hasSignature)
return tecNO_SPONSOR_PERMISSION;
}
return terNO_SPONSORSHIP;
}
return tesSUCCESS;