fix: Disallow sponsored tx to be queued (#7674)

This commit is contained in:
yinyiqian1
2026-06-30 14:21:10 -04:00
committed by GitHub
parent 09b5cd9879
commit efeedcdc60
2 changed files with 45 additions and 0 deletions

View File

@@ -19,6 +19,8 @@
#include <test/jtx/require.h>
#include <test/jtx/sendmax.h>
#include <test/jtx/seq.h>
#include <test/jtx/sig.h>
#include <test/jtx/sponsor.h>
#include <test/jtx/tags.h>
#include <test/jtx/ter.h>
#include <test/jtx/ticket.h>
@@ -2335,6 +2337,43 @@ public:
BEAST_EXPECT(env.balance(alice) == drops(5));
}
void
testSponsorTxCannotQueue()
{
using namespace jtx;
testcase("disallow sponsored transaction from being queued");
Env env(*this, makeConfig({{Keys::kMinimumTxnInLedgerStandalone, "3"}}));
auto sponsor = Account("sponsor");
auto sponsee = Account("sponsee");
auto filler = Account("filler");
env.fund(XRP(50000), noripple(sponsor, sponsee));
env.close();
env.fund(XRP(50000), noripple(filler));
env.close();
fillQueue(env, filler);
checkMetrics(*this, env, 0, 6, 4, 3);
// Sponsored transactions are not allowed to be queued.
env(noop(sponsee),
sponsor::As(sponsor, spfSponsorFee),
Sig(sfSponsorSignature, sponsor),
Ter(telCAN_NOT_QUEUE));
checkMetrics(*this, env, 0, 6, 4, 3);
// Sponsored transactions may still apply directly if they pay the
// open ledger fee. They just cannot be held in the queue.
env(noop(sponsee),
sponsor::As(sponsor, spfSponsorFee),
Sig(sfSponsorSignature, sponsor),
Fee(openLedgerCost(env)),
Ter(tesSUCCESS));
checkMetrics(*this, env, 0, 6, 5, 3);
}
void
testConsequences()
{
@@ -4662,6 +4701,7 @@ public:
testBlockersSeq();
testBlockersTicket();
testInFlightBalance();
testSponsorTxCannotQueue();
testConsequences();
}

View File

@@ -15,6 +15,7 @@
#include <xrpl/ledger/ApplyViewImpl.h>
#include <xrpl/ledger/OpenView.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/ledger/helpers/SponsorHelpers.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/Keylet.h>
@@ -398,6 +399,10 @@ TxQ::canBeHeld(
((flags & TapFailHard) != 0u))
return telCAN_NOT_QUEUE;
// Disallow sponsored transactions from being queued.
if (tx.isFieldPresent(sfSponsor) && isFeeSponsored(tx))
return telCAN_NOT_QUEUE;
{
// To be queued and relayed, the transaction needs to
// promise to stick around for long enough that it has