mirror of
https://github.com/XRPLF/rippled.git
synced 2026-04-29 15:37:57 +00:00
Sponsored Fees and Reserves for Attackathon (#6842)
Co-authored-by: Mayukha Vadari <mvadari@gmail.com> Co-authored-by: tequ <git@tequ.dev> Co-authored-by: Ed Hennis <ed@ripple.com> Co-authored-by: Shawn Xie <35279399+shawnxie999@users.noreply.github.com>
This commit is contained in:
@@ -125,6 +125,22 @@ areCompatible(
|
||||
beast::Journal::Stream& s,
|
||||
char const* reason);
|
||||
|
||||
uint32_t
|
||||
ownerCount(SLE::const_ref sponsorSle);
|
||||
|
||||
XRPAmount
|
||||
calculateReserve(SLE::const_ref sle, Fees const& fees);
|
||||
|
||||
TER
|
||||
checkInsufficientReserve(
|
||||
ReadView const& view,
|
||||
STTx const& tx,
|
||||
std::shared_ptr<SLE const> accSle,
|
||||
STAmount const& accBalance,
|
||||
std::shared_ptr<SLE const> const& sponsorSle,
|
||||
std::int32_t ownerCountDelta,
|
||||
std::int32_t accountCountDelta = 0);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Modifiers
|
||||
|
||||
@@ -38,10 +38,27 @@ xrpLiquid(ReadView const& view, AccountID const& id, std::int32_t ownerCountAdj,
|
||||
void
|
||||
adjustOwnerCount(
|
||||
ApplyView& view,
|
||||
std::shared_ptr<SLE> const& sle,
|
||||
std::shared_ptr<SLE> const& accountSle,
|
||||
std::shared_ptr<SLE> const& sponsorSle,
|
||||
std::int32_t amount,
|
||||
beast::Journal j);
|
||||
|
||||
inline void
|
||||
adjustOwnerCount(
|
||||
ApplyView& view,
|
||||
AccountID const& account,
|
||||
std::optional<AccountID> const& sponsor,
|
||||
std::int32_t amount,
|
||||
beast::Journal j)
|
||||
{
|
||||
return adjustOwnerCount(
|
||||
view,
|
||||
view.peek(keylet::account(account)),
|
||||
sponsor ? view.peek(keylet::account(*sponsor)) : std::shared_ptr<SLE>(),
|
||||
amount,
|
||||
j);
|
||||
}
|
||||
|
||||
/** Returns IOU issuer transfer fee as Rate. Rate specifies
|
||||
* the fee as fractions of 1 billion. For example, 1% transfer rate
|
||||
* is represented as 1,010,000,000.
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
|
||||
#include <xrpl/ledger/helpers/RippleStateHelpers.h>
|
||||
#include <xrpl/ledger/helpers/SponsorHelpers.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/MPTAmount.h>
|
||||
@@ -17,6 +18,7 @@ template <ValidIssueType T>
|
||||
TER
|
||||
escrowUnlockApplyHelper(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
Rate lockedRate,
|
||||
std::shared_ptr<SLE> const& sleDest,
|
||||
STAmount const& xrpBalance,
|
||||
@@ -31,6 +33,7 @@ template <>
|
||||
inline TER
|
||||
escrowUnlockApplyHelper<Issue>(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
Rate lockedRate,
|
||||
std::shared_ptr<SLE> const& sleDest,
|
||||
STAmount const& xrpBalance,
|
||||
@@ -56,8 +59,12 @@ escrowUnlockApplyHelper<Issue>(
|
||||
if (!view.exists(trustLineKey) && createAsset)
|
||||
{
|
||||
// Can the account cover the trust line's reserve?
|
||||
if (std::uint32_t const ownerCount = {sleDest->at(sfOwnerCount)};
|
||||
xrpBalance < view.fees().accountReserve(ownerCount + 1))
|
||||
auto const sponsorAccountID = getTxReserveSponsorAccountID(tx);
|
||||
std::shared_ptr<SLE> sponsorSle = {};
|
||||
if (sponsorAccountID)
|
||||
sponsorSle = view.peek(keylet::account(*sponsorAccountID));
|
||||
if (auto const ret = checkInsufficientReserve(view, tx, sleDest, xrpBalance, sponsorSle, 1);
|
||||
!isTesSuccess(ret))
|
||||
{
|
||||
JLOG(journal.trace()) << "Trust line does not exist. "
|
||||
"Insufficient reserve to create line.";
|
||||
@@ -84,6 +91,7 @@ escrowUnlockApplyHelper<Issue>(
|
||||
Issue(currency, receiver), // limit of zero
|
||||
0, // quality in
|
||||
0, // quality out
|
||||
sponsorAccountID, // sponsor
|
||||
journal); // journal
|
||||
!isTesSuccess(ter))
|
||||
{
|
||||
@@ -161,6 +169,7 @@ template <>
|
||||
inline TER
|
||||
escrowUnlockApplyHelper<MPTIssue>(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
Rate lockedRate,
|
||||
std::shared_ptr<SLE> const& sleDest,
|
||||
STAmount const& xrpBalance,
|
||||
@@ -176,24 +185,30 @@ escrowUnlockApplyHelper<MPTIssue>(
|
||||
|
||||
auto const mptID = amount.get<MPTIssue>().getMptID();
|
||||
auto const issuanceKey = keylet::mptIssuance(mptID);
|
||||
if (!view.exists(keylet::mptoken(issuanceKey.key, receiver)) && createAsset && !receiverIssuer)
|
||||
auto const mptKeylet = keylet::mptoken(issuanceKey.key, receiver);
|
||||
if (!view.exists(mptKeylet) && createAsset && !receiverIssuer)
|
||||
{
|
||||
if (std::uint32_t const ownerCount = {sleDest->at(sfOwnerCount)};
|
||||
xrpBalance < view.fees().accountReserve(ownerCount + 1))
|
||||
{
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
}
|
||||
auto const sponsorAccountID = getTxReserveSponsorAccountID(tx);
|
||||
std::shared_ptr<SLE> sponsorSle = {};
|
||||
if (sponsorAccountID)
|
||||
sponsorSle = view.peek(keylet::account(*sponsorAccountID));
|
||||
if (auto const ret = checkInsufficientReserve(view, tx, sleDest, xrpBalance, sponsorSle, 1);
|
||||
!isTesSuccess(ret))
|
||||
return ret;
|
||||
|
||||
if (auto const ter = createMPToken(view, mptID, receiver, 0); !isTesSuccess(ter))
|
||||
if (auto const ter = createMPToken(view, mptID, receiver, sponsorAccountID, 0);
|
||||
!isTesSuccess(ter))
|
||||
{
|
||||
return ter; // LCOV_EXCL_LINE
|
||||
}
|
||||
|
||||
// update owner count.
|
||||
adjustOwnerCount(view, sleDest, 1, journal);
|
||||
adjustOwnerCount(view, sleDest, sponsorSle, 1, journal);
|
||||
auto mptSle = view.peek(mptKeylet);
|
||||
addSponsorToLedgerEntry(mptSle, sponsorSle);
|
||||
}
|
||||
|
||||
if (!view.exists(keylet::mptoken(issuanceKey.key, receiver)) && !receiverIssuer)
|
||||
if (!view.exists(mptKeylet) && !receiverIssuer)
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
auto const xferRate = transferRate(view, amount);
|
||||
|
||||
@@ -68,6 +68,7 @@ canAddHolding(ReadView const& view, MPTIssue const& mptIssue);
|
||||
[[nodiscard]] TER
|
||||
authorizeMPToken(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
XRPAmount const& priorBalance,
|
||||
MPTID const& mptIssuanceID,
|
||||
AccountID const& account,
|
||||
@@ -99,6 +100,7 @@ requireAuth(
|
||||
[[nodiscard]] TER
|
||||
enforceMPTokenAuthorization(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
MPTID const& mptIssuanceID,
|
||||
AccountID const& account,
|
||||
XRPAmount const& priorBalance,
|
||||
@@ -139,6 +141,7 @@ canMPTTradeAndTransfer(
|
||||
[[nodiscard]] TER
|
||||
addEmptyHolding(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
AccountID const& accountID,
|
||||
XRPAmount priorBalance,
|
||||
MPTIssue const& mptIssue,
|
||||
@@ -147,6 +150,7 @@ addEmptyHolding(
|
||||
[[nodiscard]] TER
|
||||
removeEmptyHolding(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
AccountID const& accountID,
|
||||
MPTIssue const& mptIssue,
|
||||
beast::Journal journal);
|
||||
@@ -178,6 +182,7 @@ createMPToken(
|
||||
ApplyView& view,
|
||||
MPTID const& mptIssuanceID,
|
||||
AccountID const& account,
|
||||
std::optional<AccountID> const& sponsor,
|
||||
std::uint32_t const flags);
|
||||
|
||||
TER
|
||||
@@ -185,6 +190,7 @@ checkCreateMPT(
|
||||
xrpl::ApplyView& view,
|
||||
xrpl::MPTIssue const& mptIssue,
|
||||
xrpl::AccountID const& holder,
|
||||
std::optional<xrpl::AccountID> const& sponsor,
|
||||
beast::Journal j);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -44,7 +44,12 @@ findTokenAndPage(ApplyView& view, AccountID const& owner, uint256 const& nftoken
|
||||
|
||||
/** Insert the token in the owner's token directory. */
|
||||
TER
|
||||
insertToken(ApplyView& view, AccountID owner, STObject&& nft);
|
||||
insertToken(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
AccountID owner,
|
||||
std::optional<AccountID> const& sponsor,
|
||||
STObject&& nft);
|
||||
|
||||
/** Remove the token from the owner's token directory. */
|
||||
TER
|
||||
@@ -116,6 +121,7 @@ tokenOfferCreatePreclaim(
|
||||
TER
|
||||
tokenOfferCreateApply(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
AccountID const& acctID,
|
||||
STAmount const& amount,
|
||||
std::optional<AccountID> const& dest,
|
||||
|
||||
@@ -149,6 +149,7 @@ trustCreate(
|
||||
// Issuer should be the account being set.
|
||||
std::uint32_t uQualityIn,
|
||||
std::uint32_t uQualityOut,
|
||||
std::optional<AccountID> const& sponsorAccountID,
|
||||
beast::Journal j);
|
||||
|
||||
[[nodiscard]] TER
|
||||
@@ -229,6 +230,7 @@ canTransfer(ReadView const& view, Issue const& issue, AccountID const& from, Acc
|
||||
[[nodiscard]] TER
|
||||
addEmptyHolding(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
AccountID const& accountID,
|
||||
XRPAmount priorBalance,
|
||||
Issue const& issue,
|
||||
|
||||
114
include/xrpl/ledger/helpers/SponsorHelpers.h
Normal file
114
include/xrpl/ledger/helpers/SponsorHelpers.h
Normal file
@@ -0,0 +1,114 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TxFlags.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
inline bool
|
||||
isReserveSponsored(STTx const& tx)
|
||||
{
|
||||
return tx.getFieldU32(sfSponsorFlags) & spfSponsorReserve;
|
||||
}
|
||||
|
||||
inline bool
|
||||
isSponsorReserveCoSigning(STTx const& tx)
|
||||
{
|
||||
if (!tx.isFieldPresent(sfSponsorSignature))
|
||||
return false;
|
||||
return isReserveSponsored(tx);
|
||||
}
|
||||
|
||||
inline std::optional<AccountID>
|
||||
getTxReserveSponsorAccountID(STTx const& tx)
|
||||
{
|
||||
if (tx.isFieldPresent(sfSponsor) && isReserveSponsored(tx))
|
||||
{
|
||||
return tx.getAccountID(sfSponsor);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
inline std::shared_ptr<SLE>
|
||||
getTxReserveSponsor(ApplyView& view, STTx const& tx)
|
||||
{
|
||||
auto const sponsorID = getTxReserveSponsorAccountID(tx);
|
||||
if (sponsorID)
|
||||
return view.peek(keylet::account(*sponsorID));
|
||||
return {};
|
||||
}
|
||||
|
||||
inline std::shared_ptr<SLE const>
|
||||
getTxReserveSponsor(ReadView const& view, STTx const& tx)
|
||||
{
|
||||
auto const sponsorID = getTxReserveSponsorAccountID(tx);
|
||||
if (sponsorID)
|
||||
return view.read(keylet::account(*sponsorID));
|
||||
return {};
|
||||
}
|
||||
|
||||
inline std::optional<AccountID>
|
||||
getLedgerEntryReserveSponsorAccountID(
|
||||
std::shared_ptr<SLE const> const& sle,
|
||||
SF_ACCOUNT const& field = sfSponsor)
|
||||
{
|
||||
if (sle->isFieldPresent(field))
|
||||
return sle->getAccountID(field);
|
||||
return {};
|
||||
}
|
||||
|
||||
inline std::shared_ptr<SLE>
|
||||
getLedgerEntryReserveSponsor(
|
||||
ApplyView& view,
|
||||
std::shared_ptr<SLE> const& sle,
|
||||
SF_ACCOUNT const& field = sfSponsor)
|
||||
{
|
||||
auto const sponsorID = getLedgerEntryReserveSponsorAccountID(sle, field);
|
||||
if (sponsorID)
|
||||
return view.peek(keylet::account(*sponsorID));
|
||||
return {};
|
||||
}
|
||||
|
||||
inline std::shared_ptr<SLE const>
|
||||
getLedgerEntryReserveSponsor(
|
||||
ReadView const& view,
|
||||
std::shared_ptr<SLE const> const& sle,
|
||||
SF_ACCOUNT const& field = sfSponsor)
|
||||
{
|
||||
auto const sponsorID = getLedgerEntryReserveSponsorAccountID(sle, field);
|
||||
if (sponsorID)
|
||||
return view.read(keylet::account(*sponsorID));
|
||||
return {};
|
||||
}
|
||||
|
||||
inline void
|
||||
addSponsorToLedgerEntry(
|
||||
std::shared_ptr<SLE> const& sle,
|
||||
std::shared_ptr<SLE> const& sponsorSle,
|
||||
SF_ACCOUNT const& field = sfSponsor)
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
(sle->getType() == ltRIPPLE_STATE && (field == sfHighSponsor || field == sfLowSponsor)) ||
|
||||
(sle->getType() != ltRIPPLE_STATE && field == sfSponsor),
|
||||
"addSponsorToLedgerEntry : Invalid field to the LedgerEntry");
|
||||
if (sponsorSle)
|
||||
sle->setAccountID(field, sponsorSle->getAccountID(sfAccount));
|
||||
}
|
||||
|
||||
inline void
|
||||
removeSponsorFromLedgerEntry(std::shared_ptr<SLE> const& sle, SF_ACCOUNT const& field = sfSponsor)
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
(sle->getType() == ltRIPPLE_STATE && (field == sfHighSponsor || field == sfLowSponsor)) ||
|
||||
(sle->getType() != ltRIPPLE_STATE && field == sfSponsor),
|
||||
"removeSponsorFromLedgerEntry : Invalid field to the LedgerEntry");
|
||||
if (sle->isFieldPresent(field))
|
||||
sle->makeFieldAbsent(field);
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -214,6 +214,7 @@ canAddHolding(ReadView const& view, Asset const& asset);
|
||||
[[nodiscard]] TER
|
||||
addEmptyHolding(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
AccountID const& accountID,
|
||||
XRPAmount priorBalance,
|
||||
Asset const& asset,
|
||||
@@ -222,6 +223,7 @@ addEmptyHolding(
|
||||
[[nodiscard]] TER
|
||||
removeEmptyHolding(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
AccountID const& accountID,
|
||||
Asset const& asset,
|
||||
beast::Journal journal);
|
||||
@@ -276,6 +278,7 @@ accountSend(
|
||||
AccountID const& to,
|
||||
STAmount const& saAmount,
|
||||
beast::Journal j,
|
||||
std::optional<AccountID> const& sponsorAccountID = std::nullopt,
|
||||
WaiveTransferFee waiveFee = WaiveTransferFee::No,
|
||||
AllowMPTOverflow allowOverflow = AllowMPTOverflow::No);
|
||||
|
||||
@@ -293,6 +296,7 @@ accountSendMulti(
|
||||
Asset const& asset,
|
||||
MultiplePaymentDestinations const& receivers,
|
||||
beast::Journal j,
|
||||
std::optional<AccountID> const& sponsorAccountID,
|
||||
WaiveTransferFee waiveFee = WaiveTransferFee::No);
|
||||
|
||||
[[nodiscard]] TER
|
||||
|
||||
@@ -40,9 +40,23 @@ struct Fees
|
||||
the reserve increment times the number of increments.
|
||||
*/
|
||||
XRPAmount
|
||||
accountReserve(std::size_t ownerCount) const
|
||||
accountReserve(
|
||||
std::size_t ownerCount,
|
||||
std::size_t sponsoredOwnerCount = 0,
|
||||
std::size_t sponsoringOwnerCount = 0,
|
||||
bool isAccountSponsored = false,
|
||||
std::size_t sponsoringAccountCount = 0) const
|
||||
{
|
||||
return reserve + ownerCount * increment;
|
||||
auto const accountReserveUnits = (isAccountSponsored ? 0 : 1) + sponsoringAccountCount;
|
||||
|
||||
XRPL_ASSERT(
|
||||
ownerCount >= sponsoredOwnerCount,
|
||||
"xrpl::Fees::accountReserve : OwnerCount must be greater than or equal to "
|
||||
"SponsoredOwnerCount");
|
||||
|
||||
auto const ownerReserveUnits = (ownerCount - sponsoredOwnerCount) + sponsoringOwnerCount;
|
||||
|
||||
return (reserve * accountReserveUnits) + (increment * ownerReserveUnits);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -151,6 +151,10 @@ static ticket_t const ticket{};
|
||||
Keylet
|
||||
signers(AccountID const& account) noexcept;
|
||||
|
||||
/** A Sponsor */
|
||||
Keylet
|
||||
sponsor(AccountID const& sponsor, AccountID const& sponsee) noexcept;
|
||||
|
||||
/** A Check */
|
||||
/** @{ */
|
||||
Keylet
|
||||
|
||||
@@ -135,7 +135,7 @@ enum LedgerEntryType : std::uint16_t {
|
||||
LSF_FLAG(lsfDisallowIncomingPayChan, 0x10000000) /* True, reject new paychans */ \
|
||||
LSF_FLAG(lsfDisallowIncomingTrustline, 0x20000000) /* True, reject new trustlines (only if no issued assets) */ \
|
||||
LSF_FLAG(lsfAllowTrustLineLocking, 0x40000000) /* True, enable trustline locking */ \
|
||||
LSF_FLAG(lsfAllowTrustLineClawback, 0x80000000)) /* True, enable clawback */ \
|
||||
LSF_FLAG(lsfAllowTrustLineClawback, 0x80000000)) /* True, enable clawback */ \
|
||||
\
|
||||
LEDGER_OBJECT(Offer, \
|
||||
LSF_FLAG(lsfPassive, 0x00010000) \
|
||||
@@ -201,7 +201,11 @@ enum LedgerEntryType : std::uint16_t {
|
||||
LEDGER_OBJECT(Loan, \
|
||||
LSF_FLAG(lsfLoanDefault, 0x00010000) \
|
||||
LSF_FLAG(lsfLoanImpaired, 0x00020000) \
|
||||
LSF_FLAG(lsfLoanOverpayment, 0x00040000)) /* True, loan allows overpayments */
|
||||
LSF_FLAG(lsfLoanOverpayment, 0x00040000)) /* True, loan allows overpayments */ \
|
||||
\
|
||||
LEDGER_OBJECT(Sponsorship, \
|
||||
LSF_FLAG(lsfSponsorshipRequireSignForFee, 0x00010000) \
|
||||
LSF_FLAG(lsfSponsorshipRequireSignForReserve, 0x00020000))
|
||||
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -211,6 +211,7 @@ enum TERcodes : TERUnderlyingType {
|
||||
// create a pseudo-account
|
||||
terNO_DELEGATE_PERMISSION, // Delegate does not have permission
|
||||
terLOCKED, // MPT is locked
|
||||
terNO_SPONSORSHIP, // No sponsorship found
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -350,6 +351,7 @@ enum TECcodes : TERUnderlyingType {
|
||||
// reclaimed after those networks reset.
|
||||
tecNO_DELEGATE_PERMISSION = 198,
|
||||
tecBAD_PROOF = 199,
|
||||
tecNO_SPONSOR_PERMISSION = 200,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -100,7 +100,8 @@ inline constexpr FlagValue tfUniversalMask = ~tfUniversal;
|
||||
TRANSACTION(Payment, \
|
||||
TF_FLAG(tfNoRippleDirect, 0x00010000) \
|
||||
TF_FLAG(tfPartialPayment, 0x00020000) \
|
||||
TF_FLAG(tfLimitQuality, 0x00040000), \
|
||||
TF_FLAG(tfLimitQuality, 0x00040000) \
|
||||
TF_FLAG(tfSponsorCreatedAccount, 0x00080000), \
|
||||
MASK_ADJ(0)) \
|
||||
\
|
||||
TRANSACTION(TrustSet, \
|
||||
@@ -213,6 +214,20 @@ inline constexpr FlagValue tfUniversalMask = ~tfUniversal;
|
||||
TF_FLAG(tfLoanDefault, 0x00010000) \
|
||||
TF_FLAG(tfLoanImpair, 0x00020000) \
|
||||
TF_FLAG(tfLoanUnimpair, 0x00040000), \
|
||||
MASK_ADJ(0)) \
|
||||
\
|
||||
TRANSACTION(SponsorshipSet, \
|
||||
TF_FLAG(tfSponsorshipSetRequireSignForFee, 0x00010000) \
|
||||
TF_FLAG(tfSponsorshipClearRequireSignForFee, 0x00020000) \
|
||||
TF_FLAG(tfSponsorshipSetRequireSignForReserve, 0x00040000) \
|
||||
TF_FLAG(tfSponsorshipClearRequireSignForReserve, 0x00080000) \
|
||||
TF_FLAG(tfDeleteObject, 0x00100000), \
|
||||
MASK_ADJ(0)) \
|
||||
\
|
||||
TRANSACTION(SponsorshipTransfer, \
|
||||
TF_FLAG(tfSponsorshipEnd, 0x00000001) \
|
||||
TF_FLAG(tfSponsorshipCreate, 0x00000002) \
|
||||
TF_FLAG(tfSponsorshipReassign, 0x00000004), \
|
||||
MASK_ADJ(0))
|
||||
|
||||
// clang-format on
|
||||
@@ -337,6 +352,9 @@ getAllTxFlags()
|
||||
inline constexpr FlagValue tfMPTPaymentMask = ~(tfUniversal | tfPartialPayment);
|
||||
inline constexpr FlagValue tfTrustSetPermissionMask =
|
||||
~(tfUniversal | tfSetfAuth | tfSetFreeze | tfClearFreeze);
|
||||
inline constexpr FlagValue tfSponsorshipSetPermissionMask =
|
||||
~(tfUniversal | tfSponsorshipSetRequireSignForFee | tfSponsorshipSetRequireSignForReserve |
|
||||
tfSponsorshipClearRequireSignForFee | tfSponsorshipClearRequireSignForReserve);
|
||||
|
||||
// MPTokenIssuanceCreate MutableFlags:
|
||||
// Indicating specific fields or flags may be changed after issuance.
|
||||
@@ -449,4 +467,33 @@ getAsfFlagMap()
|
||||
#pragma pop_macro("ACCOUNTSET_FLAG_TO_MAP")
|
||||
#pragma pop_macro("ACCOUNTSET_FLAGS")
|
||||
|
||||
#pragma push_macro("SPONSOR_FLAGS")
|
||||
#pragma push_macro("SPONSOR_FLAG_TO_VALUE")
|
||||
#pragma push_macro("SPONSOR_FLAG_TO_MAP")
|
||||
|
||||
// Sponsor Flag values
|
||||
#define SPONSOR_FLAGS(SPF_FLAG) \
|
||||
SPF_FLAG(spfSponsorFee, 1) \
|
||||
SPF_FLAG(spfSponsorReserve, 2)
|
||||
|
||||
#define SPONSOR_FLAG_TO_VALUE(name, value) inline constexpr FlagValue name = value;
|
||||
#define SPONSOR_FLAG_TO_MAP(name, value) {#name, value},
|
||||
|
||||
SPONSOR_FLAGS(SPONSOR_FLAG_TO_VALUE)
|
||||
|
||||
inline std::map<std::string, FlagValue> const&
|
||||
getspfFlagMap()
|
||||
{
|
||||
static std::map<std::string, FlagValue> const flags = {SPONSOR_FLAGS(SPONSOR_FLAG_TO_MAP)};
|
||||
return flags;
|
||||
}
|
||||
|
||||
#undef SPONSOR_FLAG_TO_VALUE
|
||||
#undef SPONSOR_FLAG_TO_MAP
|
||||
#undef SPONSOR_FLAGS
|
||||
|
||||
#pragma pop_macro("SPONSOR_FLAG_TO_VALUE")
|
||||
#pragma pop_macro("SPONSOR_FLAG_TO_MAP")
|
||||
#pragma pop_macro("SPONSOR_FLAGS")
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
// Add new amendments to the top of this list.
|
||||
// Keep it sorted in reverse chronological order.
|
||||
|
||||
XRPL_FEATURE(Sponsor, Supported::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(BatchV1_1, Supported::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(ConfidentialTransfer, Supported::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(MPTokensV2, Supported::no, VoteBehavior::DefaultNo)
|
||||
|
||||
@@ -150,6 +150,9 @@ LEDGER_ENTRY(ltACCOUNT_ROOT, 0x0061, AccountRoot, account, ({
|
||||
{sfAMMID, soeOPTIONAL}, // pseudo-account designator
|
||||
{sfVaultID, soeOPTIONAL}, // pseudo-account designator
|
||||
{sfLoanBrokerID, soeOPTIONAL}, // pseudo-account designator
|
||||
{sfSponsoredOwnerCount, soeDEFAULT},
|
||||
{sfSponsoringOwnerCount, soeDEFAULT},
|
||||
{sfSponsoringAccountCount,soeDEFAULT},
|
||||
}))
|
||||
|
||||
/** A ledger object which contains a list of object identifiers.
|
||||
@@ -286,6 +289,8 @@ LEDGER_ENTRY(ltRIPPLE_STATE, 0x0072, RippleState, state, ({
|
||||
{sfHighNode, soeOPTIONAL},
|
||||
{sfHighQualityIn, soeOPTIONAL},
|
||||
{sfHighQualityOut, soeOPTIONAL},
|
||||
{sfHighSponsor, soeOPTIONAL},
|
||||
{sfLowSponsor, soeOPTIONAL},
|
||||
}))
|
||||
|
||||
/** The ledger object which lists the network's fee settings.
|
||||
@@ -615,5 +620,20 @@ LEDGER_ENTRY(ltLOAN, 0x0089, Loan, loan, ({
|
||||
{sfLoanScale, soeDEFAULT},
|
||||
}))
|
||||
|
||||
/** A ledger object representing a sponsorship.
|
||||
\sa keylet::sponsor
|
||||
*/
|
||||
LEDGER_ENTRY(ltSPONSORSHIP, 0x0090, Sponsorship, sponsorship, ({
|
||||
{sfPreviousTxnID, soeREQUIRED},
|
||||
{sfPreviousTxnLgrSeq, soeREQUIRED},
|
||||
{sfOwner, soeREQUIRED},
|
||||
{sfSponsee, soeREQUIRED},
|
||||
{sfFeeAmount, soeOPTIONAL},
|
||||
{sfMaxFee, soeOPTIONAL},
|
||||
{sfReserveCount, soeDEFAULT},
|
||||
{sfOwnerNode, soeREQUIRED},
|
||||
{sfSponseeNode, soeREQUIRED},
|
||||
}))
|
||||
|
||||
#undef EXPAND
|
||||
#undef LEDGER_ENTRY_DUPLICATE
|
||||
|
||||
@@ -78,3 +78,18 @@ GRANULAR_PERMISSION(MPTokenIssuanceLock, ttMPTOKEN_ISSUANCE_SET, 65547, tfUniver
|
||||
GRANULAR_PERMISSION(MPTokenIssuanceUnlock, ttMPTOKEN_ISSUANCE_SET, 65548, tfUniversal | tfMPTUnlock,
|
||||
({{sfMPTokenIssuanceID, soeREQUIRED},
|
||||
{sfHolder, soeOPTIONAL}}))
|
||||
|
||||
/** Grants the ability to set SponsorFee. */
|
||||
GRANULAR_PERMISSION(SponsorFee, ttSPONSORSHIP_SET, 65549,
|
||||
tfUniversal | tfSponsorshipSetRequireSignForFee | tfSponsorshipClearRequireSignForFee,
|
||||
({{sfFeeAmount, soeOPTIONAL},
|
||||
{sfMaxFee, soeOPTIONAL},
|
||||
{sfSponsee, soeOPTIONAL},
|
||||
{sfCounterpartySponsor, soeOPTIONAL}}))
|
||||
|
||||
/** Grants the ability to set SponsorReserve. */
|
||||
GRANULAR_PERMISSION(SponsorReserve, ttSPONSORSHIP_SET, 65550,
|
||||
tfUniversal | tfSponsorshipSetRequireSignForReserve | tfSponsorshipClearRequireSignForReserve,
|
||||
({{sfReserveCount, soeOPTIONAL},
|
||||
{sfSponsee, soeOPTIONAL},
|
||||
{sfCounterpartySponsor, soeOPTIONAL}}))
|
||||
|
||||
@@ -114,6 +114,11 @@ TYPED_SFIELD(sfLateInterestRate, UINT32, 66) // 1/10 basis points (bi
|
||||
TYPED_SFIELD(sfCloseInterestRate, UINT32, 67) // 1/10 basis points (bips)
|
||||
TYPED_SFIELD(sfOverpaymentInterestRate, UINT32, 68) // 1/10 basis points (bips)
|
||||
TYPED_SFIELD(sfConfidentialBalanceVersion, UINT32, 69)
|
||||
TYPED_SFIELD(sfSponsoredOwnerCount, UINT32, 70)
|
||||
TYPED_SFIELD(sfSponsoringOwnerCount, UINT32, 71)
|
||||
TYPED_SFIELD(sfSponsoringAccountCount, UINT32, 72)
|
||||
TYPED_SFIELD(sfReserveCount, UINT32, 73)
|
||||
TYPED_SFIELD(sfSponsorFlags, UINT32, 74)
|
||||
|
||||
// 64-bit integers (common)
|
||||
TYPED_SFIELD(sfIndexNext, UINT64, 1)
|
||||
@@ -148,6 +153,7 @@ TYPED_SFIELD(sfLockedAmount, UINT64, 29, SField::sMD_BaseTen|SFie
|
||||
TYPED_SFIELD(sfVaultNode, UINT64, 30)
|
||||
TYPED_SFIELD(sfLoanBrokerNode, UINT64, 31)
|
||||
TYPED_SFIELD(sfConfidentialOutstandingAmount, UINT64, 32, SField::sMD_BaseTen|SField::sMD_Default)
|
||||
TYPED_SFIELD(sfSponseeNode, UINT64, 33)
|
||||
|
||||
// 128-bit
|
||||
TYPED_SFIELD(sfEmailHash, UINT128, 1)
|
||||
@@ -208,6 +214,7 @@ TYPED_SFIELD(sfLoanBrokerID, UINT256, 37,
|
||||
SField::sMD_PseudoAccount | SField::sMD_Default)
|
||||
TYPED_SFIELD(sfLoanID, UINT256, 38)
|
||||
TYPED_SFIELD(sfBlindingFactor, UINT256, 39)
|
||||
TYPED_SFIELD(sfObjectID, UINT256, 40)
|
||||
|
||||
// number (common)
|
||||
TYPED_SFIELD(sfNumber, NUMBER, 1)
|
||||
@@ -267,6 +274,8 @@ TYPED_SFIELD(sfPrice, AMOUNT, 28)
|
||||
TYPED_SFIELD(sfSignatureReward, AMOUNT, 29)
|
||||
TYPED_SFIELD(sfMinAccountCreateAmount, AMOUNT, 30)
|
||||
TYPED_SFIELD(sfLPTokenBalance, AMOUNT, 31)
|
||||
TYPED_SFIELD(sfFeeAmount, AMOUNT, 32)
|
||||
TYPED_SFIELD(sfMaxFee, AMOUNT, 33)
|
||||
|
||||
// variable length (common)
|
||||
TYPED_SFIELD(sfPublicKey, VL, 1)
|
||||
@@ -342,6 +351,11 @@ TYPED_SFIELD(sfIssuingChainDoor, ACCOUNT, 23)
|
||||
TYPED_SFIELD(sfSubject, ACCOUNT, 24)
|
||||
TYPED_SFIELD(sfBorrower, ACCOUNT, 25)
|
||||
TYPED_SFIELD(sfCounterparty, ACCOUNT, 26)
|
||||
TYPED_SFIELD(sfSponsor, ACCOUNT, 27)
|
||||
TYPED_SFIELD(sfHighSponsor, ACCOUNT, 28)
|
||||
TYPED_SFIELD(sfLowSponsor, ACCOUNT, 29)
|
||||
TYPED_SFIELD(sfCounterpartySponsor, ACCOUNT, 30)
|
||||
TYPED_SFIELD(sfSponsee, ACCOUNT, 31)
|
||||
|
||||
// vector of 256-bit
|
||||
TYPED_SFIELD(sfIndexes, VECTOR256, 1, SField::sMD_Never)
|
||||
@@ -406,6 +420,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(sfSponsorSignature, OBJECT, 38, SField::sMD_Default, SField::notSigning)
|
||||
|
||||
// array of objects (common)
|
||||
// ARRAY/1 is reserved for end of array
|
||||
|
||||
@@ -1162,6 +1162,35 @@ TRANSACTION(ttCONFIDENTIAL_MPT_CLAWBACK, 89, ConfidentialMPTClawback,
|
||||
{sfZKProof, soeREQUIRED},
|
||||
}))
|
||||
|
||||
/** This transaction transfer sponsorship */
|
||||
#if TRANSACTION_INCLUDE
|
||||
# include <xrpl/tx/transactors/sponsor/SponsorshipTransfer.h>
|
||||
#endif
|
||||
TRANSACTION(ttSPONSORSHIP_TRANSFER, 90, SponsorshipTransfer,
|
||||
Delegation::delegable,
|
||||
featureSponsor,
|
||||
noPriv,
|
||||
({
|
||||
{sfObjectID, soeOPTIONAL},
|
||||
{sfSponsee, soeOPTIONAL},
|
||||
}))
|
||||
|
||||
/** This transaction create sponsorship object */
|
||||
#if TRANSACTION_INCLUDE
|
||||
# include <xrpl/tx/transactors/sponsor/SponsorshipSet.h>
|
||||
#endif
|
||||
TRANSACTION(ttSPONSORSHIP_SET, 91, SponsorshipSet,
|
||||
Delegation::delegable,
|
||||
featureSponsor,
|
||||
noPriv,
|
||||
({
|
||||
{sfCounterpartySponsor, soeOPTIONAL},
|
||||
{sfSponsee, soeOPTIONAL},
|
||||
{sfFeeAmount, soeOPTIONAL},
|
||||
{sfMaxFee, soeOPTIONAL},
|
||||
{sfReserveCount, soeOPTIONAL},
|
||||
}))
|
||||
|
||||
/** This system-generated transaction type is used to update the status of the various amendments.
|
||||
|
||||
For details, see: https://xrpl.org/amendments.html
|
||||
|
||||
@@ -558,6 +558,9 @@ JSS(source_account); // in: PathRequest, RipplePathFind
|
||||
JSS(source_amount); // in: PathRequest, RipplePathFind
|
||||
JSS(source_currencies); // in: PathRequest, RipplePathFind
|
||||
JSS(source_tag); // out: AccountChannels
|
||||
JSS(sponsee); // in: LedgerEntry
|
||||
JSS(sponsor); // in: LedgerEntry
|
||||
JSS(sponsored); // in: AccountObjects
|
||||
JSS(stand_alone); // out: NetworkOPs
|
||||
JSS(standard_deviation); // out: get_aggregate_price
|
||||
JSS(start); // in: TxHistory
|
||||
|
||||
@@ -518,6 +518,78 @@ public:
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfLoanBrokerID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfSponsoredOwnerCount (soeDEFAULT)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_UINT32::type::value_type>
|
||||
getSponsoredOwnerCount() const
|
||||
{
|
||||
if (hasSponsoredOwnerCount())
|
||||
return this->sle_->at(sfSponsoredOwnerCount);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfSponsoredOwnerCount is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasSponsoredOwnerCount() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfSponsoredOwnerCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfSponsoringOwnerCount (soeDEFAULT)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_UINT32::type::value_type>
|
||||
getSponsoringOwnerCount() const
|
||||
{
|
||||
if (hasSponsoringOwnerCount())
|
||||
return this->sle_->at(sfSponsoringOwnerCount);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfSponsoringOwnerCount is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasSponsoringOwnerCount() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfSponsoringOwnerCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfSponsoringAccountCount (soeDEFAULT)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_UINT32::type::value_type>
|
||||
getSponsoringAccountCount() const
|
||||
{
|
||||
if (hasSponsoringAccountCount())
|
||||
return this->sle_->at(sfSponsoringAccountCount);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfSponsoringAccountCount is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasSponsoringAccountCount() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfSponsoringAccountCount);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -819,6 +891,39 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfSponsoredOwnerCount (soeDEFAULT)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
AccountRootBuilder&
|
||||
setSponsoredOwnerCount(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfSponsoredOwnerCount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfSponsoringOwnerCount (soeDEFAULT)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
AccountRootBuilder&
|
||||
setSponsoringOwnerCount(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfSponsoringOwnerCount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfSponsoringAccountCount (soeDEFAULT)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
AccountRootBuilder&
|
||||
setSponsoringAccountCount(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfSponsoringAccountCount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the completed AccountRoot wrapper.
|
||||
* @param index The ledger entry index.
|
||||
|
||||
@@ -243,6 +243,54 @@ public:
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfHighQualityOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfHighSponsor (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_ACCOUNT::type::value_type>
|
||||
getHighSponsor() const
|
||||
{
|
||||
if (hasHighSponsor())
|
||||
return this->sle_->at(sfHighSponsor);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfHighSponsor is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasHighSponsor() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfHighSponsor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfLowSponsor (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_ACCOUNT::type::value_type>
|
||||
getLowSponsor() const
|
||||
{
|
||||
if (hasLowSponsor())
|
||||
return this->sle_->at(sfLowSponsor);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfLowSponsor is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasLowSponsor() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfLowSponsor);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -410,6 +458,28 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfHighSponsor (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
RippleStateBuilder&
|
||||
setHighSponsor(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfHighSponsor] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfLowSponsor (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
RippleStateBuilder&
|
||||
setLowSponsor(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfLowSponsor] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the completed RippleState wrapper.
|
||||
* @param index The ledger entry index.
|
||||
|
||||
344
include/xrpl/protocol_autogen/ledger_entries/Sponsorship.h
Normal file
344
include/xrpl/protocol_autogen/ledger_entries/Sponsorship.h
Normal file
@@ -0,0 +1,344 @@
|
||||
// This file is auto-generated. Do not edit.
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/STParsedJSON.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
#include <xrpl/protocol_autogen/LedgerEntryBase.h>
|
||||
#include <xrpl/protocol_autogen/LedgerEntryBuilderBase.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <optional>
|
||||
|
||||
namespace xrpl::ledger_entries {
|
||||
|
||||
class SponsorshipBuilder;
|
||||
|
||||
/**
|
||||
* @brief Ledger Entry: Sponsorship
|
||||
*
|
||||
* Type: ltSPONSORSHIP (0x0090)
|
||||
* RPC Name: sponsorship
|
||||
*
|
||||
* Immutable wrapper around SLE providing type-safe field access.
|
||||
* Use SponsorshipBuilder to construct new ledger entries.
|
||||
*/
|
||||
class Sponsorship : public LedgerEntryBase
|
||||
{
|
||||
public:
|
||||
static constexpr LedgerEntryType entryType = ltSPONSORSHIP;
|
||||
|
||||
/**
|
||||
* @brief Construct a Sponsorship ledger entry wrapper from an existing SLE object.
|
||||
* @throws std::runtime_error if the ledger entry type doesn't match.
|
||||
*/
|
||||
explicit Sponsorship(std::shared_ptr<SLE const> sle)
|
||||
: LedgerEntryBase(std::move(sle))
|
||||
{
|
||||
// Verify ledger entry type
|
||||
if (sle_->getType() != entryType)
|
||||
{
|
||||
throw std::runtime_error("Invalid ledger entry type for Sponsorship");
|
||||
}
|
||||
}
|
||||
|
||||
// Ledger entry-specific field getters
|
||||
|
||||
/**
|
||||
* @brief Get sfPreviousTxnID (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT256::type::value_type
|
||||
getPreviousTxnID() const
|
||||
{
|
||||
return this->sle_->at(sfPreviousTxnID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfPreviousTxnLgrSeq (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT32::type::value_type
|
||||
getPreviousTxnLgrSeq() const
|
||||
{
|
||||
return this->sle_->at(sfPreviousTxnLgrSeq);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfOwner (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_ACCOUNT::type::value_type
|
||||
getOwner() const
|
||||
{
|
||||
return this->sle_->at(sfOwner);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfSponsee (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_ACCOUNT::type::value_type
|
||||
getSponsee() const
|
||||
{
|
||||
return this->sle_->at(sfSponsee);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfFeeAmount (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_AMOUNT::type::value_type>
|
||||
getFeeAmount() const
|
||||
{
|
||||
if (hasFeeAmount())
|
||||
return this->sle_->at(sfFeeAmount);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfFeeAmount is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasFeeAmount() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfFeeAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfMaxFee (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_AMOUNT::type::value_type>
|
||||
getMaxFee() const
|
||||
{
|
||||
if (hasMaxFee())
|
||||
return this->sle_->at(sfMaxFee);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfMaxFee is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasMaxFee() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfMaxFee);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfReserveCount (soeDEFAULT)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_UINT32::type::value_type>
|
||||
getReserveCount() const
|
||||
{
|
||||
if (hasReserveCount())
|
||||
return this->sle_->at(sfReserveCount);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfReserveCount is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasReserveCount() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfReserveCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfOwnerNode (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT64::type::value_type
|
||||
getOwnerNode() const
|
||||
{
|
||||
return this->sle_->at(sfOwnerNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfSponseeNode (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT64::type::value_type
|
||||
getSponseeNode() const
|
||||
{
|
||||
return this->sle_->at(sfSponseeNode);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Builder for Sponsorship ledger entries.
|
||||
*
|
||||
* Provides a fluent interface for constructing ledger entries with method chaining.
|
||||
* Uses Json::Value internally for flexible ledger entry construction.
|
||||
* Inherits common field setters from LedgerEntryBuilderBase.
|
||||
*/
|
||||
class SponsorshipBuilder : public LedgerEntryBuilderBase<SponsorshipBuilder>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new SponsorshipBuilder with required fields.
|
||||
* @param previousTxnID The sfPreviousTxnID field value.
|
||||
* @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value.
|
||||
* @param owner The sfOwner field value.
|
||||
* @param sponsee The sfSponsee field value.
|
||||
* @param ownerNode The sfOwnerNode field value.
|
||||
* @param sponseeNode The sfSponseeNode field value.
|
||||
*/
|
||||
SponsorshipBuilder(std::decay_t<typename SF_UINT256::type::value_type> const& previousTxnID,std::decay_t<typename SF_UINT32::type::value_type> const& previousTxnLgrSeq,std::decay_t<typename SF_ACCOUNT::type::value_type> const& owner,std::decay_t<typename SF_ACCOUNT::type::value_type> const& sponsee,std::decay_t<typename SF_UINT64::type::value_type> const& ownerNode,std::decay_t<typename SF_UINT64::type::value_type> const& sponseeNode)
|
||||
: LedgerEntryBuilderBase<SponsorshipBuilder>(ltSPONSORSHIP)
|
||||
{
|
||||
setPreviousTxnID(previousTxnID);
|
||||
setPreviousTxnLgrSeq(previousTxnLgrSeq);
|
||||
setOwner(owner);
|
||||
setSponsee(sponsee);
|
||||
setOwnerNode(ownerNode);
|
||||
setSponseeNode(sponseeNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a SponsorshipBuilder from an existing SLE object.
|
||||
* @param sle The existing ledger entry to copy from.
|
||||
* @throws std::runtime_error if the ledger entry type doesn't match.
|
||||
*/
|
||||
SponsorshipBuilder(std::shared_ptr<SLE const> sle)
|
||||
{
|
||||
if (sle->at(sfLedgerEntryType) != ltSPONSORSHIP)
|
||||
{
|
||||
throw std::runtime_error("Invalid ledger entry type for Sponsorship");
|
||||
}
|
||||
object_ = *sle;
|
||||
}
|
||||
|
||||
/** @brief Ledger entry-specific field setters */
|
||||
|
||||
/**
|
||||
* @brief Set sfPreviousTxnID (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipBuilder&
|
||||
setPreviousTxnID(std::decay_t<typename SF_UINT256::type::value_type> const& value)
|
||||
{
|
||||
object_[sfPreviousTxnID] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfPreviousTxnLgrSeq (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipBuilder&
|
||||
setPreviousTxnLgrSeq(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfPreviousTxnLgrSeq] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfOwner (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipBuilder&
|
||||
setOwner(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfOwner] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfSponsee (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipBuilder&
|
||||
setSponsee(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfSponsee] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfFeeAmount (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipBuilder&
|
||||
setFeeAmount(std::decay_t<typename SF_AMOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfFeeAmount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfMaxFee (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipBuilder&
|
||||
setMaxFee(std::decay_t<typename SF_AMOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfMaxFee] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfReserveCount (soeDEFAULT)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipBuilder&
|
||||
setReserveCount(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfReserveCount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfOwnerNode (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipBuilder&
|
||||
setOwnerNode(std::decay_t<typename SF_UINT64::type::value_type> const& value)
|
||||
{
|
||||
object_[sfOwnerNode] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfSponseeNode (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipBuilder&
|
||||
setSponseeNode(std::decay_t<typename SF_UINT64::type::value_type> const& value)
|
||||
{
|
||||
object_[sfSponseeNode] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the completed Sponsorship wrapper.
|
||||
* @param index The ledger entry index.
|
||||
* @return The constructed ledger entry wrapper.
|
||||
*/
|
||||
Sponsorship
|
||||
build(uint256 const& index)
|
||||
{
|
||||
return Sponsorship{std::make_shared<SLE>(std::move(object_), index)};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::ledger_entries
|
||||
290
include/xrpl/protocol_autogen/transactions/SponsorshipSet.h
Normal file
290
include/xrpl/protocol_autogen/transactions/SponsorshipSet.h
Normal file
@@ -0,0 +1,290 @@
|
||||
// This file is auto-generated. Do not edit.
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/STParsedJSON.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
#include <xrpl/protocol_autogen/TransactionBase.h>
|
||||
#include <xrpl/protocol_autogen/TransactionBuilderBase.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <optional>
|
||||
|
||||
namespace xrpl::transactions {
|
||||
|
||||
class SponsorshipSetBuilder;
|
||||
|
||||
/**
|
||||
* @brief Transaction: SponsorshipSet
|
||||
*
|
||||
* Type: ttSPONSORSHIP_SET (91)
|
||||
* Delegable: Delegation::delegable
|
||||
* Amendment: featureSponsor
|
||||
* Privileges: noPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use SponsorshipSetBuilder to construct new transactions.
|
||||
*/
|
||||
class SponsorshipSet : public TransactionBase
|
||||
{
|
||||
public:
|
||||
static constexpr xrpl::TxType txType = ttSPONSORSHIP_SET;
|
||||
|
||||
/**
|
||||
* @brief Construct a SponsorshipSet transaction wrapper from an existing STTx object.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
explicit SponsorshipSet(std::shared_ptr<STTx const> tx)
|
||||
: TransactionBase(std::move(tx))
|
||||
{
|
||||
// Verify transaction type
|
||||
if (tx_->getTxnType() != txType)
|
||||
{
|
||||
throw std::runtime_error("Invalid transaction type for SponsorshipSet");
|
||||
}
|
||||
}
|
||||
|
||||
// Transaction-specific field getters
|
||||
|
||||
/**
|
||||
* @brief Get sfCounterpartySponsor (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_ACCOUNT::type::value_type>
|
||||
getCounterpartySponsor() const
|
||||
{
|
||||
if (hasCounterpartySponsor())
|
||||
{
|
||||
return this->tx_->at(sfCounterpartySponsor);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfCounterpartySponsor is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasCounterpartySponsor() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfCounterpartySponsor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfSponsee (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_ACCOUNT::type::value_type>
|
||||
getSponsee() const
|
||||
{
|
||||
if (hasSponsee())
|
||||
{
|
||||
return this->tx_->at(sfSponsee);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfSponsee is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasSponsee() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfSponsee);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfFeeAmount (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_AMOUNT::type::value_type>
|
||||
getFeeAmount() const
|
||||
{
|
||||
if (hasFeeAmount())
|
||||
{
|
||||
return this->tx_->at(sfFeeAmount);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfFeeAmount is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasFeeAmount() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfFeeAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfMaxFee (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_AMOUNT::type::value_type>
|
||||
getMaxFee() const
|
||||
{
|
||||
if (hasMaxFee())
|
||||
{
|
||||
return this->tx_->at(sfMaxFee);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfMaxFee is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasMaxFee() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfMaxFee);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfReserveCount (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_UINT32::type::value_type>
|
||||
getReserveCount() const
|
||||
{
|
||||
if (hasReserveCount())
|
||||
{
|
||||
return this->tx_->at(sfReserveCount);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfReserveCount is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasReserveCount() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfReserveCount);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Builder for SponsorshipSet transactions.
|
||||
*
|
||||
* Provides a fluent interface for constructing transactions with method chaining.
|
||||
* Uses Json::Value internally for flexible transaction construction.
|
||||
* Inherits common field setters from TransactionBuilderBase.
|
||||
*/
|
||||
class SponsorshipSetBuilder : public TransactionBuilderBase<SponsorshipSetBuilder>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new SponsorshipSetBuilder with required fields.
|
||||
* @param account The account initiating the transaction.
|
||||
* @param sequence Optional sequence number for the transaction.
|
||||
* @param fee Optional fee for the transaction.
|
||||
*/
|
||||
SponsorshipSetBuilder(SF_ACCOUNT::type::value_type account,
|
||||
std::optional<SF_UINT32::type::value_type> sequence = std::nullopt,
|
||||
std::optional<SF_AMOUNT::type::value_type> fee = std::nullopt
|
||||
)
|
||||
: TransactionBuilderBase<SponsorshipSetBuilder>(ttSPONSORSHIP_SET, account, sequence, fee)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a SponsorshipSetBuilder from an existing STTx object.
|
||||
* @param tx The existing transaction to copy from.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
SponsorshipSetBuilder(std::shared_ptr<STTx const> tx)
|
||||
{
|
||||
if (tx->getTxnType() != ttSPONSORSHIP_SET)
|
||||
{
|
||||
throw std::runtime_error("Invalid transaction type for SponsorshipSetBuilder");
|
||||
}
|
||||
object_ = *tx;
|
||||
}
|
||||
|
||||
/** @brief Transaction-specific field setters */
|
||||
|
||||
/**
|
||||
* @brief Set sfCounterpartySponsor (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipSetBuilder&
|
||||
setCounterpartySponsor(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfCounterpartySponsor] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfSponsee (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipSetBuilder&
|
||||
setSponsee(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfSponsee] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfFeeAmount (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipSetBuilder&
|
||||
setFeeAmount(std::decay_t<typename SF_AMOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfFeeAmount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfMaxFee (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipSetBuilder&
|
||||
setMaxFee(std::decay_t<typename SF_AMOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfMaxFee] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfReserveCount (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipSetBuilder&
|
||||
setReserveCount(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfReserveCount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the SponsorshipSet wrapper.
|
||||
* @param publicKey The public key for signing.
|
||||
* @param secretKey The secret key for signing.
|
||||
* @return The constructed transaction wrapper.
|
||||
*/
|
||||
SponsorshipSet
|
||||
build(PublicKey const& publicKey, SecretKey const& secretKey)
|
||||
{
|
||||
sign(publicKey, secretKey);
|
||||
return SponsorshipSet{std::make_shared<STTx>(std::move(object_))};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::transactions
|
||||
179
include/xrpl/protocol_autogen/transactions/SponsorshipTransfer.h
Normal file
179
include/xrpl/protocol_autogen/transactions/SponsorshipTransfer.h
Normal file
@@ -0,0 +1,179 @@
|
||||
// This file is auto-generated. Do not edit.
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/STParsedJSON.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
#include <xrpl/protocol_autogen/TransactionBase.h>
|
||||
#include <xrpl/protocol_autogen/TransactionBuilderBase.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <optional>
|
||||
|
||||
namespace xrpl::transactions {
|
||||
|
||||
class SponsorshipTransferBuilder;
|
||||
|
||||
/**
|
||||
* @brief Transaction: SponsorshipTransfer
|
||||
*
|
||||
* Type: ttSPONSORSHIP_TRANSFER (90)
|
||||
* Delegable: Delegation::delegable
|
||||
* Amendment: featureSponsor
|
||||
* Privileges: noPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use SponsorshipTransferBuilder to construct new transactions.
|
||||
*/
|
||||
class SponsorshipTransfer : public TransactionBase
|
||||
{
|
||||
public:
|
||||
static constexpr xrpl::TxType txType = ttSPONSORSHIP_TRANSFER;
|
||||
|
||||
/**
|
||||
* @brief Construct a SponsorshipTransfer transaction wrapper from an existing STTx object.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
explicit SponsorshipTransfer(std::shared_ptr<STTx const> tx)
|
||||
: TransactionBase(std::move(tx))
|
||||
{
|
||||
// Verify transaction type
|
||||
if (tx_->getTxnType() != txType)
|
||||
{
|
||||
throw std::runtime_error("Invalid transaction type for SponsorshipTransfer");
|
||||
}
|
||||
}
|
||||
|
||||
// Transaction-specific field getters
|
||||
|
||||
/**
|
||||
* @brief Get sfObjectID (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_UINT256::type::value_type>
|
||||
getObjectID() const
|
||||
{
|
||||
if (hasObjectID())
|
||||
{
|
||||
return this->tx_->at(sfObjectID);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfObjectID is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasObjectID() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfObjectID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfSponsee (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_ACCOUNT::type::value_type>
|
||||
getSponsee() const
|
||||
{
|
||||
if (hasSponsee())
|
||||
{
|
||||
return this->tx_->at(sfSponsee);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfSponsee is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasSponsee() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfSponsee);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Builder for SponsorshipTransfer transactions.
|
||||
*
|
||||
* Provides a fluent interface for constructing transactions with method chaining.
|
||||
* Uses Json::Value internally for flexible transaction construction.
|
||||
* Inherits common field setters from TransactionBuilderBase.
|
||||
*/
|
||||
class SponsorshipTransferBuilder : public TransactionBuilderBase<SponsorshipTransferBuilder>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new SponsorshipTransferBuilder with required fields.
|
||||
* @param account The account initiating the transaction.
|
||||
* @param sequence Optional sequence number for the transaction.
|
||||
* @param fee Optional fee for the transaction.
|
||||
*/
|
||||
SponsorshipTransferBuilder(SF_ACCOUNT::type::value_type account,
|
||||
std::optional<SF_UINT32::type::value_type> sequence = std::nullopt,
|
||||
std::optional<SF_AMOUNT::type::value_type> fee = std::nullopt
|
||||
)
|
||||
: TransactionBuilderBase<SponsorshipTransferBuilder>(ttSPONSORSHIP_TRANSFER, account, sequence, fee)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a SponsorshipTransferBuilder from an existing STTx object.
|
||||
* @param tx The existing transaction to copy from.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
SponsorshipTransferBuilder(std::shared_ptr<STTx const> tx)
|
||||
{
|
||||
if (tx->getTxnType() != ttSPONSORSHIP_TRANSFER)
|
||||
{
|
||||
throw std::runtime_error("Invalid transaction type for SponsorshipTransferBuilder");
|
||||
}
|
||||
object_ = *tx;
|
||||
}
|
||||
|
||||
/** @brief Transaction-specific field setters */
|
||||
|
||||
/**
|
||||
* @brief Set sfObjectID (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipTransferBuilder&
|
||||
setObjectID(std::decay_t<typename SF_UINT256::type::value_type> const& value)
|
||||
{
|
||||
object_[sfObjectID] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfSponsee (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SponsorshipTransferBuilder&
|
||||
setSponsee(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfSponsee] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the SponsorshipTransfer wrapper.
|
||||
* @param publicKey The public key for signing.
|
||||
* @param secretKey The secret key for signing.
|
||||
* @return The constructed transaction wrapper.
|
||||
*/
|
||||
SponsorshipTransfer
|
||||
build(PublicKey const& publicKey, SecretKey const& secretKey)
|
||||
{
|
||||
sign(publicKey, secretKey);
|
||||
return SponsorshipTransfer{std::make_shared<STTx>(std::move(object_))};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::transactions
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/beast/utility/WrappedSink.h>
|
||||
#include <xrpl/ledger/helpers/SponsorHelpers.h>
|
||||
#include <xrpl/protocol/Permissions.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/ApplyContext.h>
|
||||
@@ -106,6 +107,20 @@ struct PreflightResult;
|
||||
// Needed for preflight specialization
|
||||
class Change;
|
||||
|
||||
enum class FeePayerType {
|
||||
Account,
|
||||
Delegate,
|
||||
SponsorCoSigned,
|
||||
SponsorPreFunded,
|
||||
};
|
||||
|
||||
struct FeePayer
|
||||
{
|
||||
Keylet entry;
|
||||
SF_AMOUNT const& balanceField;
|
||||
FeePayerType type{FeePayerType::Account};
|
||||
};
|
||||
|
||||
class Transactor
|
||||
{
|
||||
protected:
|
||||
@@ -244,6 +259,9 @@ public:
|
||||
|
||||
return T::checkGranularSemantics(view, tx, heldGranularPermissions);
|
||||
}
|
||||
|
||||
static NotTEC
|
||||
checkSponsor(ReadView const& view, STTx const& tx);
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
// Interface used by AccountDelete
|
||||
@@ -355,6 +373,9 @@ private:
|
||||
std::pair<TER, XRPAmount>
|
||||
reset(XRPAmount fee);
|
||||
|
||||
static FeePayer
|
||||
getFeePayer(ReadView const& view, STTx const& tx);
|
||||
|
||||
TER
|
||||
consumeSeqProxy(SLE::pointer const& sleAccount);
|
||||
TER
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <xrpl/tx/invariants/NFTInvariant.h>
|
||||
#include <xrpl/tx/invariants/PermissionedDEXInvariant.h>
|
||||
#include <xrpl/tx/invariants/PermissionedDomainInvariant.h>
|
||||
#include <xrpl/tx/invariants/SponsorshipInvariant.h>
|
||||
#include <xrpl/tx/invariants/VaultInvariant.h>
|
||||
|
||||
#include <cstdint>
|
||||
@@ -401,7 +402,9 @@ using InvariantChecks = std::tuple<
|
||||
ValidVault,
|
||||
ValidConfidentialMPToken,
|
||||
ValidMPTPayment,
|
||||
ValidMPTTransfer>;
|
||||
ValidMPTTransfer,
|
||||
SponsorshipOwnerCountsMatch,
|
||||
SponsorshipAccountCountMatchesField>;
|
||||
|
||||
/**
|
||||
* @brief get a tuple of all invariant checks
|
||||
|
||||
55
include/xrpl/tx/invariants/SponsorshipInvariant.h
Normal file
55
include/xrpl/tx/invariants/SponsorshipInvariant.h
Normal file
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
/**
|
||||
* @brief Invariant: Sponsored owner counts are balanced.
|
||||
*
|
||||
* The following check is made for every transaction:
|
||||
* - The sum of all per-account deltas of `sfSponsoredOwnerCount` equals
|
||||
* the sum of all per-account deltas of `sfSponsoringOwnerCount`.
|
||||
* - Account OwnerCount must be greater than or equal to SponsoredOwnerCount.
|
||||
*/
|
||||
class SponsorshipOwnerCountsMatch
|
||||
{
|
||||
std::int64_t deltaSponsoredOwnerCount_ = 0;
|
||||
std::int64_t deltaSponsoringOwnerCount_ = 0;
|
||||
std::uint64_t invalidOwnerCountLessThanSponsoredOwnerCount_ = 0;
|
||||
|
||||
public:
|
||||
void
|
||||
visitEntry(bool, std::shared_ptr<SLE const> const&, std::shared_ptr<SLE const> const&);
|
||||
|
||||
bool
|
||||
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Invariant: Sponsoring account relationships tracked consistently.
|
||||
*
|
||||
* The following check is made for every transaction:
|
||||
* - The net delta of `sfSponsoringAccountCount` across all accounts equals
|
||||
* the net delta of the count of ltACCOUNT_ROOT entries having
|
||||
* `sfSponsor` present (presence transitions only: add/remove).
|
||||
*/
|
||||
class SponsorshipAccountCountMatchesField
|
||||
{
|
||||
std::int64_t deltaSponsoringAccountCount_ = 0;
|
||||
std::int64_t deltaSponsorFieldPresence_ = 0;
|
||||
|
||||
public:
|
||||
void
|
||||
visitEntry(bool, std::shared_ptr<SLE const> const&, std::shared_ptr<SLE const> const&);
|
||||
|
||||
bool
|
||||
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&);
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -104,7 +104,10 @@ public:
|
||||
send(Args&&... args)
|
||||
{
|
||||
return accountSend(
|
||||
std::forward<Args>(args)..., WaiveTransferFee::Yes, AllowMPTOverflow::Yes);
|
||||
std::forward<Args>(args)...,
|
||||
std::nullopt,
|
||||
WaiveTransferFee::Yes,
|
||||
AllowMPTOverflow::Yes);
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@@ -213,7 +213,8 @@ template <typename... Args>
|
||||
TER
|
||||
TOffer<TIn, TOut>::send(Args&&... args)
|
||||
{
|
||||
return accountSend(std::forward<Args>(args)..., WaiveTransferFee::No, AllowMPTOverflow::Yes);
|
||||
return accountSend(
|
||||
std::forward<Args>(args)..., std::nullopt, WaiveTransferFee::No, AllowMPTOverflow::Yes);
|
||||
}
|
||||
|
||||
template <StepAmount TIn, StepAmount TOut>
|
||||
|
||||
@@ -89,6 +89,7 @@ public:
|
||||
static std::tuple<TER, STAmount, STAmount, std::optional<STAmount>>
|
||||
equalWithdrawTokens(
|
||||
Sandbox& view,
|
||||
STTx const& tx,
|
||||
SLE const& ammSle,
|
||||
AccountID const account,
|
||||
AccountID const& ammAccount,
|
||||
@@ -123,6 +124,7 @@ public:
|
||||
static std::tuple<TER, STAmount, STAmount, std::optional<STAmount>>
|
||||
withdraw(
|
||||
Sandbox& view,
|
||||
STTx const& tx,
|
||||
SLE const& ammSle,
|
||||
AccountID const& ammAccount,
|
||||
AccountID const& account,
|
||||
@@ -166,6 +168,7 @@ private:
|
||||
std::pair<TER, STAmount>
|
||||
withdraw(
|
||||
Sandbox& view,
|
||||
STTx const& tx,
|
||||
SLE const& ammSle,
|
||||
AccountID const& ammAccount,
|
||||
STAmount const& amountBalance,
|
||||
@@ -191,6 +194,7 @@ private:
|
||||
std::pair<TER, STAmount>
|
||||
equalWithdrawTokens(
|
||||
Sandbox& view,
|
||||
STTx const& tx,
|
||||
SLE const& ammSle,
|
||||
AccountID const& ammAccount,
|
||||
STAmount const& amountBalance,
|
||||
@@ -216,6 +220,7 @@ private:
|
||||
std::pair<TER, STAmount>
|
||||
equalWithdrawLimit(
|
||||
Sandbox& view,
|
||||
STTx const& tx,
|
||||
SLE const& ammSle,
|
||||
AccountID const& ammAccount,
|
||||
STAmount const& amountBalance,
|
||||
@@ -238,6 +243,7 @@ private:
|
||||
std::pair<TER, STAmount>
|
||||
singleWithdraw(
|
||||
Sandbox& view,
|
||||
STTx const& tx,
|
||||
SLE const& ammSle,
|
||||
AccountID const& ammAccount,
|
||||
STAmount const& amountBalance,
|
||||
@@ -259,6 +265,7 @@ private:
|
||||
std::pair<TER, STAmount>
|
||||
singleWithdrawTokens(
|
||||
Sandbox& view,
|
||||
STTx const& tx,
|
||||
SLE const& ammSle,
|
||||
AccountID const& ammAccount,
|
||||
STAmount const& amountBalance,
|
||||
@@ -281,6 +288,7 @@ private:
|
||||
std::pair<TER, STAmount>
|
||||
singleWithdrawEPrice(
|
||||
Sandbox& view,
|
||||
STTx const& tx,
|
||||
SLE const& ammSle,
|
||||
AccountID const& ammAccount,
|
||||
STAmount const& amountBalance,
|
||||
|
||||
@@ -22,6 +22,9 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
calculateOracleReserve(std::size_t count);
|
||||
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
|
||||
29
include/xrpl/tx/transactors/sponsor/SponsorshipSet.h
Normal file
29
include/xrpl/tx/transactors/sponsor/SponsorshipSet.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
class SponsorshipSet : public Transactor
|
||||
{
|
||||
public:
|
||||
static constexpr ConsequencesFactoryType ConsequencesFactory{Normal};
|
||||
|
||||
explicit SponsorshipSet(ApplyContext& ctx) : Transactor(ctx)
|
||||
{
|
||||
}
|
||||
|
||||
static std::uint32_t
|
||||
getFlagsMask(PreflightContext const& ctx);
|
||||
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
static TER
|
||||
preclaim(PreclaimContext const& ctx);
|
||||
|
||||
TER
|
||||
doApply() override;
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
29
include/xrpl/tx/transactors/sponsor/SponsorshipTransfer.h
Normal file
29
include/xrpl/tx/transactors/sponsor/SponsorshipTransfer.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
class SponsorshipTransfer : public Transactor
|
||||
{
|
||||
public:
|
||||
static constexpr ConsequencesFactoryType ConsequencesFactory{Normal};
|
||||
|
||||
explicit SponsorshipTransfer(ApplyContext& ctx) : Transactor(ctx)
|
||||
{
|
||||
}
|
||||
|
||||
static std::uint32_t
|
||||
getFlagsMask(PreflightContext const& ctx);
|
||||
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
static TER
|
||||
preclaim(PreclaimContext const& ctx);
|
||||
|
||||
TER
|
||||
doApply() override;
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
doApply() override;
|
||||
|
||||
static Expected<MPTID, TER>
|
||||
create(ApplyView& view, beast::Journal journal, MPTCreateArgs const& args);
|
||||
create(ApplyView& view, STTx const& tx, beast::Journal journal, MPTCreateArgs const& args);
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
Reference in New Issue
Block a user