Serialized Objects
Manipulate raw serialized xrpld objects!
What are Serialized Objects?
The XRP Ledger has canonical serialized forms of all objects subject to consensus. When writing a Hook it is inevitable you will come across serialized objects. These manifest as buffers containing what might appear to the developer as opaque binary blobs. In fact you can read these with the XRPL-Binary-Visualiser.
For example an sfAmount
field serializes to a collection of bytes like 61D50F26109A32B7EC
Serialized Object API
To assist Hook developers in working with serialized objects the sto
namespace was created within the Hooks API. These functions manipulate pointers within a Hook-provided buffer. See table below.
Hook API | What it does |
sto_subfield | Index into a xrpld serialized object and return the location and length of a subfield |
sto_subarray | Index into a xrpld serialized array and return the location and length of an index |
sto_emplace | Emplace a field into an existing STObject at its canonical placement |
sto_erase | Remove a field from an STObject |
sto_validate | Validate an STObject |
Where applicable these APIs return an offset and a length encoded into a single int64_t. See individual documentation for details.
Example
At typical scenario in which you would use the STO API is in processing memos on an Originating Transaction. Since you will likely need access to the whole memo anyway, an efficient way to process a set of memos is simply to dump the whole sfMemos
field into a buffer then index around within it. While it is also possible to use the slot API to do this by slotting the Originating Transaction it would result in additional code and additional copying.
#define SUB_OFFSET(x) ((int32_t)(x >> 32))
#define SUB_LENGTH(x) ((int32_t)(x & 0xFFFFFFFFULL))
#define SBUF(str) (uint32_t)(str), sizeof(str)
uint8_t memos[2048];
int64_t memos_len = otxn_field(SBUF(memos), sfMemos);
for (int i = 0; GUARD(3), i < 3; ++i)
{
int64_t memo_lookup = sto_subarray(memos, memos_len, i);
if (memo_lookup < 0)
rollback(SBUF("Memo lookup error"), 1);
uint8_t* memo_ptr = SUB_OFFSET(memo_lookup) + memos;
uint32_t memo_len = SUB_LENGTH(memo_lookup);
// the above now point at the memo ... do something here
}
Overlap with slots
You may notice some overlap between slot APIs and STO APIs. The key difference here is who owns the underlying data:
- If you are using slots then xrpld owns the object you are interacting with.
- If you are using the STO API then the Hook owns the buffer you are interacting with.
Both sets of functions index into a Serialized Object without unnecessary copying.
Updated over 1 year ago