feat: Update to keylet::sponsorship and sfRemainingOwnerCount (#7578)

This commit is contained in:
Mayukha Vadari
2026-06-22 11:07:59 -04:00
committed by GitHub
parent d1a77b453e
commit c3b3bce35d
17 changed files with 136 additions and 123 deletions

View File

@@ -153,7 +153,7 @@ signers(AccountID const& account) noexcept;
/** A Sponsorship */
Keylet
sponsor(AccountID const& sponsor, AccountID const& sponsee) noexcept;
sponsorship(AccountID const& sponsor, AccountID const& sponsee) noexcept;
/** A Check */
/** @{ */

View File

@@ -622,7 +622,7 @@ LEDGER_ENTRY(ltSPONSORSHIP, 0x0090, Sponsorship, sponsorship, ({
{sfSponsee, SoeRequired},
{sfFeeAmount, SoeOptional},
{sfMaxFee, SoeOptional},
{sfReserveCount, SoeDefault},
{sfRemainingOwnerCount, SoeDefault},
{sfOwnerNode, SoeRequired},
{sfSponseeNode, SoeRequired},
}))

View File

@@ -116,7 +116,7 @@ TYPED_SFIELD(sfOverpaymentInterestRate, UINT32, 68) // 1/10 basis points (bi
TYPED_SFIELD(sfSponsoredOwnerCount, UINT32, 69)
TYPED_SFIELD(sfSponsoringOwnerCount, UINT32, 70)
TYPED_SFIELD(sfSponsoringAccountCount, UINT32, 71)
TYPED_SFIELD(sfReserveCount, UINT32, 72)
TYPED_SFIELD(sfRemainingOwnerCount, UINT32, 72)
TYPED_SFIELD(sfSponsorFlags, UINT32, 73)
// 64-bit integers (common)

View File

@@ -1103,7 +1103,7 @@ TRANSACTION(ttSPONSORSHIP_SET, 86, SponsorshipSet,
{sfSponsee, SoeOptional},
{sfFeeAmount, SoeOptional},
{sfMaxFee, SoeOptional},
{sfReserveCount, SoeOptional},
{sfRemainingOwnerCount, SoeOptional},
}))
/** This system-generated transaction type is used to update the status of the various amendments.

View File

@@ -138,27 +138,27 @@ public:
}
/**
* @brief Get sfReserveCount (SoeDefault)
* @brief Get sfRemainingOwnerCount (SoeDefault)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_UINT32::type::value_type>
getReserveCount() const
getRemainingOwnerCount() const
{
if (hasReserveCount())
return this->sle_->at(sfReserveCount);
if (hasRemainingOwnerCount())
return this->sle_->at(sfRemainingOwnerCount);
return std::nullopt;
}
/**
* @brief Check if sfReserveCount is present.
* @brief Check if sfRemainingOwnerCount is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasReserveCount() const
hasRemainingOwnerCount() const
{
return this->sle_->isFieldPresent(sfReserveCount);
return this->sle_->isFieldPresent(sfRemainingOwnerCount);
}
/**
@@ -297,13 +297,13 @@ public:
}
/**
* @brief Set sfReserveCount (SoeDefault)
* @brief Set sfRemainingOwnerCount (SoeDefault)
* @return Reference to this builder for method chaining.
*/
SponsorshipBuilder&
setReserveCount(std::decay_t<typename SF_UINT32::type::value_type> const& value)
setRemainingOwnerCount(std::decay_t<typename SF_UINT32::type::value_type> const& value)
{
object_[sfReserveCount] = value;
object_[sfRemainingOwnerCount] = value;
return *this;
}

View File

@@ -152,29 +152,29 @@ public:
}
/**
* @brief Get sfReserveCount (SoeOptional)
* @brief Get sfRemainingOwnerCount (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_UINT32::type::value_type>
getReserveCount() const
getRemainingOwnerCount() const
{
if (hasReserveCount())
if (hasRemainingOwnerCount())
{
return this->tx_->at(sfReserveCount);
return this->tx_->at(sfRemainingOwnerCount);
}
return std::nullopt;
}
/**
* @brief Check if sfReserveCount is present.
* @brief Check if sfRemainingOwnerCount is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasReserveCount() const
hasRemainingOwnerCount() const
{
return this->tx_->isFieldPresent(sfReserveCount);
return this->tx_->isFieldPresent(sfRemainingOwnerCount);
}
};
@@ -263,13 +263,13 @@ public:
}
/**
* @brief Set sfReserveCount (SoeOptional)
* @brief Set sfRemainingOwnerCount (SoeOptional)
* @return Reference to this builder for method chaining.
*/
SponsorshipSetBuilder&
setReserveCount(std::decay_t<typename SF_UINT32::type::value_type> const& value)
setRemainingOwnerCount(std::decay_t<typename SF_UINT32::type::value_type> const& value)
{
object_[sfReserveCount] = value;
object_[sfRemainingOwnerCount] = value;
return *this;
}

View File

@@ -274,13 +274,14 @@ adjustOwnerCount(
adjustOwnerCountHlp(view, accountSle, sfSponsoredOwnerCount, accountID, adjustment, j);
adjustOwnerCountHlp(view, sponsorSle, sfSponsoringOwnerCount, sponsorID, adjustment, j);
auto sponsorObjSle = view.peek(keylet::sponsor(sponsorID, accountID));
auto sponsorObjSle = view.peek(keylet::sponsorship(sponsorID, accountID));
if (sponsorObjSle && adjustment > 0)
{
// update the pre-funded ReserveCount on Sponsorship ledger object
// Reserve count moves opposite to adjustment: +adjustment => consume reserve (-),
// update the pre-funded RemainingOwnerCount on Sponsorship ledger object
// Remaining owner count moves opposite to adjustment:
// +adjustment => consume reserve (-),
adjustOwnerCountHlp(
view, sponsorObjSle, sfReserveCount, sponsorID, -adjustment, j, false);
view, sponsorObjSle, sfRemainingOwnerCount, sponsorID, -adjustment, j, false);
}
}
adjustOwnerCountHlp(view, accountSle, sfOwnerCount, accountID, adjustment, j);
@@ -345,7 +346,8 @@ checkInsufficientReserve(
auto const isCoSigning = isSponsorReserveCoSigning(tx);
auto const sle = view.read(
keylet::sponsor(sponsorSle->getAccountID(sfAccount), accSle->getAccountID(sfAccount)));
keylet::sponsorship(
sponsorSle->getAccountID(sfAccount), accSle->getAccountID(sfAccount)));
// prefunded sponsor should have a sponsorship entry
if (!isCoSigning && !sle)
@@ -353,7 +355,7 @@ checkInsufficientReserve(
if (sle)
{
auto const ownerCountAllowed = sle->getFieldU32(sfReserveCount);
auto const ownerCountAllowed = sle->getFieldU32(sfRemainingOwnerCount);
if (ownerCountAllowed < ownerCountDelta)
return tecINSUFFICIENT_RESERVE;
}

View File

@@ -320,7 +320,7 @@ signers(AccountID const& account) noexcept
}
Keylet
sponsor(AccountID const& sponsor, AccountID const& sponsee) noexcept
sponsorship(AccountID const& sponsor, AccountID const& sponsee) noexcept
{
return {ltSPONSORSHIP, indexHash(LedgerNameSpace::Sponsorship, sponsor, sponsee)};
}

View File

@@ -386,7 +386,7 @@ Transactor::checkSponsor(ReadView const& view, STTx const& tx)
return tesSUCCESS;
auto const sponsorshipSle =
view.read(keylet::sponsor(tx.getAccountID(sfSponsor), tx.getAccountID(sfAccount)));
view.read(keylet::sponsorship(tx.getAccountID(sfSponsor), tx.getAccountID(sfAccount)));
// sponsorship object missing for pre-funded tx
if (!sponsorshipSle)
@@ -1322,7 +1322,7 @@ Transactor::getFeePayer(ReadView const& view, STTx const& tx)
auto const sponsorAccountID = tx.getAccountID(sfSponsor);
auto const sponseeAccountID = tx.getAccountID(sfAccount);
auto const hasSponsorSignature = tx.isFieldPresent(sfSponsorSignature);
auto const sponsorshipKeylet = keylet::sponsor(sponsorAccountID, sponseeAccountID);
auto const sponsorshipKeylet = keylet::sponsorship(sponsorAccountID, sponseeAccountID);
// if pre-funded sponsorship exists, prefer it
if (hasSponsorSignature && !view.exists(sponsorshipKeylet))

View File

@@ -67,7 +67,7 @@ SponsorshipSet::preflight(PreflightContext const& ctx)
return temINVALID_FLAG;
// can not include these fields when deleting
if (ctx.tx.isFieldPresent(sfFeeAmount) || ctx.tx.isFieldPresent(sfReserveCount) ||
if (ctx.tx.isFieldPresent(sfFeeAmount) || ctx.tx.isFieldPresent(sfRemainingOwnerCount) ||
ctx.tx.isFieldPresent(sfMaxFee))
return temMALFORMED;
}
@@ -133,7 +133,7 @@ SponsorshipSet::checkPermission(ReadView const& view, STTx const& tx)
auto const sponsoringFee = tx.isFieldPresent(sfFeeAmount) || tx.isFieldPresent(sfMaxFee) ||
((txFlags & (tfSponsorshipSetRequireSignForFee | tfSponsorshipClearRequireSignForFee)) !=
0u);
auto const sponsoringReserve = tx.isFieldPresent(sfReserveCount) ||
auto const sponsoringReserve = tx.isFieldPresent(sfRemainingOwnerCount) ||
((txFlags &
(tfSponsorshipSetRequireSignForReserve | tfSponsorshipClearRequireSignForReserve)) != 0u);
@@ -170,7 +170,8 @@ SponsorshipSet::preclaim(PreclaimContext const& ctx)
return tecNO_PERMISSION;
// check if object exists
auto const sponsorObjSle = ctx.view.read(keylet::sponsor(sponsorAccountID, sponseeAccountID));
auto const sponsorObjSle =
ctx.view.read(keylet::sponsorship(sponsorAccountID, sponseeAccountID));
if (ctx.tx.isFlag(tfDeleteObject) && !sponsorObjSle)
return tecNO_ENTRY;
@@ -235,7 +236,7 @@ SponsorshipSet::doApply()
if (!ctx_.view().exists(keylet::account(sponseeAccountID)))
return tecINTERNAL; // LCOV_EXCL_LINE
auto const sponsorKeylet = keylet::sponsor(sponsorAccountID, sponseeAccountID);
auto const sponsorKeylet = keylet::sponsorship(sponsorAccountID, sponseeAccountID);
auto const sponsorObjSle = ctx_.view().peek(sponsorKeylet);
if (ctx_.tx.isFlag(tfDeleteObject))
@@ -249,7 +250,7 @@ SponsorshipSet::doApply()
auto const feeAmount = ctx_.tx[~sfFeeAmount];
auto const maxFee = ctx_.tx[~sfMaxFee];
auto const reserveCount = ctx_.tx[~sfReserveCount];
auto const reserveCount = ctx_.tx[~sfRemainingOwnerCount];
auto reserveSponsorAccSle = getTxReserveSponsor(view(), ctx_.tx);
if (!reserveSponsorAccSle)
@@ -286,7 +287,7 @@ SponsorshipSet::doApply()
if (maxFee && *maxFee > XRPAmount(0))
(*newSle)[sfMaxFee] = *maxFee;
if (reserveCount && *reserveCount > 0)
(*newSle)[sfReserveCount] = *reserveCount;
(*newSle)[sfRemainingOwnerCount] = *reserveCount;
auto flags = 0;
if (ctx_.tx.isFlag(tfSponsorshipSetRequireSignForFee))
@@ -367,7 +368,7 @@ SponsorshipSet::doApply()
}
if (reserveCount)
sponsorObjSle->at(sfReserveCount) = *reserveCount;
sponsorObjSle->at(sfRemainingOwnerCount) = *reserveCount;
// update Flags
auto flags = sponsorObjSle->getFieldU32(sfFlags);

View File

@@ -385,12 +385,13 @@ reduceReserveCount(
if (delta > 0)
return tefINTERNAL; // LCOV_EXCL_LINE
auto const sponsorKeylet = keylet::sponsor(sponsor, account);
auto const sponsorKeylet = keylet::sponsorship(sponsor, account);
auto const sponsorSle = view.peek(sponsorKeylet);
if (!sponsorSle)
return tefINTERNAL; // LCOV_EXCL_LINE
auto const afterReserveCount = applyCountDelta(sponsorSle->getFieldU32(sfReserveCount), delta);
auto const afterReserveCount =
applyCountDelta(sponsorSle->getFieldU32(sfRemainingOwnerCount), delta);
if (!afterReserveCount)
{
// already checked in preclaim()
@@ -398,7 +399,7 @@ reduceReserveCount(
return tefINTERNAL; // LCOV_EXCL_LINE
}
sponsorSle->at(sfReserveCount) = *afterReserveCount;
sponsorSle->at(sfRemainingOwnerCount) = *afterReserveCount;
view.update(sponsorSle);
return tesSUCCESS;
}

View File

@@ -322,8 +322,9 @@ public:
env.close();
// Increasing feeAmount to reach insufficient reserve
auto const currentFeeAmount =
env.le(keylet::sponsor(sponsor.id(), alice.id()))->getFieldAmount(sfFeeAmount).xrp();
auto const currentFeeAmount = env.le(keylet::sponsorship(sponsor.id(), alice.id()))
->getFieldAmount(sfFeeAmount)
.xrp();
adjustAccountXRPBalance(env, sponsor, XRP(310));
env(sponsor::set_fee(sponsor, 0, currentFeeAmount + XRP(309)),
sponsor::SponseeAcc(alice),
@@ -541,9 +542,9 @@ public:
Ter(tesSUCCESS));
env.close();
auto sle = env.le(keylet::sponsor(sponsor, alice));
auto sle = env.le(keylet::sponsorship(sponsor, alice));
BEAST_EXPECT(sle);
BEAST_EXPECT(sle->at(sfReserveCount) == 100);
BEAST_EXPECT(sle->at(sfRemainingOwnerCount) == 100);
BEAST_EXPECT(sle->at(sfFeeAmount) == XRP(100));
BEAST_EXPECT(sle->at(sfMaxFee) == XRP(1));
BEAST_EXPECT(sle->isFlag(lsfSponsorshipRequireSignForFee));
@@ -557,9 +558,9 @@ public:
Ter(tesSUCCESS));
env.close();
sle = env.le(keylet::sponsor(sponsor, alice));
sle = env.le(keylet::sponsorship(sponsor, alice));
BEAST_EXPECT(sle);
BEAST_EXPECT(sle->at(sfReserveCount) == 50);
BEAST_EXPECT(sle->at(sfRemainingOwnerCount) == 50);
BEAST_EXPECT(sle->at(sfFeeAmount) == XRP(50));
BEAST_EXPECT(sle->at(sfMaxFee) == XRP(0.5));
BEAST_EXPECT(env.balance(sponsor) == XRP(10000) - sle->at(sfFeeAmount) - XRP(2));
@@ -571,9 +572,9 @@ public:
Ter(tesSUCCESS));
env.close();
sle = env.le(keylet::sponsor(sponsor, alice));
sle = env.le(keylet::sponsorship(sponsor, alice));
BEAST_EXPECT(sle);
BEAST_EXPECT(sle->at(sfReserveCount) == 200);
BEAST_EXPECT(sle->at(sfRemainingOwnerCount) == 200);
BEAST_EXPECT(sle->at(sfFeeAmount) == XRP(200));
BEAST_EXPECT(sle->at(sfMaxFee) == XRP(2));
BEAST_EXPECT(env.balance(sponsor) == XRP(10000) - sle->at(sfFeeAmount) - XRP(3));
@@ -597,7 +598,7 @@ public:
// delete from sponsee
env(sponsor::del(alice), sponsor::CounterpartySponsor(sponsor), Ter(tesSUCCESS));
env.close();
BEAST_EXPECT(!env.le(keylet::sponsor(sponsor, alice)));
BEAST_EXPECT(!env.le(keylet::sponsorship(sponsor, alice)));
// create sponsorship with zero value
env(sponsor::set(sponsor, 0, 0, XRP(0), XRP(0)),
@@ -605,9 +606,9 @@ public:
Fee(XRP(1)));
env.close();
sle = env.le(keylet::sponsor(sponsor, alice));
sle = env.le(keylet::sponsorship(sponsor, alice));
BEAST_EXPECT(sle);
BEAST_EXPECT(!sle->isFieldPresent(sfReserveCount));
BEAST_EXPECT(!sle->isFieldPresent(sfRemainingOwnerCount));
BEAST_EXPECT(!sle->isFieldPresent(sfFeeAmount));
BEAST_EXPECT(!sle->isFieldPresent(sfMaxFee));
// verify flags from previous sponsorship are not carried over
@@ -620,9 +621,9 @@ public:
Fee(XRP(1)));
env.close();
sle = env.le(keylet::sponsor(sponsor, alice));
sle = env.le(keylet::sponsorship(sponsor, alice));
BEAST_EXPECT(sle);
BEAST_EXPECT(sle->at(sfReserveCount) == 100);
BEAST_EXPECT(sle->at(sfRemainingOwnerCount) == 100);
BEAST_EXPECT(sle->at(sfFeeAmount) == XRP(100));
BEAST_EXPECT(sle->at(sfMaxFee) == XRP(1));
@@ -632,9 +633,9 @@ public:
Fee(XRP(1)));
env.close();
sle = env.le(keylet::sponsor(sponsor, alice));
sle = env.le(keylet::sponsorship(sponsor, alice));
BEAST_EXPECT(sle);
BEAST_EXPECT(!sle->isFieldPresent(sfReserveCount));
BEAST_EXPECT(!sle->isFieldPresent(sfRemainingOwnerCount));
BEAST_EXPECT(!sle->isFieldPresent(sfFeeAmount));
BEAST_EXPECT(!sle->isFieldPresent(sfMaxFee));
}
@@ -716,17 +717,17 @@ public:
Ter(tesSUCCESS));
env.close();
auto sle = env.le(keylet::sponsor(sponsor, alice));
auto sle = env.le(keylet::sponsorship(sponsor, alice));
BEAST_EXPECT(sle);
BEAST_EXPECT(sle->at(sfReserveCount) == 99);
BEAST_EXPECT(sle->at(sfRemainingOwnerCount) == 99);
BEAST_EXPECT(sle->at(sfFeeAmount) == XRP(99));
env(did::del(alice), Ter(tesSUCCESS));
env.close();
sle = env.le(keylet::sponsor(sponsor, alice));
sle = env.le(keylet::sponsorship(sponsor, alice));
BEAST_EXPECT(sle);
BEAST_EXPECT(sle->at(sfReserveCount) == 99); // not paybacked
BEAST_EXPECT(sle->at(sfRemainingOwnerCount) == 99); // not paybacked
BEAST_EXPECT(sle->at(sfFeeAmount) == XRP(99));
}
@@ -1199,8 +1200,8 @@ public:
auto checkSle = env.le(keylet::unchecked(checkId));
BEAST_EXPECT(checkSle->isFieldPresent(sfSponsor));
BEAST_EXPECT(checkSle->getAccountID(sfSponsor) == sponsor1.id());
auto sponsor1Sle = env.le(keylet::sponsor(sponsor1, alice));
BEAST_EXPECT(sponsor1Sle->getFieldU32(sfReserveCount) == 99);
auto sponsor1Sle = env.le(keylet::sponsorship(sponsor1, alice));
BEAST_EXPECT(sponsor1Sle->getFieldU32(sfRemainingOwnerCount) == 99);
// transfer sponsor
env(sponsor::set_reserve(sponsor2, 0, 100), sponsor::SponseeAcc(alice));
@@ -1222,10 +1223,10 @@ public:
checkSle = env.le(keylet::unchecked(checkId));
BEAST_EXPECT(checkSle->isFieldPresent(sfSponsor));
BEAST_EXPECT(checkSle->getAccountID(sfSponsor) == sponsor2.id());
sponsor1Sle = env.le(keylet::sponsor(sponsor1, alice));
BEAST_EXPECT(sponsor1Sle->getFieldU32(sfReserveCount) == 99);
auto sponsor2Sle = env.le(keylet::sponsor(sponsor2, alice));
BEAST_EXPECT(sponsor2Sle->getFieldU32(sfReserveCount) == 99);
sponsor1Sle = env.le(keylet::sponsorship(sponsor1, alice));
BEAST_EXPECT(sponsor1Sle->getFieldU32(sfRemainingOwnerCount) == 99);
auto sponsor2Sle = env.le(keylet::sponsorship(sponsor2, alice));
BEAST_EXPECT(sponsor2Sle->getFieldU32(sfRemainingOwnerCount) == 99);
// dissolve sponsor
adjustAccountXRPBalance(env, alice, reserve(env, 1));
@@ -1245,8 +1246,8 @@ public:
!env.le(keylet::account(sponsor2))->isFieldPresent(sfSponsoringOwnerCount));
checkSle = env.le(keylet::unchecked(checkId));
BEAST_EXPECT(!checkSle->isFieldPresent(sfSponsor));
sponsor2Sle = env.le(keylet::sponsor(sponsor2, alice));
BEAST_EXPECT(sponsor2Sle->getFieldU32(sfReserveCount) == 99);
sponsor2Sle = env.le(keylet::sponsorship(sponsor2, alice));
BEAST_EXPECT(sponsor2Sle->getFieldU32(sfRemainingOwnerCount) == 99);
}
{
@@ -1319,7 +1320,8 @@ public:
BEAST_EXPECT(sponsoredOwnerCount(env, alice) == 1);
BEAST_EXPECT(sponsoringOwnerCount(env, sponsor) == 1);
BEAST_EXPECT(
env.le(keylet::sponsor(sponsor, alice))->getFieldU32(sfReserveCount) == 100);
env.le(keylet::sponsorship(sponsor, alice))->getFieldU32(sfRemainingOwnerCount) ==
100);
// not the owner of the object
env(sponsor::transfer(sponsor, tfSponsorshipEnd, checkId), Ter(tecNO_PERMISSION));
@@ -1333,7 +1335,8 @@ public:
BEAST_EXPECT(sponsoredOwnerCount(env, alice) == 0);
BEAST_EXPECT(sponsoringOwnerCount(env, sponsor) == 0);
BEAST_EXPECT(
env.le(keylet::sponsor(sponsor, alice))->getFieldU32(sfReserveCount) == 100);
env.le(keylet::sponsorship(sponsor, alice))->getFieldU32(sfRemainingOwnerCount) ==
100);
}
{
@@ -1552,7 +1555,9 @@ public:
env.close();
auto const sponsorFeeBalance = [&](Account const& sponsor, Account const& sponsee) {
return env.le(keylet::sponsor(sponsor, sponsee))->getFieldAmount(sfFeeAmount).xrp();
return env.le(keylet::sponsorship(sponsor, sponsee))
->getFieldAmount(sfFeeAmount)
.xrp();
};
{
@@ -1632,7 +1637,7 @@ public:
BEAST_EXPECT(env.balance(bob) == bobBalance + XRP(100));
BEAST_EXPECT(env.balance(sponsor) == sponsorBalance);
BEAST_EXPECT(
!env.le(keylet::sponsor(sponsor, alice))->isFieldPresent(sfFeeAmount));
!env.le(keylet::sponsorship(sponsor, alice))->isFieldPresent(sfFeeAmount));
}
// reset FeeAmount and MaxFee
@@ -1689,14 +1694,16 @@ public:
env(sponsor::set_fee(sponsor, 0, XRP(10)), sponsor::SponseeAcc(alice));
env.close();
BEAST_EXPECT(env.le(keylet::sponsor(sponsor, alice))->isFieldPresent(sfFeeAmount));
BEAST_EXPECT(
env.le(keylet::sponsorship(sponsor, alice))->isFieldPresent(sfFeeAmount));
auto sponsorAvailableFee = sponsorFeeBalance(sponsor, alice);
env(check::cancel(alice, uint256(1)),
Fee(sponsorAvailableFee),
sponsor::As(sponsor, spfSponsorFee),
Ter(tecNO_ENTRY));
env.close();
BEAST_EXPECT(!env.le(keylet::sponsor(sponsor, alice))->isFieldPresent(sfFeeAmount));
BEAST_EXPECT(
!env.le(keylet::sponsorship(sponsor, alice))->isFieldPresent(sfFeeAmount));
}
}
@@ -1730,7 +1737,7 @@ public:
BEAST_EXPECT(result.applied);
// Only MaxFee (10 drops) must be deducted, not the full 1000 drops.
auto const sle = overlay.read(keylet::sponsor(carol.id(), alice.id()));
auto const sle = overlay.read(keylet::sponsorship(carol.id(), alice.id()));
BEAST_EXPECT(sle);
BEAST_EXPECT(sle->isFieldPresent(sfFeeAmount));
BEAST_EXPECT(sle->getFieldAmount(sfFeeAmount) == drops(990)); // 1000 - MaxFee(10)
@@ -1757,7 +1764,8 @@ public:
env.close();
BEAST_EXPECT(
env.le(keylet::sponsor(sponsor, alice))->getFieldAmount(sfFeeAmount) == XRP(10));
env.le(keylet::sponsorship(sponsor, alice))->getFieldAmount(sfFeeAmount) ==
XRP(10));
// clear flag
env(sponsor::set_fee(sponsor, tfSponsorshipClearRequireSignForFee, XRP(10)),
@@ -1765,7 +1773,7 @@ public:
env.close();
// Payment is re-applied
BEAST_EXPECT(!env.le(keylet::sponsor(sponsor, alice))->isFieldPresent(sfFeeAmount));
BEAST_EXPECT(!env.le(keylet::sponsorship(sponsor, alice))->isFieldPresent(sfFeeAmount));
}
// RequireSignForFee: co-signing should succeed
@@ -1798,7 +1806,7 @@ public:
env.close();
BEAST_EXPECT(
env.le(keylet::sponsor(sponsor, alice))->getFieldAmount(sfFeeAmount) == XRP(9));
env.le(keylet::sponsorship(sponsor, alice))->getFieldAmount(sfFeeAmount) == XRP(9));
}
}
@@ -1974,7 +1982,8 @@ public:
BEAST_EXPECT(ownerCount(env, alice) == 0);
BEAST_EXPECT(
env.le(keylet::sponsor(sponsor, alice))->getFieldAmount(sfFeeAmount) == XRP(10));
env.le(keylet::sponsorship(sponsor, alice))->getFieldAmount(sfFeeAmount) ==
XRP(10));
// clear flag
env(sponsor::set_fee(sponsor, tfSponsorshipClearRequireSignForFee, XRP(10)),
@@ -1983,7 +1992,7 @@ public:
// CheckCreate is re-applied
BEAST_EXPECT(ownerCount(env, alice) == 1);
BEAST_EXPECT(!env.le(keylet::sponsor(sponsor, alice))->isFieldPresent(sfFeeAmount));
BEAST_EXPECT(!env.le(keylet::sponsorship(sponsor, alice))->isFieldPresent(sfFeeAmount));
}
}
@@ -2091,7 +2100,7 @@ public:
else
{
// cleanup previous sponsorship
if (env.le(keylet::sponsor(sponsor, sponsee)))
if (env.le(keylet::sponsorship(sponsor, sponsee)))
{
env(sponsor::del(sponsor), sponsor::SponseeAcc(sponsee));
env.close();
@@ -5468,7 +5477,7 @@ public:
Ter(tesSUCCESS));
env.close();
auto const keylet = keylet::sponsor(sponsor, alice);
auto const keylet = keylet::sponsorship(sponsor, alice);
BEAST_EXPECT(env.le(keylet));
// sponsor pays its own reserve here, so there is no SponsoredOwnerCount.
BEAST_EXPECT(ownerCount(env, sponsor) == 1);
@@ -5518,7 +5527,7 @@ public:
Ter(tesSUCCESS));
env.close();
auto const keylet = keylet::sponsor(sponsor, alice);
auto const keylet = keylet::sponsorship(sponsor, alice);
auto const obj = env.le(keylet);
BEAST_EXPECT(obj);
BEAST_EXPECT(
@@ -5885,10 +5894,10 @@ public:
BEAST_EXPECT(env.balance(alice) == XRP(1000));
BEAST_EXPECT(env.balance(sponsor) == XRP(900));
auto const sponsorshipSle = env.le(keylet::sponsor(sponsor, alice));
auto const sponsorshipSle = env.le(keylet::sponsorship(sponsor, alice));
BEAST_EXPECT(sponsorshipSle);
BEAST_EXPECT(sponsorshipSle->at(sfFeeAmount) == XRP(100 - 1));
BEAST_EXPECT(sponsorshipSle->at(sfReserveCount) == 100);
BEAST_EXPECT(sponsorshipSle->at(sfRemainingOwnerCount) == 100);
}
//
// Inner transaction
@@ -5991,10 +6000,10 @@ public:
BEAST_EXPECT(env.balance(sponsor) == XRP(900));
// reserve count is decreased
auto const sponsorshipSle = env.le(keylet::sponsor(sponsor, alice));
auto const sponsorshipSle = env.le(keylet::sponsorship(sponsor, alice));
BEAST_EXPECT(sponsorshipSle);
BEAST_EXPECT(sponsorshipSle->at(sfFeeAmount) == XRP(100));
BEAST_EXPECT(sponsorshipSle->at(sfReserveCount) == 99);
BEAST_EXPECT(sponsorshipSle->at(sfRemainingOwnerCount) == 99);
}
{

View File

@@ -29,7 +29,7 @@ set(jtx::Account const& account,
jv[jss::Account] = account.human();
jv[sfFlags.jsonName] = flags;
if (reserveCount)
jv[sfReserveCount.jsonName] = *reserveCount;
jv[sfRemainingOwnerCount.jsonName] = *reserveCount;
if (feeAmount)
jv[sfFeeAmount.jsonName] = feeAmount->getJson(JsonOptions::Values::None);
if (maxFee)
@@ -61,7 +61,7 @@ set_reserve(jtx::Account const& account, uint32_t flags, uint32_t reserveCount)
jv[jss::TransactionType] = jss::SponsorshipSet;
jv[jss::Account] = account.human();
jv[sfFlags.jsonName] = flags;
jv[sfReserveCount.jsonName] = reserveCount;
jv[sfRemainingOwnerCount.jsonName] = reserveCount;
return jv;
}

View File

@@ -950,7 +950,7 @@ public:
BEAST_EXPECT(sponsorship[sfSponsee.jsonName] == gw.human());
BEAST_EXPECT(
sponsorship[sfFlags.jsonName].asUInt() == tfSponsorshipSetRequireSignForFee);
BEAST_EXPECT(sponsorship[sfReserveCount.jsonName].asUInt() == 200);
BEAST_EXPECT(sponsorship[sfRemainingOwnerCount.jsonName].asUInt() == 200);
BEAST_EXPECT(sponsorship[sfFeeAmount.jsonName].asUInt() == 100000000);
BEAST_EXPECT(sponsorship[sfMaxFee.jsonName].asUInt() == 10);
}

View File

@@ -26,7 +26,7 @@ TEST(SponsorshipTests, BuilderSettersRoundTrip)
auto const sponseeValue = canonical_ACCOUNT();
auto const feeAmountValue = canonical_AMOUNT();
auto const maxFeeValue = canonical_AMOUNT();
auto const reserveCountValue = canonical_UINT32();
auto const remainingOwnerCountValue = canonical_UINT32();
auto const ownerNodeValue = canonical_UINT64();
auto const sponseeNodeValue = canonical_UINT64();
@@ -41,7 +41,7 @@ TEST(SponsorshipTests, BuilderSettersRoundTrip)
builder.setFeeAmount(feeAmountValue);
builder.setMaxFee(maxFeeValue);
builder.setReserveCount(reserveCountValue);
builder.setRemainingOwnerCount(remainingOwnerCountValue);
builder.setLedgerIndex(index);
builder.setFlags(0x1u);
@@ -105,11 +105,11 @@ TEST(SponsorshipTests, BuilderSettersRoundTrip)
}
{
auto const& expected = reserveCountValue;
auto const actualOpt = entry.getReserveCount();
auto const& expected = remainingOwnerCountValue;
auto const actualOpt = entry.getRemainingOwnerCount();
ASSERT_TRUE(actualOpt.has_value());
expectEqualField(expected, *actualOpt, "sfReserveCount");
EXPECT_TRUE(entry.hasReserveCount());
expectEqualField(expected, *actualOpt, "sfRemainingOwnerCount");
EXPECT_TRUE(entry.hasRemainingOwnerCount());
}
EXPECT_TRUE(entry.hasLedgerIndex());
@@ -131,7 +131,7 @@ TEST(SponsorshipTests, BuilderFromSleRoundTrip)
auto const sponseeValue = canonical_ACCOUNT();
auto const feeAmountValue = canonical_AMOUNT();
auto const maxFeeValue = canonical_AMOUNT();
auto const reserveCountValue = canonical_UINT32();
auto const remainingOwnerCountValue = canonical_UINT32();
auto const ownerNodeValue = canonical_UINT64();
auto const sponseeNodeValue = canonical_UINT64();
@@ -143,7 +143,7 @@ TEST(SponsorshipTests, BuilderFromSleRoundTrip)
sle->at(sfSponsee) = sponseeValue;
sle->at(sfFeeAmount) = feeAmountValue;
sle->at(sfMaxFee) = maxFeeValue;
sle->at(sfReserveCount) = reserveCountValue;
sle->at(sfRemainingOwnerCount) = remainingOwnerCountValue;
sle->at(sfOwnerNode) = ownerNodeValue;
sle->at(sfSponseeNode) = sponseeNodeValue;
@@ -243,16 +243,16 @@ TEST(SponsorshipTests, BuilderFromSleRoundTrip)
}
{
auto const& expected = reserveCountValue;
auto const& expected = remainingOwnerCountValue;
auto const fromSleOpt = entryFromSle.getReserveCount();
auto const fromBuilderOpt = entryFromBuilder.getReserveCount();
auto const fromSleOpt = entryFromSle.getRemainingOwnerCount();
auto const fromBuilderOpt = entryFromBuilder.getRemainingOwnerCount();
ASSERT_TRUE(fromSleOpt.has_value());
ASSERT_TRUE(fromBuilderOpt.has_value());
expectEqualField(expected, *fromSleOpt, "sfReserveCount");
expectEqualField(expected, *fromBuilderOpt, "sfReserveCount");
expectEqualField(expected, *fromSleOpt, "sfRemainingOwnerCount");
expectEqualField(expected, *fromBuilderOpt, "sfRemainingOwnerCount");
}
EXPECT_EQ(entryFromSle.getKey(), index);
@@ -323,7 +323,7 @@ TEST(SponsorshipTests, OptionalFieldsReturnNullopt)
EXPECT_FALSE(entry.getFeeAmount().has_value());
EXPECT_FALSE(entry.hasMaxFee());
EXPECT_FALSE(entry.getMaxFee().has_value());
EXPECT_FALSE(entry.hasReserveCount());
EXPECT_FALSE(entry.getReserveCount().has_value());
EXPECT_FALSE(entry.hasRemainingOwnerCount());
EXPECT_FALSE(entry.getRemainingOwnerCount().has_value());
}
}

View File

@@ -33,7 +33,7 @@ TEST(TransactionsSponsorshipSetTests, BuilderSettersRoundTrip)
auto const sponseeValue = canonical_ACCOUNT();
auto const feeAmountValue = canonical_AMOUNT();
auto const maxFeeValue = canonical_AMOUNT();
auto const reserveCountValue = canonical_UINT32();
auto const remainingOwnerCountValue = canonical_UINT32();
SponsorshipSetBuilder builder{
accountValue,
@@ -46,7 +46,7 @@ TEST(TransactionsSponsorshipSetTests, BuilderSettersRoundTrip)
builder.setSponsee(sponseeValue);
builder.setFeeAmount(feeAmountValue);
builder.setMaxFee(maxFeeValue);
builder.setReserveCount(reserveCountValue);
builder.setRemainingOwnerCount(remainingOwnerCountValue);
auto tx = builder.build(publicKey, secretKey);
@@ -97,11 +97,11 @@ TEST(TransactionsSponsorshipSetTests, BuilderSettersRoundTrip)
}
{
auto const& expected = reserveCountValue;
auto const actualOpt = tx.getReserveCount();
ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfReserveCount should be present";
expectEqualField(expected, *actualOpt, "sfReserveCount");
EXPECT_TRUE(tx.hasReserveCount());
auto const& expected = remainingOwnerCountValue;
auto const actualOpt = tx.getRemainingOwnerCount();
ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfRemainingOwnerCount should be present";
expectEqualField(expected, *actualOpt, "sfRemainingOwnerCount");
EXPECT_TRUE(tx.hasRemainingOwnerCount());
}
}
@@ -124,7 +124,7 @@ TEST(TransactionsSponsorshipSetTests, BuilderFromStTxRoundTrip)
auto const sponseeValue = canonical_ACCOUNT();
auto const feeAmountValue = canonical_AMOUNT();
auto const maxFeeValue = canonical_AMOUNT();
auto const reserveCountValue = canonical_UINT32();
auto const remainingOwnerCountValue = canonical_UINT32();
// Build an initial transaction
SponsorshipSetBuilder initialBuilder{
@@ -137,7 +137,7 @@ TEST(TransactionsSponsorshipSetTests, BuilderFromStTxRoundTrip)
initialBuilder.setSponsee(sponseeValue);
initialBuilder.setFeeAmount(feeAmountValue);
initialBuilder.setMaxFee(maxFeeValue);
initialBuilder.setReserveCount(reserveCountValue);
initialBuilder.setRemainingOwnerCount(remainingOwnerCountValue);
auto initialTx = initialBuilder.build(publicKey, secretKey);
@@ -185,10 +185,10 @@ TEST(TransactionsSponsorshipSetTests, BuilderFromStTxRoundTrip)
}
{
auto const& expected = reserveCountValue;
auto const actualOpt = rebuiltTx.getReserveCount();
ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfReserveCount should be present";
expectEqualField(expected, *actualOpt, "sfReserveCount");
auto const& expected = remainingOwnerCountValue;
auto const actualOpt = rebuiltTx.getRemainingOwnerCount();
ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfRemainingOwnerCount should be present";
expectEqualField(expected, *actualOpt, "sfRemainingOwnerCount");
}
}
@@ -254,8 +254,8 @@ TEST(TransactionsSponsorshipSetTests, OptionalFieldsReturnNullopt)
EXPECT_FALSE(tx.getFeeAmount().has_value());
EXPECT_FALSE(tx.hasMaxFee());
EXPECT_FALSE(tx.getMaxFee().has_value());
EXPECT_FALSE(tx.hasReserveCount());
EXPECT_FALSE(tx.getReserveCount().has_value());
EXPECT_FALSE(tx.hasRemainingOwnerCount());
EXPECT_FALSE(tx.getRemainingOwnerCount().has_value());
}
}

View File

@@ -785,7 +785,7 @@ parseSponsorship(
if (!sponseeAccountID)
return std::unexpected(sponseeAccountID.error());
return keylet::sponsor(*sponsorAccountID, *sponseeAccountID).key;
return keylet::sponsorship(*sponsorAccountID, *sponseeAccountID).key;
}
static std::expected<uint256, json::Value>