* upstream/develop: (56 commits) Remove `include(default)` from libxrpl profile (#5587) refactor: Change boost::shared_mutex to std::shared_mutex (#5576) Fix macos runner (#5585) Remove the type filter from "ledger" RPC command (#4934) refactor: Update date, libarchive, nudb, openssl, sqlite3, xxhash packages (#5567) test: Run unit tests regardless of 'Supported' amendment status (#5537) Retire Flow Cross amendment (#5562) chore: Update CI to use Conan 2 (#5556) fixAMMClawbackRounding: adjust last holder's LPToken balance (#5513) chore: Add gcc-12 workaround (#5554) Add MPT related txns into issuer's account history (#5530) chore: Remove unused headers (#5526) fix: add allowTrustLineLocking flag for account_info (#5525) Downgrade required CMake version for Antithesis SDK (#5548) fix: Link with boost libraries explicitly (#5546) chore: Fix compilation error with clang-20 and cleanup (#5543) test: Remove circular jtx.h dependencies (#5544) Decouple CredentialHelpers from xrpld/app/tx (#5487) fix: crash when trace-logging in tests (#5529) test: switch some unit tests to doctest (#5383) ...
protocol
Classes and functions for handling data and values associated with the XRP Ledger protocol.
Serialized Objects
Objects transmitted over the network must be serialized into a canonical format. The prefix "ST" refers to classes that deal with the serialized format.
The term "Tx" or "tx" is an abbreviation for "Transaction", a commonly occurring object type.
Optional Fields
Our serialized fields have some "type magic" to make optional fields easier to read:
- The operation
x[sfFoo]means "return the value of 'Foo' if it exists, or the default value if it doesn't." - The operation
x[~sfFoo]means "return the value of 'Foo' if it exists, or nothing if it doesn't." This usage of the tilde/bitwise NOT operator is not standard outside of therippledcodebase.- As a consequence of this,
x[~sfFoo] = y[~sfFoo]assigns the value of Foo from y to x, including omitting Foo from x if it doesn't exist in y.
- As a consequence of this,
Typically, for things that are guaranteed to exist, you use
x[sfFoo] and avoid having to deal with a container that may
or may not hold a value. For things not guaranteed to exist,
you use x[~sfFoo] because you want such a container. It
avoids having to look something up twice, once just to see if
it exists and a second time to get/set its value.
(Real example)
The source of this "type magic" is in SField.h.