Compare commits

...

14 Commits

Author SHA1 Message Date
JCW
4b5ed9c219 Fix formatting
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
2025-08-04 21:49:52 +01:00
JCW
5dd2020902 Revert unnecessary changes
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
2025-08-04 21:46:14 +01:00
JCW
ae95aff7aa Demonstrate how strongly typed ledger objects work
Signed-off-by: JCW <a1q123456@users.noreply.github.com>

# Conflicts:
#	include/xrpl/protocol/Keylet.h
#	src/libxrpl/protocol/Indexes.cpp
#	src/xrpld/rpc/handlers/VaultInfo.cpp
2025-08-04 21:43:22 +01:00
JCW
4f5fb6b298 Fix build error
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
2025-08-04 21:38:45 +01:00
JCW
c742a94e5f Fix formatting
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
2025-08-04 21:34:27 +01:00
JCW
abf240f6f3 Make Keylet strongly typed so that we can get strongly typed ledger obejcts from views
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
2025-08-04 21:32:56 +01:00
JCW
3f8fed9628 Fix formatting
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
2025-08-04 21:27:40 +01:00
JCW
e2e82e1c96 Support const ledger entries
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
2025-08-04 21:24:03 +01:00
JCW
a7a39d62d3 Fix formatting 2025-07-11 17:19:27 +01:00
JCW
b875ea9f37 Add comments 2025-07-11 17:09:15 +01:00
JCW
a25f2ee9dd Fix formatting 2025-07-11 11:10:59 +01:00
JCW
4f295d4856 Fix build error 2025-07-11 10:40:17 +01:00
JCW
2e5f69f8f8 Fix test coverage 2025-07-10 20:18:27 +01:00
JCW
02da6b2508 Strongly typed ledger objects support 2025-07-10 17:19:38 +01:00
31 changed files with 2074 additions and 587 deletions

View File

@@ -53,11 +53,11 @@ class SeqProxy;
namespace keylet {
/** AccountID root */
Keylet
TypedKeylet<ltACCOUNT_ROOT>
account(AccountID const& id) noexcept;
/** The index of the amendment table */
Keylet const&
TypedKeylet<ltAMENDMENTS> const&
amendments() noexcept;
/** Any item that can be in an owner dir. */
@@ -69,7 +69,7 @@ child(uint256 const& key) noexcept;
The "short" skip list is a node (at a fixed index) that holds the hashes
of ledgers since the last flag ledger. It will contain, at most, 256 hashes.
*/
Keylet const&
TypedKeylet<ltLEDGER_HASHES> const&
skip() noexcept;
/** The index of the long skip for a particular ledger range.
@@ -82,15 +82,15 @@ skip() noexcept;
and uses it to get the hash of the flag ledger whose short skip list will
contain the hash of the requested ledger.
*/
Keylet
TypedKeylet<ltLEDGER_HASHES>
skip(LedgerIndex ledger) noexcept;
/** The (fixed) index of the object containing the ledger fees. */
Keylet const&
TypedKeylet<ltFEE_SETTINGS> const&
fees() noexcept;
/** The (fixed) index of the object containing the ledger negativeUNL. */
Keylet const&
TypedKeylet<ltNEGATIVE_UNL> const&
negativeUNL() noexcept;
/** The beginning of an order book */
@@ -98,7 +98,7 @@ struct book_t
{
explicit book_t() = default;
Keylet
TypedKeylet<ltDIR_NODE>
operator()(Book const& b) const;
};
static book_t const book{};
@@ -111,13 +111,13 @@ static book_t const book{};
between them.
*/
/** @{ */
Keylet
TypedKeylet<ltRIPPLE_STATE>
line(
AccountID const& id0,
AccountID const& id1,
Currency const& currency) noexcept;
inline Keylet
inline TypedKeylet<ltRIPPLE_STATE>
line(AccountID const& id, Issue const& issue) noexcept
{
return line(id, issue.account, issue.currency);
@@ -126,27 +126,27 @@ line(AccountID const& id, Issue const& issue) noexcept
/** An offer from an account */
/** @{ */
Keylet
TypedKeylet<ltOFFER>
offer(AccountID const& id, std::uint32_t seq) noexcept;
inline Keylet
inline TypedKeylet<ltOFFER>
offer(uint256 const& key) noexcept
{
return {ltOFFER, key};
return {key};
}
/** @} */
/** The initial directory page for a specific quality */
Keylet
quality(Keylet const& k, std::uint64_t q) noexcept;
TypedKeylet<ltDIR_NODE>
quality(TypedKeylet<ltDIR_NODE> const& k, std::uint64_t q) noexcept;
/** The directory for the next lower quality */
struct next_t
{
explicit next_t() = default;
Keylet
operator()(Keylet const& k) const;
TypedKeylet<ltDIR_NODE>
operator()(TypedKeylet<ltDIR_NODE> const& k) const;
};
static next_t const next{};
@@ -155,50 +155,50 @@ struct ticket_t
{
explicit ticket_t() = default;
Keylet
TypedKeylet<ltTICKET>
operator()(AccountID const& id, std::uint32_t ticketSeq) const;
Keylet
TypedKeylet<ltTICKET>
operator()(AccountID const& id, SeqProxy ticketSeq) const;
Keylet
TypedKeylet<ltTICKET>
operator()(uint256 const& key) const
{
return {ltTICKET, key};
return {key};
}
};
static ticket_t const ticket{};
/** A SignerList */
Keylet
TypedKeylet<ltSIGNER_LIST>
signers(AccountID const& account) noexcept;
/** A Check */
/** @{ */
Keylet
TypedKeylet<ltCHECK>
check(AccountID const& id, std::uint32_t seq) noexcept;
inline Keylet
inline TypedKeylet<ltCHECK>
check(uint256 const& key) noexcept
{
return {ltCHECK, key};
return {key};
}
/** @} */
/** A DepositPreauth */
/** @{ */
Keylet
TypedKeylet<ltDEPOSIT_PREAUTH>
depositPreauth(AccountID const& owner, AccountID const& preauthorized) noexcept;
Keylet
TypedKeylet<ltDEPOSIT_PREAUTH>
depositPreauth(
AccountID const& owner,
std::set<std::pair<AccountID, Slice>> const& authCreds) noexcept;
inline Keylet
inline TypedKeylet<ltDEPOSIT_PREAUTH>
depositPreauth(uint256 const& key) noexcept
{
return {ltDEPOSIT_PREAUTH, key};
return {key};
}
/** @} */
@@ -209,15 +209,15 @@ Keylet
unchecked(uint256 const& key) noexcept;
/** The root page of an account's directory */
Keylet
TypedKeylet<ltDIR_NODE>
ownerDir(AccountID const& id) noexcept;
/** A page in a directory */
/** @{ */
Keylet
TypedKeylet<ltDIR_NODE>
page(uint256 const& root, std::uint64_t index = 0) noexcept;
inline Keylet
inline TypedKeylet<ltDIR_NODE>
page(Keylet const& root, std::uint64_t index = 0) noexcept
{
XRPL_ASSERT(
@@ -227,11 +227,11 @@ page(Keylet const& root, std::uint64_t index = 0) noexcept
/** @} */
/** An escrow entry */
Keylet
TypedKeylet<ltESCROW>
escrow(AccountID const& src, std::uint32_t seq) noexcept;
/** A PaymentChannel */
Keylet
TypedKeylet<ltPAYCHAN>
payChan(AccountID const& src, AccountID const& dst, std::uint32_t seq) noexcept;
/** NFT page keylets
@@ -243,110 +243,110 @@ payChan(AccountID const& src, AccountID const& dst, std::uint32_t seq) noexcept;
*/
/** @{ */
/** A keylet for the owner's first possible NFT page. */
Keylet
TypedKeylet<ltNFTOKEN_PAGE>
nftpage_min(AccountID const& owner);
/** A keylet for the owner's last possible NFT page. */
Keylet
TypedKeylet<ltNFTOKEN_PAGE>
nftpage_max(AccountID const& owner);
Keylet
nftpage(Keylet const& k, uint256 const& token);
TypedKeylet<ltNFTOKEN_PAGE>
nftpage(TypedKeylet<ltNFTOKEN_PAGE> const& k, uint256 const& token);
/** @} */
/** An offer from an account to buy or sell an NFT */
Keylet
TypedKeylet<ltNFTOKEN_OFFER>
nftoffer(AccountID const& owner, std::uint32_t seq);
inline Keylet
inline TypedKeylet<ltNFTOKEN_OFFER>
nftoffer(uint256 const& offer)
{
return {ltNFTOKEN_OFFER, offer};
return {offer};
}
/** The directory of buy offers for the specified NFT */
Keylet
TypedKeylet<ltDIR_NODE>
nft_buys(uint256 const& id) noexcept;
/** The directory of sell offers for the specified NFT */
Keylet
TypedKeylet<ltDIR_NODE>
nft_sells(uint256 const& id) noexcept;
/** AMM entry */
Keylet
TypedKeylet<ltAMM>
amm(Asset const& issue1, Asset const& issue2) noexcept;
Keylet
TypedKeylet<ltAMM>
amm(uint256 const& amm) noexcept;
/** A keylet for Delegate object */
Keylet
TypedKeylet<ltDELEGATE>
delegate(AccountID const& account, AccountID const& authorizedAccount) noexcept;
Keylet
TypedKeylet<ltBRIDGE>
bridge(STXChainBridge const& bridge, STXChainBridge::ChainType chainType);
Keylet
TypedKeylet<ltXCHAIN_OWNED_CLAIM_ID>
xChainClaimID(STXChainBridge const& bridge, std::uint64_t seq);
Keylet
TypedKeylet<ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID>
xChainCreateAccountClaimID(STXChainBridge const& bridge, std::uint64_t seq);
Keylet
TypedKeylet<ltDID>
did(AccountID const& account) noexcept;
Keylet
TypedKeylet<ltORACLE>
oracle(AccountID const& account, std::uint32_t const& documentID) noexcept;
Keylet
TypedKeylet<ltCREDENTIAL>
credential(
AccountID const& subject,
AccountID const& issuer,
Slice const& credType) noexcept;
inline Keylet
inline TypedKeylet<ltCREDENTIAL>
credential(uint256 const& key) noexcept
{
return {ltCREDENTIAL, key};
return {key};
}
Keylet
TypedKeylet<ltMPTOKEN_ISSUANCE>
mptIssuance(std::uint32_t seq, AccountID const& issuer) noexcept;
Keylet
TypedKeylet<ltMPTOKEN_ISSUANCE>
mptIssuance(MPTID const& issuanceID) noexcept;
inline Keylet
inline TypedKeylet<ltMPTOKEN_ISSUANCE>
mptIssuance(uint256 const& issuanceKey)
{
return {ltMPTOKEN_ISSUANCE, issuanceKey};
return {issuanceKey};
}
Keylet
TypedKeylet<ltMPTOKEN>
mptoken(MPTID const& issuanceID, AccountID const& holder) noexcept;
inline Keylet
inline TypedKeylet<ltMPTOKEN>
mptoken(uint256 const& mptokenKey)
{
return {ltMPTOKEN, mptokenKey};
return {mptokenKey};
}
Keylet
TypedKeylet<ltMPTOKEN>
mptoken(uint256 const& issuanceKey, AccountID const& holder) noexcept;
Keylet
TypedKeylet<ltVAULT>
vault(AccountID const& owner, std::uint32_t seq) noexcept;
inline Keylet
inline TypedKeylet<ltVAULT>
vault(uint256 const& vaultKey)
{
return {ltVAULT, vaultKey};
return {vaultKey};
}
Keylet
TypedKeylet<ltPERMISSIONED_DOMAIN>
permissionedDomain(AccountID const& account, std::uint32_t seq) noexcept;
Keylet
TypedKeylet<ltPERMISSIONED_DOMAIN>
permissionedDomain(uint256 const& domainID) noexcept;
} // namespace keylet

View File

@@ -49,6 +49,22 @@ struct Keylet
check(STLedgerEntry const&) const;
};
template <LedgerEntryType Type>
struct TypedKeylet : Keylet
{
static constexpr LedgerEntryType LedgerType = Type;
TypedKeylet(uint256 const& key_) : Keylet(Type, key_)
{
}
Keylet
untyped() const
{
return Keylet(LedgerType, key);
}
};
} // namespace ripple
#endif

View File

@@ -55,13 +55,33 @@ enum LedgerEntryType : std::uint16_t
#pragma push_macro("LEDGER_ENTRY")
#undef LEDGER_ENTRY
#pragma push_macro("LEDGER_ENTRY_FIELD")
#undef LEDGER_ENTRY_FIELD
#pragma push_macro("DEFINE_LEDGER_ENTRY_FIELDS")
#undef DEFINE_LEDGER_ENTRY_FIELDS
#pragma push_macro("LEDGER_ENTRIES_BEGIN")
#undef LEDGER_ENTRIES_BEGIN
#pragma push_macro("LEDGER_ENTRIES_END")
#undef LEDGER_ENTRIES_END
#define LEDGER_ENTRIES_BEGIN
#define LEDGER_ENTRIES_END
#define DEFINE_LEDGER_ENTRY_FIELDS(...) ({__VA_ARGS__})
#define LEDGER_ENTRY_FIELD(...) {__VA_ARGS__},
#define LEDGER_ENTRY(tag, value, name, rpcName, fields) tag = value,
#include <xrpl/protocol/detail/ledger_entries.macro>
#undef LEDGER_ENTRY
#pragma pop_macro("LEDGER_ENTRY")
#undef LEDGER_ENTRY_FIELD
#pragma pop_macro("LEDGER_ENTRY_FIELD")
#undef DEFINE_LEDGER_ENTRY_FIELDS
#pragma pop_macro("DEFINE_LEDGER_ENTRY_FIELDS")
#undef LEDGER_ENTRIES_BEGIN
#pragma pop_macro("LEDGER_ENTRIES_BEGIN")
#undef LEDGER_ENTRIES_END
#pragma pop_macro("LEDGER_ENTRIES_END")
//---------------------------------------------------------------------------
/** A special type, matching any ledger entry type.

View File

@@ -368,11 +368,15 @@ using SF_XCHAIN_BRIDGE = TypedField<STXChainBridge>;
#undef UNTYPED_SFIELD
#pragma push_macro("TYPED_SFIELD")
#undef TYPED_SFIELD
#pragma push_macro("ARRAY_SFIELD")
#undef ARRAY_SFIELD
#define UNTYPED_SFIELD(sfName, stiSuffix, fieldValue, ...) \
extern SField const sfName;
#define TYPED_SFIELD(sfName, stiSuffix, fieldValue, ...) \
extern SF_##stiSuffix const sfName;
#define ARRAY_SFIELD(sfName, sfItemName, stiSuffix, fieldValue, ...) \
UNTYPED_SFIELD(sfName, stiSuffix, fieldValue, __VA_ARGS__)
extern SField const sfInvalid;
extern SField const sfGeneric;
@@ -383,6 +387,8 @@ extern SField const sfGeneric;
#pragma pop_macro("TYPED_SFIELD")
#undef UNTYPED_SFIELD
#pragma pop_macro("UNTYPED_SFIELD")
#undef ARRAY_SFIELD
#pragma pop_macro("ARRAY_SFIELD")
} // namespace ripple

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,175 @@
#if !defined(INNER_OBJECT)
#error "undefined macro: INNER_OBJECT"
#endif
#if !defined(FIELDS)
#error "undefined macro: FIELDS"
#endif
#if !defined(FIELD)
#error "undefined macro: FIELD"
#endif
#if !defined(INNER_OBJECT_BEGIN)
#error "undefined macro: INNER_OBJECT_BEGIN"
#endif
#if !defined(INNER_OBJECT_END)
#error "undefined macro: INNER_OBJECT_END"
#endif
INNER_OBJECT_BEGIN
INNER_OBJECT(sfSignerEntry,
FIELDS(
FIELD(sfSignerEntry, sfAccount, soeREQUIRED)
FIELD(sfSignerEntry, sfSignerWeight, soeREQUIRED)
FIELD(sfSignerEntry, sfWalletLocator, soeOPTIONAL)
)
)
INNER_OBJECT(sfSigner,
FIELDS(
FIELD(sfSigner, sfAccount, soeREQUIRED)
FIELD(sfSigner, sfSigningPubKey, soeREQUIRED)
FIELD(sfSigner, sfTxnSignature, soeREQUIRED)
)
)
INNER_OBJECT(sfMajority,
FIELDS(
FIELD(sfMajority, sfAmendment, soeREQUIRED)
FIELD(sfMajority, sfCloseTime, soeREQUIRED)
)
)
INNER_OBJECT(sfDisabledValidator,
FIELDS(
FIELD(sfDisabledValidator, sfPublicKey, soeREQUIRED)
FIELD(sfDisabledValidator, sfFirstLedgerSequence, soeREQUIRED)
)
)
INNER_OBJECT(sfNFToken,
FIELDS(
FIELD(sfNFToken, sfNFTokenID, soeREQUIRED)
FIELD(sfNFToken, sfURI, soeOPTIONAL)
)
)
INNER_OBJECT(sfVoteEntry,
FIELDS(
FIELD(sfVoteEntry, sfAccount, soeREQUIRED)
FIELD(sfVoteEntry, sfTradingFee, soeDEFAULT)
FIELD(sfVoteEntry, sfVoteWeight, soeREQUIRED)
)
)
INNER_OBJECT(sfAuctionSlot,
FIELDS(
FIELD(sfAuctionSlot, sfAccount, soeREQUIRED)
FIELD(sfAuctionSlot, sfExpiration, soeREQUIRED)
FIELD(sfAuctionSlot, sfDiscountedFee, soeDEFAULT)
FIELD(sfAuctionSlot, sfPrice, soeREQUIRED)
FIELD(sfAuctionSlot, sfAuthAccounts, soeOPTIONAL)
)
)
INNER_OBJECT(sfXChainClaimAttestationCollectionElement,
FIELDS(
FIELD(sfXChainClaimAttestationCollectionElement, sfAttestationSignerAccount, soeREQUIRED)
FIELD(sfXChainClaimAttestationCollectionElement, sfPublicKey, soeREQUIRED)
FIELD(sfXChainClaimAttestationCollectionElement, sfSignature, soeREQUIRED)
FIELD(sfXChainClaimAttestationCollectionElement, sfAmount, soeREQUIRED)
FIELD(sfXChainClaimAttestationCollectionElement, sfAccount, soeREQUIRED)
FIELD(sfXChainClaimAttestationCollectionElement, sfAttestationRewardAccount, soeREQUIRED)
FIELD(sfXChainClaimAttestationCollectionElement, sfWasLockingChainSend, soeREQUIRED)
FIELD(sfXChainClaimAttestationCollectionElement, sfXChainClaimID, soeREQUIRED)
FIELD(sfXChainClaimAttestationCollectionElement, sfDestination, soeOPTIONAL)
)
)
INNER_OBJECT(sfXChainCreateAccountAttestationCollectionElement,
FIELDS(
FIELD(sfXChainCreateAccountAttestationCollectionElement, sfAttestationSignerAccount, soeREQUIRED)
FIELD(sfXChainCreateAccountAttestationCollectionElement, sfPublicKey, soeREQUIRED)
FIELD(sfXChainCreateAccountAttestationCollectionElement, sfSignature, soeREQUIRED)
FIELD(sfXChainCreateAccountAttestationCollectionElement, sfAmount, soeREQUIRED)
FIELD(sfXChainCreateAccountAttestationCollectionElement, sfAccount, soeREQUIRED)
FIELD(sfXChainCreateAccountAttestationCollectionElement, sfAttestationRewardAccount, soeREQUIRED)
FIELD(sfXChainCreateAccountAttestationCollectionElement, sfWasLockingChainSend, soeREQUIRED)
FIELD(sfXChainCreateAccountAttestationCollectionElement, sfXChainAccountCreateCount, soeREQUIRED)
FIELD(sfXChainCreateAccountAttestationCollectionElement, sfDestination, soeREQUIRED)
FIELD(sfXChainCreateAccountAttestationCollectionElement, sfSignatureReward, soeREQUIRED)
)
)
INNER_OBJECT(sfXChainClaimProofSig,
FIELDS(
FIELD(sfXChainClaimProofSig, sfAttestationSignerAccount, soeREQUIRED)
FIELD(sfXChainClaimProofSig, sfPublicKey, soeREQUIRED)
FIELD(sfXChainClaimProofSig, sfAmount, soeREQUIRED)
FIELD(sfXChainClaimProofSig, sfAttestationRewardAccount, soeREQUIRED)
FIELD(sfXChainClaimProofSig, sfWasLockingChainSend, soeREQUIRED)
FIELD(sfXChainClaimProofSig, sfDestination, soeOPTIONAL)
)
)
INNER_OBJECT(sfXChainCreateAccountProofSig,
FIELDS(
FIELD(sfXChainCreateAccountProofSig, sfAttestationSignerAccount, soeREQUIRED)
FIELD(sfXChainCreateAccountProofSig, sfPublicKey, soeREQUIRED)
FIELD(sfXChainCreateAccountProofSig, sfAmount, soeREQUIRED)
FIELD(sfXChainCreateAccountProofSig, sfSignatureReward, soeREQUIRED)
FIELD(sfXChainCreateAccountProofSig, sfAttestationRewardAccount, soeREQUIRED)
FIELD(sfXChainCreateAccountProofSig, sfWasLockingChainSend, soeREQUIRED)
FIELD(sfXChainCreateAccountProofSig, sfDestination, soeREQUIRED)
)
)
INNER_OBJECT(sfAuthAccount,
FIELDS(
FIELD(sfAuthAccount, sfAccount, soeREQUIRED)
)
)
INNER_OBJECT(sfPriceData,
FIELDS(
FIELD(sfPriceData, sfBaseAsset, soeREQUIRED)
FIELD(sfPriceData, sfQuoteAsset, soeREQUIRED)
FIELD(sfPriceData, sfAssetPrice, soeOPTIONAL)
FIELD(sfPriceData, sfScale, soeDEFAULT)
)
)
INNER_OBJECT(sfCredential,
FIELDS(
FIELD(sfCredential, sfIssuer, soeREQUIRED)
FIELD(sfCredential, sfCredentialType, soeREQUIRED)
)
)
INNER_OBJECT(sfPermission,
FIELDS(
FIELD(sfPermission, sfPermissionValue, soeREQUIRED)
)
)
INNER_OBJECT(sfBatchSigner,
FIELDS(
FIELD(sfBatchSigner, sfAccount, soeREQUIRED)
FIELD(sfBatchSigner, sfSigningPubKey, soeOPTIONAL)
FIELD(sfBatchSigner, sfTxnSignature, soeOPTIONAL)
FIELD(sfBatchSigner, sfSigners, soeOPTIONAL)
)
)
INNER_OBJECT(sfBook,
FIELDS(
FIELD(sfBook, sfBookDirectory, soeREQUIRED)
FIELD(sfBook, sfBookNode, soeREQUIRED)
)
)
INNER_OBJECT_END

View File

@@ -21,6 +21,22 @@
#error "undefined macro: LEDGER_ENTRY"
#endif
#if !defined(LEDGER_ENTRY_FIELD)
#error "undefined macro: LEDGER_ENTRY_FIELD"
#endif
#if !defined(DEFINE_LEDGER_ENTRY_FIELDS)
#error "undefined macro: DEFINE_LEDGER_ENTRY_FIELDS"
#endif
#if !defined(LEDGER_ENTRIES_BEGIN)
#error "undefined macro: LEDGER_ENTRIES_BEGIN"
#endif
#if !defined(LEDGER_ENTRIES_END)
#error "undefined macro: LEDGER_ENTRIES_END"
#endif
#ifndef LEDGER_ENTRY_DUPLICATE
// The EXPAND macro is needed for Windows
// https://stackoverflow.com/questions/5134523/msvc-doesnt-expand-va-args-correctly
@@ -32,6 +48,8 @@
#define LEDGER_ENTRY_DUPLICATE(...) EXPAND(LEDGER_ENTRY(__VA_ARGS__))
#endif
LEDGER_ENTRIES_BEGIN
/**
* These objects are listed in order of increasing ledger type ID.
* There are many gaps between these IDs.
@@ -42,50 +60,50 @@
\sa keylet::nftoffer
*/
LEDGER_ENTRY(ltNFTOKEN_OFFER, 0x0037, NFTokenOffer, nft_offer, ({
{sfOwner, soeREQUIRED},
{sfNFTokenID, soeREQUIRED},
{sfAmount, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfNFTokenOfferNode, soeREQUIRED},
{sfDestination, soeOPTIONAL},
{sfExpiration, soeOPTIONAL},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
}))
LEDGER_ENTRY(ltNFTOKEN_OFFER, 0x0037, NFTokenOffer, nft_offer, DEFINE_LEDGER_ENTRY_FIELDS(
LEDGER_ENTRY_FIELD(sfOwner, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfNFTokenID, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfAmount, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfOwnerNode, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfNFTokenOfferNode, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfDestination, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfExpiration, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfPreviousTxnID, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnLgrSeq, soeREQUIRED)
))
/** A ledger object which describes a check.
\sa keylet::check
*/
LEDGER_ENTRY(ltCHECK, 0x0043, Check, check, ({
{sfAccount, soeREQUIRED},
{sfDestination, soeREQUIRED},
{sfSendMax, soeREQUIRED},
{sfSequence, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfDestinationNode, soeREQUIRED},
{sfExpiration, soeOPTIONAL},
{sfInvoiceID, soeOPTIONAL},
{sfSourceTag, soeOPTIONAL},
{sfDestinationTag, soeOPTIONAL},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
}))
LEDGER_ENTRY(ltCHECK, 0x0043, Check, check, DEFINE_LEDGER_ENTRY_FIELDS(
LEDGER_ENTRY_FIELD(sfAccount, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfDestination, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfSendMax, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfSequence, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfOwnerNode, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfDestinationNode, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfExpiration, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfInvoiceID, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfSourceTag, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfDestinationTag, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfPreviousTxnID, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnLgrSeq, soeREQUIRED)
))
/** The ledger object which tracks the DID.
\sa keylet::did
*/
LEDGER_ENTRY(ltDID, 0x0049, DID, did, ({
{sfAccount, soeREQUIRED},
{sfDIDDocument, soeOPTIONAL},
{sfURI, soeOPTIONAL},
{sfData, soeOPTIONAL},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
}))
LEDGER_ENTRY(ltDID, 0x0049, DID, did, DEFINE_LEDGER_ENTRY_FIELDS(
LEDGER_ENTRY_FIELD(sfAccount, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfDIDDocument, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfURI, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfData, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfOwnerNode, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnID, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnLgrSeq, soeREQUIRED)
))
/** The ledger object which tracks the current negative UNL state.
@@ -93,25 +111,25 @@ LEDGER_ENTRY(ltDID, 0x0049, DID, did, ({
\sa keylet::negativeUNL
*/
LEDGER_ENTRY(ltNEGATIVE_UNL, 0x004e, NegativeUNL, nunl, ({
{sfDisabledValidators, soeOPTIONAL},
{sfValidatorToDisable, soeOPTIONAL},
{sfValidatorToReEnable, soeOPTIONAL},
{sfPreviousTxnID, soeOPTIONAL},
{sfPreviousTxnLgrSeq, soeOPTIONAL},
}))
LEDGER_ENTRY(ltNEGATIVE_UNL, 0x004e, NegativeUNL, nunl, DEFINE_LEDGER_ENTRY_FIELDS(
LEDGER_ENTRY_FIELD(sfDisabledValidators, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfValidatorToDisable, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfValidatorToReEnable, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfPreviousTxnID, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfPreviousTxnLgrSeq, soeOPTIONAL)
))
/** A ledger object which contains a list of NFTs
\sa keylet::nftpage_min, keylet::nftpage_max, keylet::nftpage
*/
LEDGER_ENTRY(ltNFTOKEN_PAGE, 0x0050, NFTokenPage, nft_page, ({
{sfPreviousPageMin, soeOPTIONAL},
{sfNextPageMin, soeOPTIONAL},
{sfNFTokens, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
}))
LEDGER_ENTRY(ltNFTOKEN_PAGE, 0x0050, NFTokenPage, nft_page, DEFINE_LEDGER_ENTRY_FIELDS(
LEDGER_ENTRY_FIELD(sfPreviousPageMin, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfNextPageMin, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfNFTokens, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnID, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnLgrSeq, soeREQUIRED)
))
/** A ledger object which contains a signer list for an account.
@@ -119,77 +137,77 @@ LEDGER_ENTRY(ltNFTOKEN_PAGE, 0x0050, NFTokenPage, nft_page, ({
*/
// All fields are soeREQUIRED because there is always a SignerEntries.
// If there are no SignerEntries the node is deleted.
LEDGER_ENTRY(ltSIGNER_LIST, 0x0053, SignerList, signer_list, ({
{sfOwnerNode, soeREQUIRED},
{sfSignerQuorum, soeREQUIRED},
{sfSignerEntries, soeREQUIRED},
{sfSignerListID, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
}))
LEDGER_ENTRY(ltSIGNER_LIST, 0x0053, SignerList, signer_list, DEFINE_LEDGER_ENTRY_FIELDS(
LEDGER_ENTRY_FIELD(sfOwnerNode, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfSignerQuorum, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfSignerEntries, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfSignerListID, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnID, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnLgrSeq, soeREQUIRED)
))
/** A ledger object which describes a ticket.
\sa keylet::ticket
*/
LEDGER_ENTRY(ltTICKET, 0x0054, Ticket, ticket, ({
{sfAccount, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfTicketSequence, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
}))
LEDGER_ENTRY(ltTICKET, 0x0054, Ticket, ticket, DEFINE_LEDGER_ENTRY_FIELDS(
LEDGER_ENTRY_FIELD(sfAccount, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfOwnerNode, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfTicketSequence, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnID, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnLgrSeq, soeREQUIRED)
))
/** A ledger object which describes an account.
\sa keylet::account
*/
LEDGER_ENTRY(ltACCOUNT_ROOT, 0x0061, AccountRoot, account, ({
{sfAccount, soeREQUIRED},
{sfSequence, soeREQUIRED},
{sfBalance, soeREQUIRED},
{sfOwnerCount, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfAccountTxnID, soeOPTIONAL},
{sfRegularKey, soeOPTIONAL},
{sfEmailHash, soeOPTIONAL},
{sfWalletLocator, soeOPTIONAL},
{sfWalletSize, soeOPTIONAL},
{sfMessageKey, soeOPTIONAL},
{sfTransferRate, soeOPTIONAL},
{sfDomain, soeOPTIONAL},
{sfTickSize, soeOPTIONAL},
{sfTicketCount, soeOPTIONAL},
{sfNFTokenMinter, soeOPTIONAL},
{sfMintedNFTokens, soeDEFAULT},
{sfBurnedNFTokens, soeDEFAULT},
{sfFirstNFTokenSequence, soeOPTIONAL},
{sfAMMID, soeOPTIONAL}, // pseudo-account designator
{sfVaultID, soeOPTIONAL}, // pseudo-account designator
}))
LEDGER_ENTRY(ltACCOUNT_ROOT, 0x0061, AccountRoot, account, DEFINE_LEDGER_ENTRY_FIELDS(
LEDGER_ENTRY_FIELD(sfAccount, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfSequence, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfBalance, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfOwnerCount, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnID, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnLgrSeq, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfAccountTxnID, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfRegularKey, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfEmailHash, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfWalletLocator, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfWalletSize, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfMessageKey, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfTransferRate, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfDomain, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfTickSize, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfTicketCount, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfNFTokenMinter, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfMintedNFTokens, soeDEFAULT)
LEDGER_ENTRY_FIELD(sfBurnedNFTokens, soeDEFAULT)
LEDGER_ENTRY_FIELD(sfFirstNFTokenSequence, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfAMMID, soeOPTIONAL) // pseudo-account designator
LEDGER_ENTRY_FIELD(sfVaultID, soeOPTIONAL) // pseudo-account designator
))
/** A ledger object which contains a list of object identifiers.
\sa keylet::page, keylet::quality, keylet::book, keylet::next and
keylet::ownerDir
*/
LEDGER_ENTRY(ltDIR_NODE, 0x0064, DirectoryNode, directory, ({
{sfOwner, soeOPTIONAL}, // for owner directories
{sfTakerPaysCurrency, soeOPTIONAL}, // order book directories
{sfTakerPaysIssuer, soeOPTIONAL}, // order book directories
{sfTakerGetsCurrency, soeOPTIONAL}, // order book directories
{sfTakerGetsIssuer, soeOPTIONAL}, // order book directories
{sfExchangeRate, soeOPTIONAL}, // order book directories
{sfIndexes, soeREQUIRED},
{sfRootIndex, soeREQUIRED},
{sfIndexNext, soeOPTIONAL},
{sfIndexPrevious, soeOPTIONAL},
{sfNFTokenID, soeOPTIONAL},
{sfPreviousTxnID, soeOPTIONAL},
{sfPreviousTxnLgrSeq, soeOPTIONAL},
{sfDomainID, soeOPTIONAL}
}))
LEDGER_ENTRY(ltDIR_NODE, 0x0064, DirectoryNode, directory, DEFINE_LEDGER_ENTRY_FIELDS(
LEDGER_ENTRY_FIELD(sfOwner, soeOPTIONAL) // for owner directories
LEDGER_ENTRY_FIELD(sfTakerPaysCurrency, soeOPTIONAL) // order book directories
LEDGER_ENTRY_FIELD(sfTakerPaysIssuer, soeOPTIONAL) // order book directories
LEDGER_ENTRY_FIELD(sfTakerGetsCurrency, soeOPTIONAL) // order book directories
LEDGER_ENTRY_FIELD(sfTakerGetsIssuer, soeOPTIONAL) // order book directories
LEDGER_ENTRY_FIELD(sfExchangeRate, soeOPTIONAL) // order book directories
LEDGER_ENTRY_FIELD(sfIndexes, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfRootIndex, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfIndexNext, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfIndexPrevious, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfNFTokenID, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfPreviousTxnID, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfPreviousTxnLgrSeq, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfDomainID, soeOPTIONAL)
))
/** The ledger object which lists details about amendments on the network.
@@ -197,12 +215,12 @@ LEDGER_ENTRY(ltDIR_NODE, 0x0064, DirectoryNode, directory, ({
\sa keylet::amendments
*/
LEDGER_ENTRY(ltAMENDMENTS, 0x0066, Amendments, amendments, ({
{sfAmendments, soeOPTIONAL}, // Enabled
{sfMajorities, soeOPTIONAL},
{sfPreviousTxnID, soeOPTIONAL},
{sfPreviousTxnLgrSeq, soeOPTIONAL},
}))
LEDGER_ENTRY(ltAMENDMENTS, 0x0066, Amendments, amendments, DEFINE_LEDGER_ENTRY_FIELDS(
LEDGER_ENTRY_FIELD(sfAmendments, soeOPTIONAL) // Enabled
LEDGER_ENTRY_FIELD(sfMajorities, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfPreviousTxnID, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfPreviousTxnLgrSeq, soeOPTIONAL)
))
/** A ledger object that contains a list of ledger hashes.
@@ -212,76 +230,76 @@ LEDGER_ENTRY(ltAMENDMENTS, 0x0066, Amendments, amendments, ({
\sa keylet::skip
*/
LEDGER_ENTRY(ltLEDGER_HASHES, 0x0068, LedgerHashes, hashes, ({
{sfFirstLedgerSequence, soeOPTIONAL},
{sfLastLedgerSequence, soeOPTIONAL},
{sfHashes, soeREQUIRED},
}))
LEDGER_ENTRY(ltLEDGER_HASHES, 0x0068, LedgerHashes, hashes, DEFINE_LEDGER_ENTRY_FIELDS(
LEDGER_ENTRY_FIELD(sfFirstLedgerSequence, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfLastLedgerSequence, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfHashes, soeREQUIRED)
))
/** The ledger object which lists details about sidechains.
\sa keylet::bridge
*/
LEDGER_ENTRY(ltBRIDGE, 0x0069, Bridge, bridge, ({
{sfAccount, soeREQUIRED},
{sfSignatureReward, soeREQUIRED},
{sfMinAccountCreateAmount, soeOPTIONAL},
{sfXChainBridge, soeREQUIRED},
{sfXChainClaimID, soeREQUIRED},
{sfXChainAccountCreateCount, soeREQUIRED},
{sfXChainAccountClaimCount, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
}))
LEDGER_ENTRY(ltBRIDGE, 0x0069, Bridge, bridge, DEFINE_LEDGER_ENTRY_FIELDS(
LEDGER_ENTRY_FIELD(sfAccount, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfSignatureReward, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfMinAccountCreateAmount, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfXChainBridge, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfXChainClaimID, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfXChainAccountCreateCount, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfXChainAccountClaimCount, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfOwnerNode, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnID, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnLgrSeq, soeREQUIRED)
))
/** A ledger object which describes an offer on the DEX.
\sa keylet::offer
*/
LEDGER_ENTRY(ltOFFER, 0x006f, Offer, offer, ({
{sfAccount, soeREQUIRED},
{sfSequence, soeREQUIRED},
{sfTakerPays, soeREQUIRED},
{sfTakerGets, soeREQUIRED},
{sfBookDirectory, soeREQUIRED},
{sfBookNode, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfExpiration, soeOPTIONAL},
{sfDomainID, soeOPTIONAL},
{sfAdditionalBooks, soeOPTIONAL},
}))
LEDGER_ENTRY(ltOFFER, 0x006f, Offer, offer, DEFINE_LEDGER_ENTRY_FIELDS(
LEDGER_ENTRY_FIELD(sfAccount, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfSequence, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfTakerPays, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfTakerGets, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfBookDirectory, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfBookNode, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfOwnerNode, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnID, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnLgrSeq, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfExpiration, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfDomainID, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfAdditionalBooks, soeOPTIONAL)
))
/** A ledger object which describes a deposit preauthorization.
\sa keylet::depositPreauth
*/
LEDGER_ENTRY_DUPLICATE(ltDEPOSIT_PREAUTH, 0x0070, DepositPreauth, deposit_preauth, ({
{sfAccount, soeREQUIRED},
{sfAuthorize, soeOPTIONAL},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfAuthorizeCredentials, soeOPTIONAL},
}))
LEDGER_ENTRY_DUPLICATE(ltDEPOSIT_PREAUTH, 0x0070, DepositPreauth, deposit_preauth, DEFINE_LEDGER_ENTRY_FIELDS(
LEDGER_ENTRY_FIELD(sfAccount, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfAuthorize, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfOwnerNode, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnID, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnLgrSeq, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfAuthorizeCredentials, soeOPTIONAL)
))
/** A claim id for a cross chain transaction.
\sa keylet::xChainClaimID
*/
LEDGER_ENTRY(ltXCHAIN_OWNED_CLAIM_ID, 0x0071, XChainOwnedClaimID, xchain_owned_claim_id, ({
{sfAccount, soeREQUIRED},
{sfXChainBridge, soeREQUIRED},
{sfXChainClaimID, soeREQUIRED},
{sfOtherChainSource, soeREQUIRED},
{sfXChainClaimAttestations, soeREQUIRED},
{sfSignatureReward, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
}))
LEDGER_ENTRY(ltXCHAIN_OWNED_CLAIM_ID, 0x0071, XChainOwnedClaimID, xchain_owned_claim_id, DEFINE_LEDGER_ENTRY_FIELDS(
LEDGER_ENTRY_FIELD(sfAccount, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfXChainBridge, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfXChainClaimID, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfOtherChainSource, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfXChainClaimAttestations, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfSignatureReward, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfOwnerNode, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnID, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnLgrSeq, soeREQUIRED)
))
/** A ledger object which describes a bidirectional trust line.
@@ -289,19 +307,19 @@ LEDGER_ENTRY(ltXCHAIN_OWNED_CLAIM_ID, 0x0071, XChainOwnedClaimID, xchain_owned_c
\sa keylet::line
*/
LEDGER_ENTRY(ltRIPPLE_STATE, 0x0072, RippleState, state, ({
{sfBalance, soeREQUIRED},
{sfLowLimit, soeREQUIRED},
{sfHighLimit, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfLowNode, soeOPTIONAL},
{sfLowQualityIn, soeOPTIONAL},
{sfLowQualityOut, soeOPTIONAL},
{sfHighNode, soeOPTIONAL},
{sfHighQualityIn, soeOPTIONAL},
{sfHighQualityOut, soeOPTIONAL},
}))
LEDGER_ENTRY(ltRIPPLE_STATE, 0x0072, RippleState, state, DEFINE_LEDGER_ENTRY_FIELDS(
LEDGER_ENTRY_FIELD(sfBalance, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfLowLimit, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfHighLimit, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnID, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnLgrSeq, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfLowNode, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfLowQualityIn, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfLowQualityOut, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfHighNode, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfHighQualityIn, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfHighQualityOut, soeOPTIONAL)
))
/** The ledger object which lists the network's fee settings.
@@ -309,201 +327,202 @@ LEDGER_ENTRY(ltRIPPLE_STATE, 0x0072, RippleState, state, ({
\sa keylet::fees
*/
LEDGER_ENTRY(ltFEE_SETTINGS, 0x0073, FeeSettings, fee, ({
LEDGER_ENTRY(ltFEE_SETTINGS, 0x0073, FeeSettings, fee, DEFINE_LEDGER_ENTRY_FIELDS(
// Old version uses raw numbers
{sfBaseFee, soeOPTIONAL},
{sfReferenceFeeUnits, soeOPTIONAL},
{sfReserveBase, soeOPTIONAL},
{sfReserveIncrement, soeOPTIONAL},
LEDGER_ENTRY_FIELD(sfBaseFee, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfReferenceFeeUnits, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfReserveBase, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfReserveIncrement, soeOPTIONAL)
// New version uses Amounts
{sfBaseFeeDrops, soeOPTIONAL},
{sfReserveBaseDrops, soeOPTIONAL},
{sfReserveIncrementDrops, soeOPTIONAL},
{sfPreviousTxnID, soeOPTIONAL},
{sfPreviousTxnLgrSeq, soeOPTIONAL},
}))
LEDGER_ENTRY_FIELD(sfBaseFeeDrops, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfReserveBaseDrops, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfReserveIncrementDrops, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfPreviousTxnID, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfPreviousTxnLgrSeq, soeOPTIONAL)
))
/** A claim id for a cross chain create account transaction.
\sa keylet::xChainCreateAccountClaimID
*/
LEDGER_ENTRY(ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID, 0x0074, XChainOwnedCreateAccountClaimID, xchain_owned_create_account_claim_id, ({
{sfAccount, soeREQUIRED},
{sfXChainBridge, soeREQUIRED},
{sfXChainAccountCreateCount, soeREQUIRED},
{sfXChainCreateAccountAttestations, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
}))
LEDGER_ENTRY(ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID, 0x0074, XChainOwnedCreateAccountClaimID, xchain_owned_create_account_claim_id, DEFINE_LEDGER_ENTRY_FIELDS(
LEDGER_ENTRY_FIELD(sfAccount, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfXChainBridge, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfXChainAccountCreateCount, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfXChainCreateAccountAttestations, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfOwnerNode, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnID, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnLgrSeq, soeREQUIRED)
))
/** A ledger object describing a single escrow.
\sa keylet::escrow
*/
LEDGER_ENTRY(ltESCROW, 0x0075, Escrow, escrow, ({
{sfAccount, soeREQUIRED},
{sfDestination, soeREQUIRED},
{sfAmount, soeREQUIRED},
{sfCondition, soeOPTIONAL},
{sfCancelAfter, soeOPTIONAL},
{sfFinishAfter, soeOPTIONAL},
{sfSourceTag, soeOPTIONAL},
{sfDestinationTag, soeOPTIONAL},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfDestinationNode, soeOPTIONAL},
{sfTransferRate, soeOPTIONAL},
{sfIssuerNode, soeOPTIONAL},
}))
LEDGER_ENTRY(ltESCROW, 0x0075, Escrow, escrow, DEFINE_LEDGER_ENTRY_FIELDS(
LEDGER_ENTRY_FIELD(sfAccount, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfDestination, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfAmount, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfCondition, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfCancelAfter, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfFinishAfter, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfSourceTag, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfDestinationTag, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfOwnerNode, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnID, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnLgrSeq, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfDestinationNode, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfTransferRate, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfIssuerNode, soeOPTIONAL)
))
/** A ledger object describing a single unidirectional XRP payment channel.
\sa keylet::payChan
*/
LEDGER_ENTRY(ltPAYCHAN, 0x0078, PayChannel, payment_channel, ({
{sfAccount, soeREQUIRED},
{sfDestination, soeREQUIRED},
{sfAmount, soeREQUIRED},
{sfBalance, soeREQUIRED},
{sfPublicKey, soeREQUIRED},
{sfSettleDelay, soeREQUIRED},
{sfExpiration, soeOPTIONAL},
{sfCancelAfter, soeOPTIONAL},
{sfSourceTag, soeOPTIONAL},
{sfDestinationTag, soeOPTIONAL},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfDestinationNode, soeOPTIONAL},
}))
LEDGER_ENTRY(ltPAYCHAN, 0x0078, PayChannel, payment_channel, DEFINE_LEDGER_ENTRY_FIELDS(
LEDGER_ENTRY_FIELD(sfAccount, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfDestination, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfAmount, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfBalance, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPublicKey, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfSettleDelay, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfExpiration, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfCancelAfter, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfSourceTag, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfDestinationTag, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfOwnerNode, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnID, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnLgrSeq, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfDestinationNode, soeOPTIONAL)
))
/** The ledger object which tracks the AMM.
\sa keylet::amm
*/
LEDGER_ENTRY(ltAMM, 0x0079, AMM, amm, ({
{sfAccount, soeREQUIRED},
{sfTradingFee, soeDEFAULT},
{sfVoteSlots, soeOPTIONAL},
{sfAuctionSlot, soeOPTIONAL},
{sfLPTokenBalance, soeREQUIRED},
{sfAsset, soeREQUIRED},
{sfAsset2, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeOPTIONAL},
{sfPreviousTxnLgrSeq, soeOPTIONAL},
}))
LEDGER_ENTRY(ltAMM, 0x0079, AMM, amm, DEFINE_LEDGER_ENTRY_FIELDS(
LEDGER_ENTRY_FIELD(sfAccount, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfTradingFee, soeDEFAULT)
LEDGER_ENTRY_FIELD(sfVoteSlots, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfAuctionSlot, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfLPTokenBalance, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfAsset, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfAsset2, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfOwnerNode, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnID, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfPreviousTxnLgrSeq, soeOPTIONAL)
))
/** A ledger object which tracks MPTokenIssuance
\sa keylet::mptIssuance
*/
LEDGER_ENTRY(ltMPTOKEN_ISSUANCE, 0x007e, MPTokenIssuance, mpt_issuance, ({
{sfIssuer, soeREQUIRED},
{sfSequence, soeREQUIRED},
{sfTransferFee, soeDEFAULT},
{sfOwnerNode, soeREQUIRED},
{sfAssetScale, soeDEFAULT},
{sfMaximumAmount, soeOPTIONAL},
{sfOutstandingAmount, soeREQUIRED},
{sfLockedAmount, soeOPTIONAL},
{sfMPTokenMetadata, soeOPTIONAL},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfDomainID, soeOPTIONAL},
}))
LEDGER_ENTRY(ltMPTOKEN_ISSUANCE, 0x007e, MPTokenIssuance, mpt_issuance, DEFINE_LEDGER_ENTRY_FIELDS(
LEDGER_ENTRY_FIELD(sfIssuer, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfSequence, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfTransferFee, soeDEFAULT)
LEDGER_ENTRY_FIELD(sfOwnerNode, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfAssetScale, soeDEFAULT)
LEDGER_ENTRY_FIELD(sfMaximumAmount, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfOutstandingAmount, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfLockedAmount, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfMPTokenMetadata, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfPreviousTxnID, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnLgrSeq, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfDomainID, soeOPTIONAL)
))
/** A ledger object which tracks MPToken
\sa keylet::mptoken
*/
LEDGER_ENTRY(ltMPTOKEN, 0x007f, MPToken, mptoken, ({
{sfAccount, soeREQUIRED},
{sfMPTokenIssuanceID, soeREQUIRED},
{sfMPTAmount, soeDEFAULT},
{sfLockedAmount, soeOPTIONAL},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
}))
LEDGER_ENTRY(ltMPTOKEN, 0x007f, MPToken, mptoken, DEFINE_LEDGER_ENTRY_FIELDS(
LEDGER_ENTRY_FIELD(sfAccount, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfMPTokenIssuanceID, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfMPTAmount, soeDEFAULT)
LEDGER_ENTRY_FIELD(sfLockedAmount, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfOwnerNode, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnID, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnLgrSeq, soeREQUIRED)
))
/** A ledger object which tracks Oracle
\sa keylet::oracle
*/
LEDGER_ENTRY(ltORACLE, 0x0080, Oracle, oracle, ({
{sfOwner, soeREQUIRED},
{sfProvider, soeREQUIRED},
{sfPriceDataSeries, soeREQUIRED},
{sfAssetClass, soeREQUIRED},
{sfLastUpdateTime, soeREQUIRED},
{sfURI, soeOPTIONAL},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
}))
LEDGER_ENTRY(ltORACLE, 0x0080, Oracle, oracle, DEFINE_LEDGER_ENTRY_FIELDS(
LEDGER_ENTRY_FIELD(sfOwner, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfProvider, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPriceDataSeries, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfAssetClass, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfLastUpdateTime, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfURI, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfOwnerNode, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnID, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnLgrSeq, soeREQUIRED)
))
/** A ledger object which tracks Credential
\sa keylet::credential
*/
LEDGER_ENTRY(ltCREDENTIAL, 0x0081, Credential, credential, ({
{sfSubject, soeREQUIRED},
{sfIssuer, soeREQUIRED},
{sfCredentialType, soeREQUIRED},
{sfExpiration, soeOPTIONAL},
{sfURI, soeOPTIONAL},
{sfIssuerNode, soeREQUIRED},
{sfSubjectNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
}))
LEDGER_ENTRY(ltCREDENTIAL, 0x0081, Credential, credential, DEFINE_LEDGER_ENTRY_FIELDS(
LEDGER_ENTRY_FIELD(sfSubject, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfIssuer, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfCredentialType, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfExpiration, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfURI, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfIssuerNode, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfSubjectNode, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnID, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnLgrSeq, soeREQUIRED)
))
/** A ledger object which tracks PermissionedDomain
\sa keylet::permissionedDomain
*/
LEDGER_ENTRY(ltPERMISSIONED_DOMAIN, 0x0082, PermissionedDomain, permissioned_domain, ({
{sfOwner, soeREQUIRED},
{sfSequence, soeREQUIRED},
{sfAcceptedCredentials, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
}))
LEDGER_ENTRY(ltPERMISSIONED_DOMAIN, 0x0082, PermissionedDomain, permissioned_domain, DEFINE_LEDGER_ENTRY_FIELDS(
LEDGER_ENTRY_FIELD(sfOwner, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfSequence, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfAcceptedCredentials, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfOwnerNode, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnID, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnLgrSeq, soeREQUIRED)
))
/** A ledger object representing permissions an account has delegated to another account.
\sa keylet::delegate
*/
LEDGER_ENTRY(ltDELEGATE, 0x0083, Delegate, delegate, ({
{sfAccount, soeREQUIRED},
{sfAuthorize, soeREQUIRED},
{sfPermissions, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
}))
LEDGER_ENTRY(ltDELEGATE, 0x0083, Delegate, delegate, DEFINE_LEDGER_ENTRY_FIELDS(
LEDGER_ENTRY_FIELD(sfAccount, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfAuthorize, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPermissions, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfOwnerNode, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnID, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnLgrSeq, soeREQUIRED)
))
/** A ledger object representing a single asset vault.
\sa keylet::mptoken
*/
LEDGER_ENTRY(ltVAULT, 0x0084, Vault, vault, ({
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfSequence, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfOwner, soeREQUIRED},
{sfAccount, soeREQUIRED},
{sfData, soeOPTIONAL},
{sfAsset, soeREQUIRED},
{sfAssetsTotal, soeREQUIRED},
{sfAssetsAvailable, soeREQUIRED},
{sfAssetsMaximum, soeDEFAULT},
{sfLossUnrealized, soeREQUIRED},
{sfShareMPTID, soeREQUIRED},
{sfWithdrawalPolicy, soeREQUIRED},
LEDGER_ENTRY(ltVAULT, 0x0084, Vault, vault, DEFINE_LEDGER_ENTRY_FIELDS(
LEDGER_ENTRY_FIELD(sfPreviousTxnID, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfPreviousTxnLgrSeq, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfSequence, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfOwnerNode, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfOwner, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfAccount, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfData, soeOPTIONAL)
LEDGER_ENTRY_FIELD(sfAsset, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfAssetsTotal, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfAssetsAvailable, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfAssetsMaximum, soeDEFAULT)
LEDGER_ENTRY_FIELD(sfLossUnrealized, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfShareMPTID, soeREQUIRED)
LEDGER_ENTRY_FIELD(sfWithdrawalPolicy, soeREQUIRED)
// no SharesTotal ever (use MPTIssuance.sfOutstandingAmount)
// no PermissionedDomainID ever (use MPTIssuance.sfDomainID)
}))
))
#undef EXPAND
#undef LEDGER_ENTRY_DUPLICATE
LEDGER_ENTRIES_END

View File

@@ -23,6 +23,9 @@
#if !defined(TYPED_SFIELD)
#error "undefined macro: TYPED_SFIELD"
#endif
#if !defined(ARRAY_SFIELD)
#error "undefined macro: ARRAY_SFIELD"
#endif
// untyped
UNTYPED_SFIELD(sfLedgerEntry, LEDGERENTRY, 257)
@@ -366,33 +369,33 @@ UNTYPED_SFIELD(sfBook, OBJECT, 36)
// array of objects (common)
// ARRAY/1 is reserved for end of array
// sfSigningAccounts has never been used.
//UNTYPED_SFIELD(sfSigningAccounts, ARRAY, 2)
UNTYPED_SFIELD(sfSigners, ARRAY, 3, SField::sMD_Default, SField::notSigning)
UNTYPED_SFIELD(sfSignerEntries, ARRAY, 4)
UNTYPED_SFIELD(sfTemplate, ARRAY, 5)
UNTYPED_SFIELD(sfNecessary, ARRAY, 6)
UNTYPED_SFIELD(sfSufficient, ARRAY, 7)
UNTYPED_SFIELD(sfAffectedNodes, ARRAY, 8)
UNTYPED_SFIELD(sfMemos, ARRAY, 9)
UNTYPED_SFIELD(sfNFTokens, ARRAY, 10)
UNTYPED_SFIELD(sfHooks, ARRAY, 11)
UNTYPED_SFIELD(sfVoteSlots, ARRAY, 12)
UNTYPED_SFIELD(sfAdditionalBooks, ARRAY, 13)
//UNTYPED_SFIELD(sfSigningAccounts, sfInvalid, ARRAY, 2)
ARRAY_SFIELD(sfSigners, sfSigner, ARRAY, 3, SField::sMD_Default, SField::notSigning)
ARRAY_SFIELD(sfSignerEntries, sfSignerEntry, ARRAY, 4)
ARRAY_SFIELD(sfTemplate, sfInvalid, ARRAY, 5)
ARRAY_SFIELD(sfNecessary, sfInvalid, ARRAY, 6)
ARRAY_SFIELD(sfSufficient, sfInvalid, ARRAY, 7)
ARRAY_SFIELD(sfAffectedNodes, sfInvalid, ARRAY, 8)
ARRAY_SFIELD(sfMemos, sfInvalid, ARRAY, 9)
ARRAY_SFIELD(sfNFTokens, sfNFToken, ARRAY, 10)
ARRAY_SFIELD(sfHooks, sfInvalid, ARRAY, 11)
ARRAY_SFIELD(sfVoteSlots, sfVoteEntry, ARRAY, 12)
ARRAY_SFIELD(sfAdditionalBooks, sfInvalid, ARRAY, 13)
// array of objects (uncommon)
UNTYPED_SFIELD(sfMajorities, ARRAY, 16)
UNTYPED_SFIELD(sfDisabledValidators, ARRAY, 17)
UNTYPED_SFIELD(sfHookExecutions, ARRAY, 18)
UNTYPED_SFIELD(sfHookParameters, ARRAY, 19)
UNTYPED_SFIELD(sfHookGrants, ARRAY, 20)
UNTYPED_SFIELD(sfXChainClaimAttestations, ARRAY, 21)
UNTYPED_SFIELD(sfXChainCreateAccountAttestations, ARRAY, 22)
ARRAY_SFIELD(sfMajorities, sfMajority, ARRAY, 16)
ARRAY_SFIELD(sfDisabledValidators, sfDisabledValidator, ARRAY, 17)
ARRAY_SFIELD(sfHookExecutions, sfInvalid, ARRAY, 18)
ARRAY_SFIELD(sfHookParameters, sfInvalid, ARRAY, 19)
ARRAY_SFIELD(sfHookGrants, sfInvalid, ARRAY, 20)
ARRAY_SFIELD(sfXChainClaimAttestations, sfInvalid, ARRAY, 21)
ARRAY_SFIELD(sfXChainCreateAccountAttestations, sfInvalid, ARRAY, 22)
// 23 unused
UNTYPED_SFIELD(sfPriceDataSeries, ARRAY, 24)
UNTYPED_SFIELD(sfAuthAccounts, ARRAY, 25)
UNTYPED_SFIELD(sfAuthorizeCredentials, ARRAY, 26)
UNTYPED_SFIELD(sfUnauthorizeCredentials, ARRAY, 27)
UNTYPED_SFIELD(sfAcceptedCredentials, ARRAY, 28)
UNTYPED_SFIELD(sfPermissions, ARRAY, 29)
UNTYPED_SFIELD(sfRawTransactions, ARRAY, 30)
UNTYPED_SFIELD(sfBatchSigners, ARRAY, 31, SField::sMD_Default, SField::notSigning)
ARRAY_SFIELD(sfPriceDataSeries, sfPriceData, ARRAY, 24)
ARRAY_SFIELD(sfAuthAccounts, sfAuthAccount, ARRAY, 25)
ARRAY_SFIELD(sfAuthorizeCredentials, sfInvalid, ARRAY, 26)
ARRAY_SFIELD(sfUnauthorizeCredentials, sfInvalid, ARRAY, 27)
ARRAY_SFIELD(sfAcceptedCredentials, sfInvalid, ARRAY, 28)
ARRAY_SFIELD(sfPermissions, sfPermission, ARRAY, 29)
ARRAY_SFIELD(sfRawTransactions, sfInvalid, ARRAY, 30)
ARRAY_SFIELD(sfBatchSigners, sfBatchSigner, ARRAY, 31, SField::sMD_Default, SField::notSigning)

View File

@@ -717,7 +717,19 @@ JSS(write_load); // out: GetCounts
#undef LEDGER_ENTRY
#pragma push_macro("LEDGER_ENTRY_DUPLICATE")
#undef LEDGER_ENTRY_DUPLICATE
#pragma push_macro("LEDGER_ENTRY_FIELD")
#undef LEDGER_ENTRY_FIELD
#pragma push_macro("DEFINE_LEDGER_ENTRY_FIELDS")
#undef DEFINE_LEDGER_ENTRY_FIELDS
#pragma push_macro("LEDGER_ENTRIES_BEGIN")
#undef LEDGER_ENTRIES_BEGIN
#pragma push_macro("LEDGER_ENTRIES_END")
#undef LEDGER_ENTRIES_END
#define LEDGER_ENTRIES_BEGIN
#define LEDGER_ENTRIES_END
#define DEFINE_LEDGER_ENTRY_FIELDS(...) ({__VA_ARGS__})
#define LEDGER_ENTRY_FIELD(...) {__VA_ARGS__},
#define LEDGER_ENTRY(tag, value, name, rpcName, fields) \
JSS(name); \
JSS(rpcName);
@@ -730,6 +742,14 @@ JSS(write_load); // out: GetCounts
#pragma pop_macro("LEDGER_ENTRY")
#undef LEDGER_ENTRY_DUPLICATE
#pragma pop_macro("LEDGER_ENTRY_DUPLICATE")
#undef LEDGER_ENTRY_FIELD
#pragma pop_macro("LEDGER_ENTRY_FIELD")
#undef DEFINE_LEDGER_ENTRY_FIELDS
#pragma pop_macro("DEFINE_LEDGER_ENTRY_FIELDS")
#undef LEDGER_ENTRIES_BEGIN
#pragma pop_macro("LEDGER_ENTRIES_BEGIN")
#undef LEDGER_ENTRIES_END
#pragma pop_macro("LEDGER_ENTRIES_END")
#undef JSS

View File

@@ -132,7 +132,7 @@ getBookBase(Book const& book)
book.out.account);
// Return with quality 0.
auto k = keylet::quality({ltDIR_NODE, index}, 0);
auto k = keylet::quality({index}, 0);
return k.key;
}
@@ -180,10 +180,10 @@ makeMptID(std::uint32_t sequence, AccountID const& account)
namespace keylet {
Keylet
TypedKeylet<ltACCOUNT_ROOT>
account(AccountID const& id) noexcept
{
return Keylet{ltACCOUNT_ROOT, indexHash(LedgerNameSpace::ACCOUNT, id)};
return TypedKeylet<ltACCOUNT_ROOT>{indexHash(LedgerNameSpace::ACCOUNT, id)};
}
Keylet
@@ -192,55 +192,53 @@ child(uint256 const& key) noexcept
return {ltCHILD, key};
}
Keylet const&
TypedKeylet<ltLEDGER_HASHES> const&
skip() noexcept
{
static Keylet const ret{
ltLEDGER_HASHES, indexHash(LedgerNameSpace::SKIP_LIST)};
static TypedKeylet<ltLEDGER_HASHES> const ret{
indexHash(LedgerNameSpace::SKIP_LIST)};
return ret;
}
Keylet
TypedKeylet<ltLEDGER_HASHES>
skip(LedgerIndex ledger) noexcept
{
return {
ltLEDGER_HASHES,
indexHash(
LedgerNameSpace::SKIP_LIST,
std::uint32_t(static_cast<std::uint32_t>(ledger) >> 16))};
return {indexHash(
LedgerNameSpace::SKIP_LIST,
std::uint32_t(static_cast<std::uint32_t>(ledger) >> 16))};
}
Keylet const&
TypedKeylet<ltAMENDMENTS> const&
amendments() noexcept
{
static Keylet const ret{
ltAMENDMENTS, indexHash(LedgerNameSpace::AMENDMENTS)};
static TypedKeylet<ltAMENDMENTS> const ret{
indexHash(LedgerNameSpace::AMENDMENTS)};
return ret;
}
Keylet const&
TypedKeylet<ltFEE_SETTINGS> const&
fees() noexcept
{
static Keylet const ret{
ltFEE_SETTINGS, indexHash(LedgerNameSpace::FEE_SETTINGS)};
static TypedKeylet<ltFEE_SETTINGS> const ret{
indexHash(LedgerNameSpace::FEE_SETTINGS)};
return ret;
}
Keylet const&
TypedKeylet<ltNEGATIVE_UNL> const&
negativeUNL() noexcept
{
static Keylet const ret{
ltNEGATIVE_UNL, indexHash(LedgerNameSpace::NEGATIVE_UNL)};
static TypedKeylet<ltNEGATIVE_UNL> const ret{
indexHash(LedgerNameSpace::NEGATIVE_UNL)};
return ret;
}
Keylet
TypedKeylet<ltDIR_NODE>
book_t::operator()(Book const& b) const
{
return {ltDIR_NODE, getBookBase(b)};
return {getBookBase(b)};
}
Keylet
TypedKeylet<ltRIPPLE_STATE>
line(
AccountID const& id0,
AccountID const& id1,
@@ -261,27 +259,22 @@ line(
// two accounts (smallest then largest) and hash them in that order:
auto const accounts = std::minmax(id0, id1);
return {
ltRIPPLE_STATE,
indexHash(
LedgerNameSpace::TRUST_LINE,
accounts.first,
accounts.second,
currency)};
return {indexHash(
LedgerNameSpace::TRUST_LINE,
accounts.first,
accounts.second,
currency)};
}
Keylet
TypedKeylet<ltOFFER>
offer(AccountID const& id, std::uint32_t seq) noexcept
{
return {ltOFFER, indexHash(LedgerNameSpace::OFFER, id, seq)};
return {indexHash(LedgerNameSpace::OFFER, id, seq)};
}
Keylet
quality(Keylet const& k, std::uint64_t q) noexcept
TypedKeylet<ltDIR_NODE>
quality(TypedKeylet<ltDIR_NODE> const& k, std::uint64_t q) noexcept
{
XRPL_ASSERT(
k.type == ltDIR_NODE, "ripple::keylet::quality : valid input type");
// Indexes are stored in big endian format: they print as hex as stored.
// Most significant bytes are first and the least significant bytes
// represent adjacent entries. We place the quality, in big endian format,
@@ -292,62 +285,57 @@ quality(Keylet const& k, std::uint64_t q) noexcept
// FIXME This is ugly and we can and should do better...
((std::uint64_t*)x.end())[-1] = boost::endian::native_to_big(q);
return {ltDIR_NODE, x};
return {x};
}
Keylet
next_t::operator()(Keylet const& k) const
TypedKeylet<ltDIR_NODE>
next_t::operator()(TypedKeylet<ltDIR_NODE> const& k) const
{
XRPL_ASSERT(
k.type == ltDIR_NODE,
"ripple::keylet::next_t::operator() : valid input type");
return {ltDIR_NODE, getQualityNext(k.key)};
return {getQualityNext(k.key)};
}
Keylet
TypedKeylet<ltTICKET>
ticket_t::operator()(AccountID const& id, std::uint32_t ticketSeq) const
{
return {ltTICKET, getTicketIndex(id, ticketSeq)};
return {getTicketIndex(id, ticketSeq)};
}
Keylet
TypedKeylet<ltTICKET>
ticket_t::operator()(AccountID const& id, SeqProxy ticketSeq) const
{
return {ltTICKET, getTicketIndex(id, ticketSeq)};
return {getTicketIndex(id, ticketSeq)};
}
// This function is presently static, since it's never accessed from anywhere
// else. If we ever support multiple pages of signer lists, this would be the
// keylet used to locate them.
static Keylet
static TypedKeylet<ltSIGNER_LIST>
signers(AccountID const& account, std::uint32_t page) noexcept
{
return {
ltSIGNER_LIST, indexHash(LedgerNameSpace::SIGNER_LIST, account, page)};
return {indexHash(LedgerNameSpace::SIGNER_LIST, account, page)};
}
Keylet
TypedKeylet<ltSIGNER_LIST>
signers(AccountID const& account) noexcept
{
return signers(account, 0);
}
Keylet
TypedKeylet<ltCHECK>
check(AccountID const& id, std::uint32_t seq) noexcept
{
return {ltCHECK, indexHash(LedgerNameSpace::CHECK, id, seq)};
return TypedKeylet<ltCHECK>{indexHash(LedgerNameSpace::CHECK, id, seq)};
}
Keylet
TypedKeylet<ltDEPOSIT_PREAUTH>
depositPreauth(AccountID const& owner, AccountID const& preauthorized) noexcept
{
return {
ltDEPOSIT_PREAUTH,
return TypedKeylet<ltDEPOSIT_PREAUTH>{
indexHash(LedgerNameSpace::DEPOSIT_PREAUTH, owner, preauthorized)};
}
// Credentials should be sorted here, use credentials::makeSorted
Keylet
TypedKeylet<ltDEPOSIT_PREAUTH>
depositPreauth(
AccountID const& owner,
std::set<std::pair<AccountID, Slice>> const& authCreds) noexcept
@@ -357,8 +345,7 @@ depositPreauth(
for (auto const& o : authCreds)
hashes.emplace_back(sha512Half(o.first, o.second));
return {
ltDEPOSIT_PREAUTH,
return TypedKeylet<ltDEPOSIT_PREAUTH>{
indexHash(LedgerNameSpace::DEPOSIT_PREAUTH_CREDENTIALS, owner, hashes)};
}
@@ -367,82 +354,82 @@ depositPreauth(
Keylet
unchecked(uint256 const& key) noexcept
{
return {ltANY, key};
return Keylet{ltANY, key};
}
Keylet
TypedKeylet<ltDIR_NODE>
ownerDir(AccountID const& id) noexcept
{
return {ltDIR_NODE, indexHash(LedgerNameSpace::OWNER_DIR, id)};
return TypedKeylet<ltDIR_NODE>{indexHash(LedgerNameSpace::OWNER_DIR, id)};
}
Keylet
TypedKeylet<ltDIR_NODE>
page(uint256 const& key, std::uint64_t index) noexcept
{
if (index == 0)
return {ltDIR_NODE, key};
return TypedKeylet<ltDIR_NODE>{key};
return {ltDIR_NODE, indexHash(LedgerNameSpace::DIR_NODE, key, index)};
return TypedKeylet<ltDIR_NODE>{
indexHash(LedgerNameSpace::DIR_NODE, key, index)};
}
Keylet
TypedKeylet<ltESCROW>
escrow(AccountID const& src, std::uint32_t seq) noexcept
{
return {ltESCROW, indexHash(LedgerNameSpace::ESCROW, src, seq)};
return TypedKeylet<ltESCROW>{indexHash(LedgerNameSpace::ESCROW, src, seq)};
}
Keylet
TypedKeylet<ltPAYCHAN>
payChan(AccountID const& src, AccountID const& dst, std::uint32_t seq) noexcept
{
return {
ltPAYCHAN,
return TypedKeylet<ltPAYCHAN>{
indexHash(LedgerNameSpace::XRP_PAYMENT_CHANNEL, src, dst, seq)};
}
Keylet
TypedKeylet<ltNFTOKEN_PAGE>
nftpage_min(AccountID const& owner)
{
std::array<std::uint8_t, 32> buf{};
std::memcpy(buf.data(), owner.data(), owner.size());
return {ltNFTOKEN_PAGE, uint256{buf}};
return TypedKeylet<ltNFTOKEN_PAGE>{uint256{buf}};
}
Keylet
TypedKeylet<ltNFTOKEN_PAGE>
nftpage_max(AccountID const& owner)
{
uint256 id = nft::pageMask;
std::memcpy(id.data(), owner.data(), owner.size());
return {ltNFTOKEN_PAGE, id};
return TypedKeylet<ltNFTOKEN_PAGE>{id};
}
Keylet
nftpage(Keylet const& k, uint256 const& token)
TypedKeylet<ltNFTOKEN_PAGE>
nftpage(TypedKeylet<ltNFTOKEN_PAGE> const& k, uint256 const& token)
{
XRPL_ASSERT(
k.type == ltNFTOKEN_PAGE, "ripple::keylet::nftpage : valid input type");
return {ltNFTOKEN_PAGE, (k.key & ~nft::pageMask) + (token & nft::pageMask)};
return {(k.key & ~nft::pageMask) + (token & nft::pageMask)};
}
Keylet
TypedKeylet<ltNFTOKEN_OFFER>
nftoffer(AccountID const& owner, std::uint32_t seq)
{
return {
ltNFTOKEN_OFFER, indexHash(LedgerNameSpace::NFTOKEN_OFFER, owner, seq)};
return TypedKeylet<ltNFTOKEN_OFFER>{
indexHash(LedgerNameSpace::NFTOKEN_OFFER, owner, seq)};
}
Keylet
TypedKeylet<ltDIR_NODE>
nft_buys(uint256 const& id) noexcept
{
return {ltDIR_NODE, indexHash(LedgerNameSpace::NFTOKEN_BUY_OFFERS, id)};
return TypedKeylet<ltDIR_NODE>{
indexHash(LedgerNameSpace::NFTOKEN_BUY_OFFERS, id)};
}
Keylet
TypedKeylet<ltDIR_NODE>
nft_sells(uint256 const& id) noexcept
{
return {ltDIR_NODE, indexHash(LedgerNameSpace::NFTOKEN_SELL_OFFERS, id)};
return TypedKeylet<ltDIR_NODE>{
indexHash(LedgerNameSpace::NFTOKEN_SELL_OFFERS, id)};
}
Keylet
TypedKeylet<ltAMM>
amm(Asset const& issue1, Asset const& issue2) noexcept
{
auto const& [minI, maxI] =
@@ -455,129 +442,120 @@ amm(Asset const& issue1, Asset const& issue2) noexcept
maxI.currency));
}
Keylet
TypedKeylet<ltAMM>
amm(uint256 const& id) noexcept
{
return {ltAMM, id};
return TypedKeylet<ltAMM>{id};
}
Keylet
TypedKeylet<ltDELEGATE>
delegate(AccountID const& account, AccountID const& authorizedAccount) noexcept
{
return {
ltDELEGATE,
return TypedKeylet<ltDELEGATE>{
indexHash(LedgerNameSpace::DELEGATE, account, authorizedAccount)};
}
Keylet
TypedKeylet<ltBRIDGE>
bridge(STXChainBridge const& bridge, STXChainBridge::ChainType chainType)
{
// A door account can support multiple bridges. On the locking chain
// there can only be one bridge per lockingChainCurrency. On the issuing
// chain there can only be one bridge per issuingChainCurrency.
auto const& issue = bridge.issue(chainType);
return {
ltBRIDGE,
indexHash(
LedgerNameSpace::BRIDGE, bridge.door(chainType), issue.currency)};
return TypedKeylet<ltBRIDGE>{indexHash(
LedgerNameSpace::BRIDGE, bridge.door(chainType), issue.currency)};
}
Keylet
TypedKeylet<ltXCHAIN_OWNED_CLAIM_ID>
xChainClaimID(STXChainBridge const& bridge, std::uint64_t seq)
{
return {
ltXCHAIN_OWNED_CLAIM_ID,
indexHash(
LedgerNameSpace::XCHAIN_CLAIM_ID,
bridge.lockingChainDoor(),
bridge.lockingChainIssue(),
bridge.issuingChainDoor(),
bridge.issuingChainIssue(),
seq)};
return TypedKeylet<ltXCHAIN_OWNED_CLAIM_ID>{indexHash(
LedgerNameSpace::XCHAIN_CLAIM_ID,
bridge.lockingChainDoor(),
bridge.lockingChainIssue(),
bridge.issuingChainDoor(),
bridge.issuingChainIssue(),
seq)};
}
Keylet
TypedKeylet<ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID>
xChainCreateAccountClaimID(STXChainBridge const& bridge, std::uint64_t seq)
{
return {
ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID,
indexHash(
LedgerNameSpace::XCHAIN_CREATE_ACCOUNT_CLAIM_ID,
bridge.lockingChainDoor(),
bridge.lockingChainIssue(),
bridge.issuingChainDoor(),
bridge.issuingChainIssue(),
seq)};
return TypedKeylet<ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID>{indexHash(
LedgerNameSpace::XCHAIN_CREATE_ACCOUNT_CLAIM_ID,
bridge.lockingChainDoor(),
bridge.lockingChainIssue(),
bridge.issuingChainDoor(),
bridge.issuingChainIssue(),
seq)};
}
Keylet
TypedKeylet<ltDID>
did(AccountID const& account) noexcept
{
return {ltDID, indexHash(LedgerNameSpace::DID, account)};
return TypedKeylet<ltDID>{indexHash(LedgerNameSpace::DID, account)};
}
Keylet
TypedKeylet<ltORACLE>
oracle(AccountID const& account, std::uint32_t const& documentID) noexcept
{
return {ltORACLE, indexHash(LedgerNameSpace::ORACLE, account, documentID)};
return TypedKeylet<ltORACLE>{
indexHash(LedgerNameSpace::ORACLE, account, documentID)};
}
Keylet
TypedKeylet<ltMPTOKEN_ISSUANCE>
mptIssuance(std::uint32_t seq, AccountID const& issuer) noexcept
{
return mptIssuance(makeMptID(seq, issuer));
}
Keylet
TypedKeylet<ltMPTOKEN_ISSUANCE>
mptIssuance(MPTID const& issuanceID) noexcept
{
return {
ltMPTOKEN_ISSUANCE,
return TypedKeylet<ltMPTOKEN_ISSUANCE>{
indexHash(LedgerNameSpace::MPTOKEN_ISSUANCE, issuanceID)};
}
Keylet
TypedKeylet<ltMPTOKEN>
mptoken(MPTID const& issuanceID, AccountID const& holder) noexcept
{
return mptoken(mptIssuance(issuanceID).key, holder);
}
Keylet
TypedKeylet<ltMPTOKEN>
mptoken(uint256 const& issuanceKey, AccountID const& holder) noexcept
{
return {
ltMPTOKEN, indexHash(LedgerNameSpace::MPTOKEN, issuanceKey, holder)};
return TypedKeylet<ltMPTOKEN>{
indexHash(LedgerNameSpace::MPTOKEN, issuanceKey, holder)};
}
Keylet
TypedKeylet<ltCREDENTIAL>
credential(
AccountID const& subject,
AccountID const& issuer,
Slice const& credType) noexcept
{
return {
ltCREDENTIAL,
return TypedKeylet<ltCREDENTIAL>{
indexHash(LedgerNameSpace::CREDENTIAL, subject, issuer, credType)};
}
Keylet
TypedKeylet<ltVAULT>
vault(AccountID const& owner, std::uint32_t seq) noexcept
{
return vault(indexHash(LedgerNameSpace::VAULT, owner, seq));
}
Keylet
TypedKeylet<ltPERMISSIONED_DOMAIN>
permissionedDomain(AccountID const& account, std::uint32_t seq) noexcept
{
return {
ltPERMISSIONED_DOMAIN,
return TypedKeylet<ltPERMISSIONED_DOMAIN>{
indexHash(LedgerNameSpace::PERMISSIONED_DOMAIN, account, seq)};
}
Keylet
TypedKeylet<ltPERMISSIONED_DOMAIN>
permissionedDomain(uint256 const& domainID) noexcept
{
return {ltPERMISSIONED_DOMAIN, domainID};
return TypedKeylet<ltPERMISSIONED_DOMAIN>{domainID};
}
} // namespace keylet

View File

@@ -39,8 +39,20 @@ LedgerFormats::LedgerFormats()
#undef UNWRAP
#pragma push_macro("LEDGER_ENTRY")
#undef LEDGER_ENTRY
#pragma push_macro("LEDGER_ENTRY_FIELD")
#undef LEDGER_ENTRY_FIELD
#pragma push_macro("DEFINE_LEDGER_ENTRY_FIELDS")
#undef DEFINE_LEDGER_ENTRY_FIELDS
#pragma push_macro("LEDGER_ENTRIES_BEGIN")
#undef LEDGER_ENTRIES_BEGIN
#pragma push_macro("LEDGER_ENTRIES_END")
#undef LEDGER_ENTRIES_END
#define LEDGER_ENTRIES_BEGIN
#define LEDGER_ENTRIES_END
#define DEFINE_LEDGER_ENTRY_FIELDS(...) ({__VA_ARGS__})
#define UNWRAP(...) __VA_ARGS__
#define LEDGER_ENTRY_FIELD(...) {__VA_ARGS__},
#define LEDGER_ENTRY(tag, value, name, rpcName, fields) \
add(jss::name, tag, UNWRAP fields, commonFields);
@@ -48,6 +60,14 @@ LedgerFormats::LedgerFormats()
#undef LEDGER_ENTRY
#pragma pop_macro("LEDGER_ENTRY")
#undef LEDGER_ENTRY_FIELD
#pragma pop_macro("LEDGER_ENTRY_FIELD")
#undef DEFINE_LEDGER_ENTRY_FIELDS
#pragma pop_macro("DEFINE_LEDGER_ENTRY_FIELDS")
#undef LEDGER_ENTRIES_BEGIN
#pragma pop_macro("LEDGER_ENTRIES_BEGIN")
#undef LEDGER_ENTRIES_END
#pragma pop_macro("LEDGER_ENTRIES_END")
#undef UNWRAP
#pragma pop_macro("UNWRAP")
}

View File

@@ -52,6 +52,8 @@ TypedField<T>::TypedField(private_access_tag_t pat, Args&&... args)
#undef UNTYPED_SFIELD
#pragma push_macro("TYPED_SFIELD")
#undef TYPED_SFIELD
#pragma push_macro("ARRAY_SFIELD")
#undef ARRAY_SFIELD
#define UNTYPED_SFIELD(sfName, stiSuffix, fieldValue, ...) \
SField const sfName( \
@@ -67,6 +69,13 @@ TypedField<T>::TypedField(private_access_tag_t pat, Args&&... args)
fieldValue, \
std::string_view(#sfName).substr(2).data(), \
##__VA_ARGS__);
#define ARRAY_SFIELD(sfName, sfItemName, stiSuffix, fieldValue, ...) \
SField const sfName( \
access, \
STI_##stiSuffix, \
fieldValue, \
std::string_view(#sfName).substr(2).data(), \
##__VA_ARGS__);
// SFields which, for historical reasons, do not follow naming conventions.
SField const sfInvalid(access, -1);
@@ -82,6 +91,8 @@ SField const sfIndex(access, STI_UINT256, 258, "index");
#pragma pop_macro("TYPED_SFIELD")
#undef UNTYPED_SFIELD
#pragma pop_macro("UNTYPED_SFIELD")
#undef ARRAY_SFIELD
#pragma pop_macro("ARRAY_SFIELD")
SField::SField(
private_access_tag_t,

View File

@@ -265,8 +265,8 @@ MPTTester::forObject(
{
if (!id_)
Throw<std::runtime_error>("MPT has not been created");
auto const key = holder_ ? keylet::mptoken(*id_, holder_->id())
: keylet::mptIssuance(*id_);
auto const key = holder_ ? keylet::mptoken(*id_, holder_->id()).untyped()
: keylet::mptIssuance(*id_).untyped();
if (auto const sle = env_.le(key))
return cb(sle);
return false;

View File

@@ -0,0 +1,142 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2025 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <xrpl/beast/unit_test.h>
#include <xrpl/protocol/STObject.h>
#include <xrpl/protocol/TypedLedgerEntries.h>
namespace ripple {
struct TypedLedgerEntries_test : public beast::unit_test::suite
{
void
testAccessSTArrayProxy()
{
testcase("testAccessSTArrayProxy");
STArray innerArray;
STArrayProxy<InnerObjectType<SFieldNames::field_sfSignerEntry>> array{
&innerArray};
BEAST_EXPECT(array.empty());
auto item = array.createItem();
item.fsfSignerWeight() = 1;
array.push_back(item);
BEAST_EXPECT(array.back().fsfSignerWeight() == 1);
BEAST_EXPECT(array.value().back()[sfSignerWeight] == 1);
BEAST_EXPECT(array.begin()->fsfSignerWeight() == 1);
BEAST_EXPECT(std::distance(array.begin(), array.end()) == 1);
BEAST_EXPECT(array.size() == 1);
BEAST_EXPECT(!array.empty());
BEAST_EXPECT(array.at(0).fsfSignerWeight() == 1);
BEAST_EXPECT(!array.at(1).isValid());
BEAST_EXPECT(array.valid());
BEAST_EXPECT(
!STArrayProxy<LedgerObjectType<ltSIGNER_LIST>>{nullptr}.valid());
}
void
testGet()
{
testcase("testGet");
auto object = std::make_shared<SLE>(ltSIGNER_LIST, uint256{});
STArray signerEntries;
STObject signerEntry{sfSignerEntry};
signerEntry[sfAccount] = AccountID{1};
signerEntry[sfSignerWeight] = 2;
signerEntry[sfWalletLocator] = uint256{3};
signerEntries.emplace_back(signerEntry);
(*object)[sfOwnerNode] = 1UL;
(*object)[sfSignerQuorum] = 2U;
(*object)[sfSignerListID] = 3U;
(*object)[sfPreviousTxnLgrSeq] = 4U;
(*object)[sfPreviousTxnID] = uint256{5};
(*object).setFieldArray(sfSignerEntries, signerEntries);
auto entry = LedgerObjectType<ltSIGNER_LIST>::fromObject(object);
BEAST_EXPECT(entry.fsfOwnerNode() == 1);
BEAST_EXPECT(entry.fsfSignerQuorum() == 2);
BEAST_EXPECT(entry.fsfSignerListID() == 3);
BEAST_EXPECT(entry.fsfPreviousTxnLgrSeq() == 4);
BEAST_EXPECT(entry.fsfPreviousTxnID() == uint256{5});
BEAST_EXPECT(entry.fsfSignerEntries().size() == 1);
BEAST_EXPECT(
entry.fsfSignerEntries()[0].fsfAccount().value() == AccountID{1});
BEAST_EXPECT(entry.fsfSignerEntries()[0].fsfSignerWeight() == 2);
BEAST_EXPECT(
entry.fsfSignerEntries()[0].fsfWalletLocator() == uint256{3});
}
void
testSet()
{
testcase("testSet");
auto new_object = LedgerObjectType<ltSIGNER_LIST>::create(uint256{});
new_object.fsfOwnerNode() = 1;
new_object.fsfSignerQuorum() = 2;
new_object.fsfSignerListID() = 3;
new_object.fsfPreviousTxnLgrSeq() = 4;
new_object.fsfPreviousTxnID() = uint256{5};
auto signerEntry = new_object.fsfSignerEntries().createItem();
signerEntry.fsfAccount() = AccountID{1};
signerEntry.fsfSignerWeight() = 2;
signerEntry.fsfWalletLocator() = uint256{3};
new_object.fsfSignerEntries().push_back(signerEntry);
auto& object = *new_object.getObject();
BEAST_EXPECT(object[sfOwnerNode] == new_object.fsfOwnerNode());
BEAST_EXPECT(object[sfSignerQuorum] == new_object.fsfSignerQuorum());
BEAST_EXPECT(object[sfSignerListID] == new_object.fsfSignerListID());
BEAST_EXPECT(
object[sfPreviousTxnLgrSeq] == new_object.fsfPreviousTxnLgrSeq());
BEAST_EXPECT(object[sfPreviousTxnID] == new_object.fsfPreviousTxnID());
BEAST_EXPECT(
object.getFieldArray(sfSignerEntries).size() ==
new_object.fsfSignerEntries().size());
auto entries = object.getFieldArray(sfSignerEntries);
BEAST_EXPECT(
entries[0][sfAccount] ==
new_object.fsfSignerEntries()[0].fsfAccount());
BEAST_EXPECT(
entries[0][sfSignerWeight] ==
new_object.fsfSignerEntries()[0].fsfSignerWeight());
BEAST_EXPECT(
entries[0][sfWalletLocator] ==
new_object.fsfSignerEntries()[0].fsfWalletLocator());
}
void
run() override
{
testGet();
testSet();
testAccessSTArrayProxy();
}
};
BEAST_DEFINE_TESTSUITE(TypedLedgerEntries, protocol, ripple);
} // namespace ripple

View File

@@ -156,8 +156,7 @@ public:
if (!sleAcct)
return false;
SeqProxy const acctSeq =
SeqProxy::sequence(sleAcct->getFieldU32(sfSequence));
SeqProxy const acctSeq = SeqProxy::sequence(sleAcct.fsfSequence());
SeqProxy const seqProx = txn.getSeqProxy();
if (seqProx.isSeq())

View File

@@ -245,7 +245,7 @@ authorizedDepositPreauth(
return tefINTERNAL; // LCOV_EXCL_LINE
auto [it, ins] =
sorted.emplace((*sleCred)[sfIssuer], (*sleCred)[sfCredentialType]);
sorted.emplace(sleCred.fsfIssuer(), sleCred.fsfCredentialType());
if (!ins)
return tefINTERNAL; // LCOV_EXCL_LINE
lifeExtender.push_back(std::move(sleCred));

View File

@@ -34,10 +34,10 @@ accountInDomain(
return false;
// domain owner is in the domain
if (sleDomain->getAccountID(sfOwner) == account)
if (sleDomain.fsfOwner() == account)
return true;
auto const& credentials = sleDomain->getFieldArray(sfAcceptedCredentials);
auto const& credentials = sleDomain.fsfAcceptedCredentials();
bool const inDomain = std::any_of(
credentials.begin(), credentials.end(), [&](auto const& credential) {
@@ -67,20 +67,19 @@ offerInDomain(
// have any of the following wrong behavior
if (!sleOffer)
return false; // LCOV_EXCL_LINE
if (!sleOffer->isFieldPresent(sfDomainID))
if (!sleOffer.fsfDomainID().has_value())
return false; // LCOV_EXCL_LINE
if (sleOffer->getFieldH256(sfDomainID) != domainID)
if (sleOffer.fsfDomainID() != domainID)
return false; // LCOV_EXCL_LINE
if (sleOffer->isFlag(lsfHybrid) &&
!sleOffer->isFieldPresent(sfAdditionalBooks))
if (sleOffer->isFlag(lsfHybrid) && !sleOffer.fsfAdditionalBooks())
{
JLOG(j.error()) << "Hybrid offer " << offerID
<< " missing AdditionalBooks field";
return false; // LCOV_EXCL_LINE
}
return accountInDomain(view, sleOffer->getAccountID(sfAccount), domainID);
return accountInDomain(view, sleOffer.fsfAccount(), domainID);
}
} // namespace permissioned_dex

View File

@@ -215,14 +215,14 @@ ammAccountHolds(
if (isXRP(issue))
{
if (auto const sle = view.read(keylet::account(ammAccountID)))
return (*sle)[sfBalance];
return sle.fsfBalance();
}
else if (auto const sle = view.read(
keylet::line(ammAccountID, issue.account, issue.currency));
sle &&
!isFrozen(view, ammAccountID, issue.currency, issue.account))
{
auto amount = (*sle)[sfBalance];
auto amount = sle.fsfBalance();
if (ammAccountID > issue.account)
amount.negate();
amount.setIssuer(issue.account);

View File

@@ -104,7 +104,7 @@ public:
ammSle && ammSle->getFieldAmount(sfLPTokenBalance) != beast::zero)
ammLiquidity_.emplace(
ctx.view,
(*ammSle)[sfAccount],
ammSle.fsfAccount(),
getTradingFee(ctx.view, *ammSle, ctx.ammContext.account()),
in,
out,
@@ -1392,7 +1392,7 @@ BookStep<TIn, TOut, TDerived>::check(StrandContext const& ctx) const
auto sle = view.read(keylet::line(*prev, cur, book_.in.currency));
if (!sle)
return terNO_LINE;
if ((*sle)[sfFlags] &
if ((*sle.getObject())[sfFlags] &
((cur > *prev) ? lsfHighNoRipple : lsfLowNoRipple))
return terNO_RIPPLE;
}

View File

@@ -421,7 +421,7 @@ DirectIPaymentStep::check(
if (((*sleSrc)[sfFlags] & lsfRequireAuth) &&
!((*sleLine)[sfFlags] & authField) &&
(*sleLine)[sfBalance] == beast::zero)
sleLine.fsfBalance() == beast::zero)
{
JLOG(j_.warn())
<< "DirectStepI: can't receive IOUs from issuer without auth."

View File

@@ -65,17 +65,18 @@ checkFreeze(
if (view.rules().enabled(fixFrozenLPTokenTransfer))
{
if (auto const sleDst = view.read(keylet::account(dst));
sleDst && sleDst->isFieldPresent(sfAMMID))
sleDst && sleDst.fsfAMMID().has_value())
{
auto const sleAmm = view.read(keylet::amm((*sleDst)[sfAMMID]));
auto const sleAmm =
view.read(keylet::amm(sleDst.fsfAMMID().value()));
if (!sleAmm)
return tecINTERNAL; // LCOV_EXCL_LINE
if (isLPTokenFrozen(
view,
src,
(*sleAmm)[sfAsset].get<Issue>(),
(*sleAmm)[sfAsset2].get<Issue>()))
sleAmm.fsfAsset().get<Issue>(),
sleAmm.fsfAsset2().get<Issue>()))
{
return terNO_LINE;
}

View File

@@ -109,7 +109,7 @@ AMMBid::preclaim(PreclaimContext const& ctx)
return terNO_AMM;
}
auto const lpTokensBalance = (*ammSle)[sfLPTokenBalance];
auto const lpTokensBalance = ammSle.fsfLPTokenBalance();
if (lpTokensBalance == beast::zero)
return tecAMM_EMPTY;

View File

@@ -56,7 +56,7 @@ AMMDelete::preclaim(PreclaimContext const& ctx)
return terNO_AMM;
}
auto const lpTokensBalance = (*ammSle)[sfLPTokenBalance];
auto const lpTokensBalance = ammSle.fsfLPTokenBalance();
if (lpTokensBalance != beast::zero)
return tecAMM_NOT_EMPTY;

View File

@@ -220,7 +220,7 @@ AMMDeposit::preclaim(PreclaimContext const& ctx)
auto balance = [&](auto const& deposit) -> TER {
if (isXRP(deposit))
{
auto const lpIssue = (*ammSle)[sfLPTokenBalance].issue();
auto const lpIssue = ammSle.fsfLPTokenBalance().issue();
// Adjust the reserve if LP doesn't have LPToken trustline
auto const sle = ctx.view.read(
keylet::line(accountID, lpIssue.account, lpIssue.currency));

View File

@@ -61,7 +61,7 @@ CancelCheck::preclaim(PreclaimContext const& ctx)
using duration = NetClock::duration;
using timepoint = NetClock::time_point;
auto const optExpiry = (*sleCheck)[~sfExpiration];
auto const optExpiry = sleCheck.fsfExpiration();
// Expiration is defined in terms of the close time of the parent
// ledger, because we definitively know the time that it closed but
@@ -73,8 +73,8 @@ CancelCheck::preclaim(PreclaimContext const& ctx)
// If the check is not yet expired, then only the creator or the
// destination may cancel the check.
AccountID const acctId{ctx.tx[sfAccount]};
if (acctId != (*sleCheck)[sfAccount] &&
acctId != (*sleCheck)[sfDestination])
if (acctId != sleCheck.fsfAccount() &&
acctId != sleCheck.fsfDestination())
{
JLOG(ctx.j.warn()) << "Check is not expired and canceler is "
"neither check source nor destination.";

View File

@@ -61,7 +61,7 @@ CancelOffer::preclaim(PreclaimContext const& ctx)
if (!sle)
return terNO_ACCOUNT;
if ((*sle)[sfSequence] <= offerSequence)
if (sle.fsfSequence() <= offerSequence)
{
JLOG(ctx.j.trace()) << "Malformed transaction: "
<< "Sequence " << offerSequence << " is invalid.";

View File

@@ -33,6 +33,7 @@
#include <xrpl/protocol/STAmount.h>
#include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/TypedLedgerEntries.h>
#include <cstdint>
#include <optional>
@@ -170,6 +171,13 @@ public:
virtual std::shared_ptr<SLE const>
read(Keylet const& k) const = 0;
template <LedgerEntryType Type>
ConstLedgerObjectType<Type>
read(TypedKeylet<Type> const& k) const
{
return ConstLedgerObjectType<Type>::fromObject(read(k));
}
// Accounts in a payment are not allowed to use assets acquired during that
// payment. The PaymentSandbox tracks the debits, credits, and owner count
// changes that accounts make during a payment. `balanceHook` adjusts

View File

@@ -34,6 +34,7 @@
#include <xrpl/protocol/Quality.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/TxFlags.h>
#include <xrpl/protocol/TypedLedgerEntries.h>
#include <xrpl/protocol/digest.h>
#include <xrpl/protocol/st.h>
@@ -260,9 +261,9 @@ isFrozen(
if (issuer != account)
{
// Check if the issuer froze the line
sle = view.read(keylet::line(account, issuer, currency));
if (sle &&
sle->isFlag((issuer > account) ? lsfHighFreeze : lsfLowFreeze))
auto sleLine = view.read(keylet::line(account, issuer, currency));
if (sleLine &&
sleLine->isFlag((issuer > account) ? lsfHighFreeze : lsfLowFreeze))
return true;
}
return false;
@@ -320,29 +321,28 @@ isVaultPseudoAccountFrozen(
auto const mptIssuance =
view.read(keylet::mptIssuance(mptShare.getMptID()));
if (mptIssuance == nullptr)
if (mptIssuance.isValid())
return false; // zero MPToken won't block deletion of MPTokenIssuance
auto const issuer = mptIssuance->getAccountID(sfIssuer);
auto const issuer = mptIssuance.fsfIssuer();
auto const mptIssuer = view.read(keylet::account(issuer));
if (mptIssuer == nullptr)
if (mptIssuer.isValid())
{ // LCOV_EXCL_START
UNREACHABLE("ripple::isVaultPseudoAccountFrozen : null MPToken issuer");
return false;
} // LCOV_EXCL_STOP
if (!mptIssuer->isFieldPresent(sfVaultID))
if (!mptIssuer.fsfVaultID().has_value())
return false; // not a Vault pseudo-account, common case
auto const vault =
view.read(keylet::vault(mptIssuer->getFieldH256(sfVaultID)));
if (vault == nullptr)
auto const vault = view.read(keylet::vault(*mptIssuer.fsfVaultID()));
if (vault.isValid())
{ // LCOV_EXCL_START
UNREACHABLE("ripple::isVaultPseudoAccountFrozen : null vault");
return false;
} // LCOV_EXCL_STOP
return isAnyFrozen(view, {issuer, account}, vault->at(sfAsset), depth + 1);
return isAnyFrozen(view, {issuer, account}, vault.fsfAsset(), depth + 1);
}
bool

View File

@@ -937,7 +937,20 @@ chooseLedgerEntryType(Json::Value const& params)
std::tuple<char const*, char const*, LedgerEntryType>>({
#pragma push_macro("LEDGER_ENTRY")
#undef LEDGER_ENTRY
#pragma push_macro("LEDGER_ENTRY_FIELD")
#undef LEDGER_ENTRY_FIELD
#pragma push_macro("DEFINE_LEDGER_ENTRY_FIELDS")
#undef DEFINE_LEDGER_ENTRY_FIELDS
#pragma push_macro("LEDGER_ENTRIES_BEGIN")
#undef LEDGER_ENTRIES_BEGIN
#pragma push_macro("LEDGER_ENTRIES_END")
#undef LEDGER_ENTRIES_END
#define LEDGER_ENTRIES_BEGIN
#define LEDGER_ENTRIES_END
#define DEFINE_LEDGER_ENTRY_FIELDS(...) ({__VA_ARGS__})
#define LEDGER_ENTRY_FIELD(...) {__VA_ARGS__},
#define LEDGER_ENTRY(tag, value, name, rpcName, fields) \
{jss::name, jss::rpcName, tag},
@@ -945,6 +958,14 @@ chooseLedgerEntryType(Json::Value const& params)
#undef LEDGER_ENTRY
#pragma pop_macro("LEDGER_ENTRY")
#undef LEDGER_ENTRY_FIELD
#pragma pop_macro("LEDGER_ENTRY_FIELD")
#undef DEFINE_LEDGER_ENTRY_FIELDS
#pragma pop_macro("DEFINE_LEDGER_ENTRY_FIELDS")
#undef LEDGER_ENTRIES_BEGIN
#pragma pop_macro("LEDGER_ENTRIES_BEGIN")
#undef LEDGER_ENTRIES_END
#pragma pop_macro("LEDGER_ENTRIES_END")
});
auto const& p = params[jss::type];

View File

@@ -244,7 +244,7 @@ doLedgerGrpc(RPC::GRPCContext<org::xrpl::rpc::v1::GetLedgerRequest>& context)
auto sle = std::make_shared<SLE>(SerialIter{blob}, k);
if (!sle->isFieldPresent(sfOwner))
{
auto bookBase = keylet::quality({ltDIR_NODE, k}, 0);
auto bookBase = keylet::quality({k}, 0);
if (!inBase && inDesired)
{
auto firstBook =

View File

@@ -95,7 +95,8 @@ doVaultInfo(RPC::JsonContext& context)
auto const sleVault = lpLedger->read(keylet::vault(uNodeIndex));
auto const sleIssuance = sleVault == nullptr //
? nullptr
: lpLedger->read(keylet::mptIssuance(sleVault->at(sfShareMPTID)));
: lpLedger->read(
keylet::mptIssuance(sleVault->at(sfShareMPTID)).untyped());
if (!sleVault || !sleIssuance)
{
jvResult[jss::error] = "entryNotFound";