Trait TransactionBuilder

Source
pub trait TransactionBuilder<const TXN_LEN: usize> {
    const TXN_TYPE: TxnType;
    const TXN_LEN: usize = TXN_LEN;

    // Required method
    fn build(
        &self,
        uninitialized_buffer: &mut [MaybeUninit<u8>; TXN_LEN],
    ) -> Result<()>;

    // Provided method
    fn uninit_buffer() -> [MaybeUninit<u8>; TXN_LEN] { ... }
}
Expand description

Builds a transaction.

Required Associated Constants§

Source

const TXN_TYPE: TxnType

Transaction type of the transaction.

Provided Associated Constants§

Source

const TXN_LEN: usize = TXN_LEN

Byte length of the transaction.

Required Methods§

Source

fn build( &self, uninitialized_buffer: &mut [MaybeUninit<u8>; TXN_LEN], ) -> Result<()>

Builds a specific transaction by directly modifying the uninitialized buffer provided as an argument.

The reason that this function must take a mutable reference to an uninitialized buffer and cannot initialize its own buffer inside it to return it is because of Rust’s restrictions on returning unsafe pointer to local variables to the outer scope and its compiler producing memcpy instructions on return a long buffer if we don’t want to return a pointer to a local variable.

For example, if we were to do this inside a function:

let mut uninitialized_buffer: [MaybeUninit<u8>; 270] = MaybeUninit::uninit_array();

....

return uninitialized_buffer.as_ptr() as *const u8

This never works, because uninitialized_buffer is dropped at the end of the function, but the pointer to it is returned to the outer scope, which is undefined behavior.

If we do this instead:

let mut uninitialized_buffer: [MaybeUninit<u8>; 270] = MaybeUninit::uninit_array();

....

return uninitialized_buffer

This is completely fine as it just moves uninitialized_buffer, but it will somehow motivate the Rust compiler to create memcpy instruction, which is prohibited in wasm that is to be used as a hook where only two function exports are allowed: hook and cbak.

§Example

Therefore, we have no choice but to use this syntax:

let xrp_payment_txn_builder = XrpPaymentBuilder::new(1000, &otxn_account, 0, 0);
let mut buffer = XrpPaymentBuilder::uninit_buffer();
match xrp_payment_txn_builder.build(&mut buffer) {
    Ok(ptr) => ptr,
    Err(err) => {
        rollback(b"could not build xrp payment txn", err.into());
    }
};

Provided Methods§

Source

fn uninit_buffer() -> [MaybeUninit<u8>; TXN_LEN]

Utility method for creating an uninitialized buffer for a predefined length. Use this for creating an uninitialized transaction buffer to pass to build.

§Example
let xrp_payment_txn_builder = XrpPaymentBuilder::new(1000, &otxn_account, 0, 0);
let mut buffer = XrpPaymentBuilder::uninit_buffer();
match xrp_payment_txn_builder.build(&mut buffer) {
    Ok(ptr) => ptr,
    Err(err) => {
        rollback(b"could not build xrp payment txn", err.into());
    }
};

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§

Source§

impl TransactionBuilder<270> for XrpPaymentBuilder<'_>

Source§

const TXN_TYPE: TxnType = TxnType::Payment