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§
Provided Associated Constants§
Required Methods§
Sourcefn build(
&self,
uninitialized_buffer: &mut [MaybeUninit<u8>; TXN_LEN],
) -> Result<()>
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§
Sourcefn uninit_buffer() -> [MaybeUninit<u8>; TXN_LEN]
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.