Files
rippled/include/xrpl/protocol/TxFormats.h
Denis Angell 315d1fdb06 part 3
2026-05-14 06:57:17 +02:00

138 lines
5.6 KiB
C++

#pragma once
#include <xrpl/protocol/KnownFormats.h>
#include <vector>
namespace xrpl {
/** Wire-format identifiers for every XRPL transaction type.
*
* The numeric values are generated by the X-macro expansion of
* `transactions.macro` and are embedded inside signed transaction objects.
* They are therefore **immutable protocol surface**: a validator that
* assigns a different meaning to a given numeric value cannot participate
* in consensus with its peers, which would cause a hard fork.
*
* Deprecated types (`TtNicknameSet`, `TtContract`, `TtSpinalTap`) are
* retained as tombstoned, `[[deprecated]]`-annotated enumerators so that
* their numeric slots can never be accidentally reused by a future
* transaction type — doing so would cause historical ledger data to be
* misclassified.
*
* @warning Do not change any existing enumerator value. Numeric IDs are
* part of the signed binary format and altering them constitutes
* a consensus-breaking protocol change.
*
* @note The language cannot detect duplicate enumerator values at compile
* time; duplicate-ID protection is enforced instead at static-init time
* by `TxFormats::TxFormats()` via `KnownFormats::add()`.
*
* @ingroup protocol
*/
// clang-format off
// Protocol-critical, hundreds of usages
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum TxType : std::uint16_t
{
#pragma push_macro("TRANSACTION")
#undef TRANSACTION
#define TRANSACTION(tag, value, ...) tag = value,
#include <xrpl/protocol/detail/transactions.macro>
#undef TRANSACTION
#pragma pop_macro("TRANSACTION")
/** This transaction type is deprecated; it is retained for historical purposes. */
TtNicknameSet [[deprecated("This transaction type is not supported and should not be used.")]] = 6,
/** This transaction type is deprecated; it is retained for historical purposes. */
TtContract [[deprecated("This transaction type is not supported and should not be used.")]] = 9,
/** This identifier was never used, but the slot is reserved for historical purposes. */
TtSpinalTap [[deprecated("This transaction type is not supported and should not be used.")]] = 11,
/** This transaction type installs a hook. */
TtHookSet [[maybe_unused]] = 22,
};
// clang-format on
/** Singleton registry mapping every XRPL transaction type to its field schema.
*
* `TxFormats` inherits `KnownFormats<TxType, TxFormats>`, which stores one
* `Item` per transaction type. Each `Item` pairs the type's human-readable
* name and `TxType` discriminant with an `SOTemplate` — the ordered list of
* `SOElement` descriptors specifying which SFields the transaction accepts
* and whether each is required, optional, or default.
*
* The singleton is constructed lazily on the first call to `getInstance()`.
* During construction, `transactions.macro` is expanded via an X-macro to
* call `KnownFormats::add()` once per transaction type. Registering a
* duplicate `TxType` value causes an immediate `logicError()` (process
* abort), making collisions visible at startup rather than at request time.
*
* Every transaction's `SOTemplate` is formed by merging the type-specific
* fields from `transactions.macro` with the universal common fields returned
* by `getCommonFields()`. The resulting schema is consulted by the
* deserializer and validator for every transaction that enters the ledger.
*
* @note This class is non-copyable. Obtain the single instance via
* `getInstance()`.
*
* @see KnownFormats, TxType, SOTemplate
*/
class TxFormats : public KnownFormats<TxType, TxFormats>
{
private:
/** Populate the registry with every known transaction format.
*
* Called exactly once by `getInstance()`. Expands `transactions.macro`
* and registers each transaction type via `KnownFormats::add()`.
*/
TxFormats();
public:
/** Return the process-wide singleton registry of all transaction formats.
*
* The registry is constructed on the first call via a function-local
* static, guaranteeing thread-safe initialization under C++11 rules for
* local statics. The same reference is returned on every subsequent
* call.
*
* @return A stable `const` reference to the singleton `TxFormats`
* instance.
*/
static TxFormats const&
getInstance();
/** Return the fields shared by every XRPL transaction, regardless of type.
*
* The returned vector is merged with each transaction's unique fields
* inside `KnownFormats::add()` to form the complete `SOTemplate` for
* that type. Required entries are `sfTransactionType`, `sfAccount`,
* `sfSequence`, `sfFee`, and `sfSigningPubKey`; a transaction missing
* any of them fails template validation.
*
* Notable optional fields and their roles:
* - `sfTicketSequence` — consume a pre-issued ticket instead of the
* account's current sequence, enabling out-of-order submission.
* - `sfSigners` — multi-signature array; coexists with `sfSigningPubKey`
* because single-sig and multi-sig are orthogonal format modes.
* - `sfNetworkID` — distinguishes sidechain transactions from mainnet
* ones at the wire level.
* - `sfDelegate` — authorizes a second account to act on behalf of the
* fee-paying account.
*
* @return A stable `const` reference to the static common-field vector.
* The vector is initialized on the first call and lives for the
* lifetime of the process.
*/
static std::vector<SOElement> const&
getCommonFields();
};
} // namespace xrpl