Repository navigation
Description
Summary
Generate the TransactionCommonFields trait (xrpl-common-stdlib/src/current_tx/traits.rs) from rippled's TxFormats::getCommonFields() instead of hand-writing each getter, and add a --check drift gate to CI, mirroring what ./scripts/generate-ledger-objects.sh already does for ledger-object field traits.
Motivation
Today the trait is 100% hand-written. Each new common field (e.g. get_delegate, added in the feat/add-delegate-tx-field branch) means a hand-written getter, doc comment, and a set of mock-based tests copied from a neighbouring getter. Nothing in CI notices when rippled adds a common field.
Compared against src/libxrpl/protocol/TxFormats.cpp on the ripple/se/supported branch (the default source the existing generators read), the trait is already missing five common fields:
| rippled field | soe | Status in trait |
|---|---|---|
PreviousTxnID |
SoeOptional | missing (emitted-transaction only) |
OperationLimit |
SoeOptional | missing |
Sponsor |
SoeOptional | missing |
SponsorFlags |
SoeOptional | missing |
SponsorSignature |
SoeOptional | missing |
A generator with a drift check would have surfaced all five.
Proposed approach
Reuse the machinery in tools/generateLedgerObjects.js rather than writing a parallel generator:
- Parse
getCommonFields()fromTxFormats.cpp({sfX, SoeRequired|SoeOptional}entries, same shape asledger_entries.macro). - Resolve Rust types through the shared
tools/sfieldTypeMap.js, emittingResult<T>for required fields andResult<Option<T>>for optional ones. SkipArray/Objectfields (Memos,Signers) as the ledger-object generator does; they stay reachable viapath(). - Emit to a new generated file (e.g.
xrpl-common-stdlib/src/current_tx/generated/common_fields.rs) with the same banner,#[cfg(test)] mod testsblock, and unmapped-type header the ledger-object generator produces. - Fetch doc comments from the xrpl-dev-portal transaction common-fields page, analogous to the per-entry docs fetch for ledger objects.
- Add
./scripts/generate-tx-common-fields.shwith a--checkmode, wire it intoscripts/run-all.shand.github/workflows/test.yml, and document it inCLAUDE.md's command list and generated-files sections.
Hand-written divergences to preserve
The current trait deliberately differs from rippled in four places. The generator needs per-field exclusions (like PER_ENTRY_EXCLUDED_FIELDS) so these can stay in a hand-written extension trait, or be relocated:
get_gasis not a common field. rippled declaressfGasasSoeOptionalonttESCROW_FINISHonly, but the trait exposes it as a requiredResult<u32>on the common trait. It probably belongs inxrpl-escrow-stdlib(onEscrowFinish), and this work should decide that.get_signing_pub_keyisSoeRequiredin rippled but returnsResult<Option<PublicKey>>based on a 0-or-33-byte length check (empty means multi-signed), with a panic on any other length.get_txn_signatureisSoeOptionalin rippled but the trait returns a requiredResult<SignatureBlob>.- The existing doc comments carry security notes and usage guidance that a docs-portal fetch may not reproduce. Decide whether to keep those getters hand-written or accept generated docs.
Acceptance criteria
-
TransactionCommonFieldsgetters for every field ingetCommonFields()are generated, excludingArray/Objectfields and the explicit exclusions above. - The five currently-missing fields are exposed (or explicitly excluded with a documented reason).
-
./scripts/generate-tx-common-fields.sh --checkruns inrun-all.shand CI and fails on drift. - Generated tests cover the same Some/None/error/invalid cases the hand-written tests do today.
-
get_gasplacement is resolved (moved toxrpl-escrow-stdlibor kept with a documented rationale). -
CLAUDE.md,skills/xrpl-smart-escrows/reference/api-surface.md, andscripts/README.mdare updated.
Related
feat/add-delegate-tx-fieldbranch: hand-writtenget_delegate, the change that prompted this proposal.- feat: Remove float_root #283 (float_root removal) and the
--checkgate inscripts/generate-ledger-objects.shfor the drift-check pattern to copy.
Activity