From 84e84fbadf3c08e61a9b63ca15da945c94d662ac Mon Sep 17 00:00:00 2001 From: tequ Date: Mon, 13 Apr 2026 14:03:37 +0900 Subject: [PATCH] fix Sponsor able to provide sponsorship with just base reserve --- src/libxrpl/tx/Transactor.cpp | 10 +++++++++- src/test/app/Sponsor_test.cpp | 22 +++++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/libxrpl/tx/Transactor.cpp b/src/libxrpl/tx/Transactor.cpp index b2e48f93a1..413a821354 100644 --- a/src/libxrpl/tx/Transactor.cpp +++ b/src/libxrpl/tx/Transactor.cpp @@ -479,7 +479,15 @@ Transactor::checkFee(PreclaimContext const& ctx, XRPAmount baseFee) if (payerSle->getType() != ltACCOUNT_ROOT) return tefINTERNAL; // LCOV_EXCL_LINE - maxSpendable = payerSle->getFieldAmount(payer.balanceField).xrp(); + if (payer.type == FeePayerType::SponsorCoSigned) + { + STAmount const sponsorReserve = calculateReserve(payerSle, ctx.view.fees()); + maxSpendable = payerSle->getFieldAmount(sfBalance).xrp() - sponsorReserve.xrp(); + } + else + { + maxSpendable = payerSle->getFieldAmount(payer.balanceField).xrp(); + } } // NOTE: Because preclaim evaluates against a static readview, it diff --git a/src/test/app/Sponsor_test.cpp b/src/test/app/Sponsor_test.cpp index e1638de7f1..9c48f8ba25 100644 --- a/src/test/app/Sponsor_test.cpp +++ b/src/test/app/Sponsor_test.cpp @@ -1444,6 +1444,27 @@ public: BEAST_EXPECT(env.balance(bob) == bobBalance); BEAST_EXPECT(env.balance(sponsor) == sponsorBalance - feeAmt); } + + { + // below reserve + adjustAccountXRPBalance(env, sponsor, env.current()->fees().reserve); + env.close(); + auto const feeAmt = XRP(4); + + env(noop(alice), + fee(env.current()->fees().base), + sponsor::as(sponsor, spfSponsorFee), + sig(sfSponsorSignature, sponsor), + ter(terINSUF_FEE_B)); + env.close(); + + env(noop(alice), + fee(XRP(10)), + sponsor::as(sponsor, spfSponsorFee), + sig(sfSponsorSignature, sponsor), + ter(terINSUF_FEE_B)); + env.close(); + } } { @@ -1595,7 +1616,6 @@ public: BEAST_EXPECT(env.le(keylet::sponsor(sponsor, alice))->isFieldPresent(sfFeeAmount)); auto sponsorAvailableFee = sponsorFeeBalance(sponsor, alice); - printf("sponsorAvailableFee: %s\n", to_string(sponsorAvailableFee).c_str()); env(check::cancel(alice, uint256(1)), fee(sponsorAvailableFee), sponsor::as(sponsor, spfSponsorFee),