Strongly typed ledger objects support

This commit is contained in:
JCW
2025-07-03 15:41:41 +01:00
parent b113190563
commit 02da6b2508
11 changed files with 1560 additions and 340 deletions

View File

@@ -55,13 +55,33 @@ enum LedgerEntryType : std::uint16_t
#pragma push_macro("LEDGER_ENTRY") #pragma push_macro("LEDGER_ENTRY")
#undef 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, #define LEDGER_ENTRY(tag, value, name, rpcName, fields) tag = value,
#include <xrpl/protocol/detail/ledger_entries.macro> #include <xrpl/protocol/detail/ledger_entries.macro>
#undef LEDGER_ENTRY #undef LEDGER_ENTRY
#pragma pop_macro("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. /** A special type, matching any ledger entry type.

View File

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

View File

@@ -0,0 +1,812 @@
//------------------------------------------------------------------------------
/*
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.
*/
//==============================================================================
#ifndef TYPED_LEDGER_ENTRIES_H
#define TYPED_LEDGER_ENTRIES_H
#include <xrpl/protocol/LedgerFormats.h>
#include <xrpl/protocol/STArray.h>
#include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/protocol/STNumber.h>
#include <xrpl/protocol/STObject.h>
#include <optional>
namespace ripple {
// This is a proxy that returns a strongly-typed object instead of an STObject
template <typename ProxyType>
class STArrayProxy
{
public:
using value_type = ProxyType;
using size_type = std::size_t;
class iterator
{
public:
using difference_type = std::ptrdiff_t;
using value_type = ProxyType;
using reference = ProxyType;
using iterator_category = std::bidirectional_iterator_tag;
struct pointer
{
ProxyType object_;
ProxyType const*
operator->() const
{
return &object_;
}
ProxyType const&
operator*() const
{
return object_;
}
ProxyType*
operator->()
{
return &object_;
}
ProxyType&
operator*()
{
return object_;
}
};
explicit iterator(STArray::iterator it) : it_(it)
{
}
reference
operator*()
{
return ProxyType::fromObject(*it_);
}
pointer
operator->()
{
return pointer{ProxyType::fromObject(*it_)};
}
iterator&
operator++()
{
++it_;
return *this;
}
iterator
operator++(int)
{
iterator tmp = *this;
++(*this);
return tmp;
}
bool
operator==(iterator const& other) const
{
return it_ == other.it_;
}
bool
operator!=(iterator const& other) const
{
return it_ != other.it_;
}
private:
STArray::iterator it_;
};
explicit STArrayProxy(STArray* array) : array_(array)
{
}
[[nodiscard]] bool
valid() const
{
return array_ != nullptr;
}
explicit
operator bool() const
{
return valid();
}
STArray&
value()
{
return *array_;
}
ProxyType
createItem()
{
return ProxyType::create();
}
void
push_back(ProxyType const& obj)
{
array_->push_back(obj);
}
[[nodiscard]] size_type
size() const
{
return array_ ? array_->size() : 0;
}
[[nodiscard]] bool
empty() const
{
return size() == 0;
}
[[nodiscard]] ProxyType
at(size_type idx) const
{
if (!array_ || idx >= array_->size())
{
return ProxyType::fromObject(nullptr);
}
return ProxyType::fromObject((*array_)[idx]);
}
ProxyType
operator[](size_type idx) const
{
return at(idx);
}
[[nodiscard]] ProxyType
back() const
{
return ProxyType::fromObject(array_->back());
}
[[nodiscard]] iterator
begin() const
{
return array_ ? iterator{array_->begin()}
: iterator{STArray::iterator{}};
}
[[nodiscard]] iterator
end() const
{
return array_ ? iterator{array_->end()} : iterator{STArray::iterator{}};
}
private:
STArray* array_;
};
// We need a way to address each field so that we can map the field names
// to field types
#pragma push_macro("UNTYPED_SFIELD")
#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, ...) field_##sfName,
#define TYPED_SFIELD(sfName, stiSuffix, fieldValue, ...) field_##sfName,
#define ARRAY_SFIELD(sfName, sfItemName, stiSuffix, fieldValue, ...) \
UNTYPED_SFIELD(sfName, stiSuffix, fieldValue, __VA_ARGS__)
enum class SFieldNames {
field_sfInvalid,
#include <xrpl/protocol/detail/sfields.macro>
};
#undef TYPED_SFIELD
#pragma pop_macro("TYPED_SFIELD")
#undef UNTYPED_SFIELD
#pragma pop_macro("UNTYPED_SFIELD")
#undef ARRAY_SFIELD
#pragma pop_macro("ARRAY_SFIELD")
namespace detail {
// This enum defines what an UNTYPED_SFIELD is holding,
// and we only care about objects and arrays
enum class AggregateFieldTypes {
NONE,
OBJECT,
ARRAY,
LEDGERENTRY,
TRANSACTION,
VALIDATION,
METADATA,
PATHSET,
};
// The base case for GetFieldType. We'll define more specialisations for each
// SFieldName so that we can find the field type and the item type if it's
// an array
template <SFieldNames FieldName>
struct GetFieldType
{
constexpr static AggregateFieldTypes Value = AggregateFieldTypes::NONE;
constexpr static SFieldNames ItemField = SFieldNames::field_sfInvalid;
};
// For each field defined in sfields.macro, we will have a template
// specialisation of GetFieldType for it, and each GetFieldType will
// have a static Value member and a static ItemField member
#pragma push_macro("UNTYPED_SFIELD")
#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, ...) \
template <> \
struct GetFieldType<SFieldNames::field_##sfName> \
{ \
constexpr static AggregateFieldTypes Value = \
AggregateFieldTypes::stiSuffix; \
constexpr static SFieldNames ItemField = SFieldNames::field_sfInvalid; \
};
#define TYPED_SFIELD(sfName, stiSuffix, fieldValue, ...)
#define ARRAY_SFIELD(sfName, sfItemName, stiSuffix, fieldValue, ...) \
template <> \
struct GetFieldType<SFieldNames::field_##sfName> \
{ \
constexpr static AggregateFieldTypes Value = \
AggregateFieldTypes::stiSuffix; \
constexpr static SFieldNames ItemField = \
SFieldNames::field_##sfItemName; \
};
#include <xrpl/protocol/detail/sfields.macro>
#undef TYPED_SFIELD
#pragma pop_macro("TYPED_SFIELD")
#undef UNTYPED_SFIELD
#pragma pop_macro("UNTYPED_SFIELD")
#undef ARRAY_SFIELD
#pragma pop_macro("ARRAY_SFIELD")
// We reference those `InnerObjects` in the get function when we define the type
// Because of that, We need to push types defined in inner_objects.macro into an
// array so that we can delay evaluating the types.
// This Pair struct stores a field name and a type
template <SFieldNames FieldName, typename Type>
struct InnerObjectTypePair
{
static constexpr SFieldNames Field = FieldName;
using InnerObjectType = Type;
};
template <typename T>
concept IsInnerObjectTypePair = requires {
std::same_as<decltype(T::Field), SFieldNames>;
typename T::InnerObjectType;
} || std::same_as<T, void>;
// Those `GetInnerObjectStruct` classes iterate through each item in the array,
// and then return the type that the corresponding field name is equal to the
// name we're looking for. It returns void if there's no corresponding field.
template <SFieldNames FieldName, typename Tuple>
struct GetInnerObjectStruct
{
};
template <
SFieldNames FieldName,
IsInnerObjectTypePair Current,
IsInnerObjectTypePair... Pairs>
struct GetInnerObjectStruct<FieldName, std::tuple<Current, Pairs...>>
{
using Struct = std::conditional_t<
Current::Field == FieldName,
typename Current::InnerObjectType,
typename GetInnerObjectStruct<FieldName, std::tuple<Pairs...>>::Struct>;
};
template <SFieldNames FieldName, IsInnerObjectTypePair Current>
struct GetInnerObjectStruct<FieldName, std::tuple<Current, void>>
{
using Struct = std::conditional_t<
Current::Field == FieldName,
typename Current::InnerObjectType,
void>;
};
template <SFieldNames FieldName>
struct GetInnerObjectStruct<FieldName, std::tuple<void>>
{
using Struct = void;
};
// This type returns the value directly if the field is a typed field.
template <
SFieldNames FieldName,
SFieldNames ItemFieldName,
SOEStyle SOEStyleValue,
AggregateFieldTypes FieldType,
typename InnerObjectTypesArray>
struct GetFieldValue
{
template <typename TFieldType>
static auto
get(STObject& object, TFieldType const& field)
{
return object[field];
}
};
// This type returns an optional value when the field is marked as optional
template <
SFieldNames FieldName,
SFieldNames ItemFieldName,
typename InnerObjectTypesArray>
struct GetFieldValue<
FieldName,
ItemFieldName,
soeOPTIONAL,
AggregateFieldTypes::NONE,
InnerObjectTypesArray>
{
template <typename TFieldType>
static auto
get(STObject& object, TFieldType const& field)
{
return object[~field];
}
};
// This type wraps the STObject value into the corresponding proxy type to
// provide intellisense
template <
SFieldNames FieldName,
SFieldNames ItemFieldName,
SOEStyle SOEStyle,
typename InnerObjectTypesArray>
struct GetFieldValue<
FieldName,
ItemFieldName,
SOEStyle,
AggregateFieldTypes::OBJECT,
InnerObjectTypesArray>
{
using InnerObjectType =
typename GetInnerObjectStruct<FieldName, InnerObjectTypesArray>::Struct;
// If the type is defined in inner_objects.macro, we return the defined type
// otherwise, we return the untyped STObject
template <typename TFieldType>
static std::conditional_t<
!std::is_void_v<InnerObjectType>,
InnerObjectType,
STObject const&>
get(STObject& object, TFieldType const& field)
{
if constexpr (!std::is_void_v<InnerObjectType>)
{
return InnerObjectType::fromObject(
object.getField(field).template downcast<STObject>());
}
else
{
return object.getField(field).template downcast<STObject>();
}
}
};
// This type returns an std::optional when the field is marked as optional.
template <
SFieldNames FieldName,
SFieldNames ItemFieldName,
typename InnerObjectTypesArray>
struct GetFieldValue<
FieldName,
ItemFieldName,
soeOPTIONAL,
AggregateFieldTypes::OBJECT,
InnerObjectTypesArray>
{
using InnerObjectType =
typename GetInnerObjectStruct<FieldName, InnerObjectTypesArray>::Struct;
template <typename TFieldType>
static std::conditional_t<
!std::is_void_v<InnerObjectType>,
std::optional<InnerObjectType>,
STObject const*>
get(STObject& object, TFieldType const& field)
{
if constexpr (!std::is_void_v<InnerObjectType>)
{
if (object.isFieldPresent(field))
{
return InnerObjectType::fromObject(
object.getField(field).template downcast<STObject>());
}
return std::nullopt;
}
else
{
if (object.isFieldPresent(field))
{
return &object.getField(field).template downcast<STObject>();
}
return nullptr;
}
}
};
// This type wraps the STArray value into the strongly-typed array proxy.
template <
SFieldNames FieldName,
SFieldNames ItemFieldName,
SOEStyle Style,
typename InnerObjectTypesArray>
struct GetFieldValue<
FieldName,
ItemFieldName,
Style,
AggregateFieldTypes::ARRAY,
InnerObjectTypesArray>
{
using InnerObjectType =
typename GetInnerObjectStruct<ItemFieldName, InnerObjectTypesArray>::
Struct;
template <typename TFieldType>
static std::conditional_t<
!std::is_void_v<InnerObjectType>,
STArrayProxy<InnerObjectType>,
STArray&>
get(STObject& object, TFieldType const& field)
{
if constexpr (!std::is_void_v<InnerObjectType>)
{
return STArrayProxy<InnerObjectType>{&object.peekFieldArray(field)};
}
else
{
return object.peekFieldArray(field);
}
}
};
// This type returns an std::optional when the field is marked as optional.
template <
SFieldNames FieldName,
SFieldNames ItemFieldName,
typename InnerObjectTypesArray>
struct GetFieldValue<
FieldName,
ItemFieldName,
soeOPTIONAL,
AggregateFieldTypes::ARRAY,
InnerObjectTypesArray>
{
using InnerObjectType =
typename GetInnerObjectStruct<ItemFieldName, InnerObjectTypesArray>::
Struct;
template <typename TFieldType>
static std::conditional_t<
!std::is_void_v<InnerObjectType>,
STArrayProxy<InnerObjectType>,
STArray*>
get(STObject& object, TFieldType const& field)
{
if constexpr (!std::is_void_v<InnerObjectType>)
{
if (object.isFieldPresent(field))
{
return STArrayProxy<InnerObjectType>{
&object.peekFieldArray(field)};
}
return STArrayProxy<InnerObjectType>{nullptr};
}
else
{
if (object.isFieldPresent(field))
{
return &object.peekFieldArray(field);
}
return nullptr;
}
}
};
// We're defining the inner object type array so that we can use it
// in the get function.
#pragma push_macro("INNER_OBJECT")
#pragma push_macro("FIELDS")
#pragma push_macro("FIELD")
#pragma push_macro("INNER_OBJECT_BEGIN")
#pragma push_macro("INNER_OBJECT_END")
#define INNER_OBJECT_BEGIN using InnerObjectTypesArray = std::tuple <
#define INNER_OBJECT_END void > ;
#define FIELDS(...) __VA_ARGS__
#define FIELD(name, field, soeStyle)
#define INNER_OBJECT(name, fields) \
InnerObjectTypePair<SFieldNames::field_##name, struct InnerObject_##name>,
#include <xrpl/protocol/detail/inner_objects.macro>
#pragma pop_macro("INNER_OBJECT")
#pragma pop_macro("FIELDS")
#pragma pop_macro("FIELD")
#pragma pop_macro("INNER_OBJECT_BEGIN")
#pragma pop_macro("INNER_OBJECT_END")
// We're defining each inner object type here.
#pragma push_macro("INNER_OBJECT")
#pragma push_macro("FIELDS")
#pragma push_macro("FIELD")
#pragma push_macro("INNER_OBJECT_BEGIN")
#pragma push_macro("INNER_OBJECT_END")
#define INNER_OBJECT_BEGIN
#define INNER_OBJECT_END
#define FIELDS(...) __VA_ARGS__
#define FIELD(name, field, soeStyle) \
auto f##field() \
{ \
return GetFieldValue< \
SFieldNames::field_##field, \
detail::GetFieldType<SFieldNames::field_##field>::ItemField, \
soeStyle, \
detail::GetFieldType<SFieldNames::field_##field>::Value, \
InnerObjectTypesArray>::get(*getObject(), field); \
}
#define INNER_OBJECT(name, fields) \
struct InnerObject_##name \
{ \
private: \
std::variant<std::shared_ptr<STObject>, STObject*> object_; \
InnerObject_##name(STObject* object) : object_(object) \
{ \
} \
InnerObject_##name(std::shared_ptr<STObject> const& object) \
: object_(object) \
{ \
} \
\
public: \
static constexpr bool IsValidType = true; \
static InnerObject_##name \
fromObject(STObject& object) \
{ \
return InnerObject_##name{&object}; \
} \
static InnerObject_##name \
fromObject(std::shared_ptr<STObject> const& object) \
{ \
return InnerObject_##name{object}; \
} \
static InnerObject_##name \
create() \
{ \
return InnerObject_##name{std::make_shared<STObject>(name)}; \
} \
operator STObject const&() const \
{ \
return *getObject(); \
} \
operator STObject&() \
{ \
return *getObject(); \
} \
STObject* \
getObject() \
{ \
if (std::holds_alternative<std::shared_ptr<STObject>>(object_)) \
{ \
return std::get<std::shared_ptr<STObject>>(object_).get(); \
} \
else \
{ \
return std::get<STObject*>(object_); \
} \
} \
STObject const* \
getObject() const \
{ \
if (std::holds_alternative<std::shared_ptr<STObject>>(object_)) \
{ \
return std::get<std::shared_ptr<STObject>>(object_).get(); \
} \
else \
{ \
return std::get<STObject*>(object_); \
} \
} \
bool \
isValid() const \
{ \
return getObject() != nullptr; \
} \
fields \
};
#include <xrpl/protocol/detail/inner_objects.macro>
// We're defining each ledger entry here.
#pragma pop_macro("INNER_OBJECT")
#pragma pop_macro("FIELDS")
#pragma pop_macro("FIELD")
#pragma pop_macro("INNER_OBJECT_BEGIN")
#pragma pop_macro("INNER_OBJECT_END")
template <LedgerEntryType EntryType>
struct LedgerEntry
{
};
#pragma push_macro("LEDGER_ENTRY")
#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(field, soeStyle) \
using Field_##field##Type = \
decltype(GetFieldValue< \
SFieldNames::field_##field, \
detail::GetFieldType<SFieldNames::field_##field>::ItemField, \
soeStyle, \
detail::GetFieldType<SFieldNames::field_##field>::Value, \
InnerObjectTypesArray>:: \
get(std::declval<STObject&>(), field)); \
Field_##field##Type f##field() \
{ \
return GetFieldValue< \
SFieldNames::field_##field, \
detail::GetFieldType<SFieldNames::field_##field>::ItemField, \
soeStyle, \
detail::GetFieldType<SFieldNames::field_##field>::Value, \
InnerObjectTypesArray>::get(*getObject(), field); \
}
#define LEDGER_ENTRY(tag, value, name, rpcName, fields) \
template <> \
struct LedgerEntry<tag> \
{ \
private: \
using CLS = LedgerEntry<tag>; \
std::variant<std::shared_ptr<STLedgerEntry>, STLedgerEntry*> object_; \
LedgerEntry(STLedgerEntry& object) : object_(&object) \
{ \
} \
LedgerEntry(std::shared_ptr<STLedgerEntry> const& object) \
: object_(object) \
{ \
} \
\
public: \
bool \
isValid() const \
{ \
return getObject() != nullptr; \
} \
static void \
ensureType(STLedgerEntry const& object) \
{ \
if (tag != object.getType()) \
{ \
Throw<std::runtime_error>("Object type mismatch!"); \
} \
} \
STLedgerEntry* \
getObject() \
{ \
if (std::holds_alternative<std::shared_ptr<STLedgerEntry>>( \
object_)) \
{ \
return std::get<std::shared_ptr<STLedgerEntry>>(object_) \
.get(); \
} \
else \
{ \
return std::get<STLedgerEntry*>(object_); \
} \
} \
STLedgerEntry const* \
getObject() const \
{ \
if (std::holds_alternative<std::shared_ptr<STLedgerEntry>>( \
object_)) \
{ \
return std::get<std::shared_ptr<STLedgerEntry>>(object_) \
.get(); \
} \
else \
{ \
return std::get<STLedgerEntry*>(object_); \
} \
} \
static LedgerEntry \
fromObject(STLedgerEntry& object) \
{ \
ensureType(object); \
return LedgerEntry{object}; \
} \
static LedgerEntry \
fromObject(std::shared_ptr<STLedgerEntry> const& object) \
{ \
ensureType(*object); \
return LedgerEntry{object}; \
} \
static LedgerEntry \
create(uint256 const& key) \
{ \
return LedgerEntry{std::make_shared<STLedgerEntry>(tag, key)}; \
} \
fields \
};
#define LEDGER_ENTRY_DUPLICATE(...)
#include <xrpl/protocol/detail/ledger_entries.macro>
#undef LEDGER_ENTRY
#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")
} // namespace detail
template <SFieldNames FieldName>
using InnerObjectType = typename detail::
GetInnerObjectStruct<FieldName, detail::InnerObjectTypesArray>::Struct;
template <LedgerEntryType EntryType>
using LedgerObjectType = detail::LedgerEntry<EntryType>;
} // namespace ripple
#endif // TYPED_LEDGER_ENTRIES_H

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

View File

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

View File

@@ -39,8 +39,20 @@ LedgerFormats::LedgerFormats()
#undef UNWRAP #undef UNWRAP
#pragma push_macro("LEDGER_ENTRY") #pragma push_macro("LEDGER_ENTRY")
#undef 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 UNWRAP(...) __VA_ARGS__
#define LEDGER_ENTRY_FIELD(...) {__VA_ARGS__},
#define LEDGER_ENTRY(tag, value, name, rpcName, fields) \ #define LEDGER_ENTRY(tag, value, name, rpcName, fields) \
add(jss::name, tag, UNWRAP fields, commonFields); add(jss::name, tag, UNWRAP fields, commonFields);
@@ -48,6 +60,14 @@ LedgerFormats::LedgerFormats()
#undef LEDGER_ENTRY #undef LEDGER_ENTRY
#pragma pop_macro("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 #undef UNWRAP
#pragma pop_macro("UNWRAP") #pragma pop_macro("UNWRAP")
} }

View File

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

View File

@@ -0,0 +1,113 @@
//------------------------------------------------------------------------------
/*
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
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();
}
};
BEAST_DEFINE_TESTSUITE(TypedLedgerEntries, protocol, ripple);
} // namespace ripple

View File

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