Add the transaction handling for `EscrowCreate.Bytecode`/`Data` and `EscrowFinish.Gas`, gated on `featureSmartEscrow`. The field and result-code plumbing landed in #8157. EscrowCreate: * `Bytecode` joins `FinishAfter` and `Condition` as a way to say how an escrow completes, but always needs a `CancelAfter`: nothing else can free the funds if the contract never accepts. * `Data` requires `Bytecode` and is capped at `kMaxWasmDataLength`. * Bytecode is capped at the voted `BytecodeSizeLimit`, and refused outright when fee voting has zeroed `GasLimit` or `BytecodeSizeLimit`. * The fee is ten base fees plus five drops per byte. * The owner reserve is one increment per 500 bytes beyond the first 500, on top of the increment every escrow costs. EscrowCancel and EscrowFinish refund what was taken. EscrowFinish: * `Gas` is bounded by the voted `GasLimit` and costs `GasPrice` micro-drops each. * `Gas` and the escrow's `Bytecode` must both be present or both absent (tefBYTECODE_NOT_INCLUDED / tefNO_BYTECODE). * The destination and deposit-preauth checks move ahead of the condition check, so a contract never runs against a destination that cannot receive. The WASM engine is not in this build, so nothing runs the bytecode: creating, funding and cancelling a Smart Escrow works, and finishing one reports tecFAILED_PROCESSING at the TODO where the contract would run. The gas and return-code metadata, tecBYTECODE_REJECTED, and the `Data` a rejected contract leaves behind all arrive with the engine. Reachable only under `featureSmartEscrow`, which is `Supported::No`.
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 thexrpldcodebase.- 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.