mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-07-14 18:00:14 +00:00
243 lines
6.9 KiB
Rust
243 lines
6.9 KiB
Rust
use std::{ffi::CString, ptr, slice};
|
|
|
|
use crate::{
|
|
block_on,
|
|
error::{print_error, WalletFfiError},
|
|
generic_transaction::{FfiProgram, FfiTransactionResult},
|
|
wallet::get_wallet,
|
|
WalletHandle,
|
|
};
|
|
|
|
/// Send a program deployment transaction.
|
|
///
|
|
/// Publishes program for future use.
|
|
///
|
|
/// # Parameters
|
|
/// - `handle`: Valid wallet handle
|
|
/// - `elf_data`: Valid pointer to elf data in bytes
|
|
/// - `elf_size`: Size of elf data
|
|
/// - `out_result`: Output pointer for transfer result
|
|
///
|
|
/// # Returns
|
|
/// - `Success` if deployment was submitted successfully
|
|
/// - Error code on other failures
|
|
///
|
|
/// # Memory
|
|
/// The result must be freed with `wallet_ffi_free_transaction_result()`.
|
|
///
|
|
/// # Safety
|
|
/// - `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`
|
|
/// - `elf_data` must be a valid pointer to elf data
|
|
/// - `out_result` must be a valid pointer to a `FfiTransferResult` struct
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn wallet_ffi_program_deployment(
|
|
handle: *mut WalletHandle,
|
|
elf_data: *const u8,
|
|
elf_size: usize,
|
|
out_result: *mut FfiTransactionResult,
|
|
) -> WalletFfiError {
|
|
let wrapper = match get_wallet(handle) {
|
|
Ok(w) => w,
|
|
Err(e) => return e,
|
|
};
|
|
|
|
if elf_data.is_null() || out_result.is_null() {
|
|
print_error("Null pointer argument");
|
|
return WalletFfiError::NullPointer;
|
|
}
|
|
|
|
let wallet = match wrapper.core.lock() {
|
|
Ok(w) => w,
|
|
Err(e) => {
|
|
print_error(format!("Failed to lock wallet: {e}"));
|
|
return WalletFfiError::InternalError;
|
|
}
|
|
};
|
|
|
|
let elf = unsafe { slice::from_raw_parts(elf_data, elf_size) }.to_vec();
|
|
|
|
match block_on(wallet.send_program_deployment_transaction(elf)) {
|
|
Ok(tx_hash) => {
|
|
let tx_hash = CString::new(tx_hash.to_string())
|
|
.map_or(ptr::null_mut(), std::ffi::CString::into_raw);
|
|
|
|
unsafe {
|
|
(*out_result).tx_hash = tx_hash;
|
|
(*out_result).success = true;
|
|
}
|
|
WalletFfiError::Success
|
|
}
|
|
Err(e) => {
|
|
print_error(format!("Deployment failed: {e:?}"));
|
|
unsafe {
|
|
(*out_result).tx_hash = ptr::null_mut();
|
|
(*out_result).success = false;
|
|
}
|
|
WalletFfiError::NetworkError
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Writes elf data of authenticated transfer program into buffer.
|
|
///
|
|
/// WARNING: Result is not consisent and change between versions, use for testing purposes only.
|
|
///
|
|
/// # Parameters
|
|
/// - `ffi_program`: Valid pointer to `FfiProgram`
|
|
///
|
|
/// # Returns
|
|
/// - `Success` if deployment was submitted successfully
|
|
/// - Error code on other failures
|
|
///
|
|
/// # Memory
|
|
/// - `FfiProgram` can be freed with corresponding `wallet_ffi_free_ffi_program` function
|
|
///
|
|
/// # Safety
|
|
/// - `ffi_program` must be a non-null pointer
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn wallet_ffi_transfer_elf(ffi_program: *mut FfiProgram) -> WalletFfiError {
|
|
if ffi_program.is_null() {
|
|
print_error("Null pointer argument");
|
|
return WalletFfiError::NullPointer;
|
|
}
|
|
|
|
let elf = programs::authenticated_transfer().elf().to_vec();
|
|
|
|
let (raw_elf_data, raw_elf_size, _) = elf.into_raw_parts();
|
|
|
|
unsafe {
|
|
(*ffi_program).elf_data = raw_elf_data;
|
|
(*ffi_program).elf_size = raw_elf_size;
|
|
};
|
|
|
|
WalletFfiError::Success
|
|
}
|
|
|
|
/// Writes elf data of authenticated token program into buffer.
|
|
///
|
|
/// WARNING: Result is not consisent and change between versions, use for testing purposes only.
|
|
///
|
|
/// # Parameters
|
|
/// - `ffi_program`: Valid pointer to `FfiProgram`
|
|
///
|
|
/// # Returns
|
|
/// - `Success` if deployment was submitted successfully
|
|
/// - Error code on other failures
|
|
///
|
|
/// # Memory
|
|
/// - `FfiProgram` can be freed with corresponding `wallet_ffi_free_ffi_program` function
|
|
///
|
|
/// # Safety
|
|
/// - `ffi_program` must be a non-null pointer
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn wallet_ffi_token_elf(ffi_program: *mut FfiProgram) -> WalletFfiError {
|
|
if ffi_program.is_null() {
|
|
print_error("Null pointer argument");
|
|
return WalletFfiError::NullPointer;
|
|
}
|
|
|
|
let elf = programs::token().elf().to_vec();
|
|
|
|
let (raw_elf_data, raw_elf_size, _) = elf.into_raw_parts();
|
|
|
|
unsafe {
|
|
(*ffi_program).elf_data = raw_elf_data;
|
|
(*ffi_program).elf_size = raw_elf_size;
|
|
};
|
|
|
|
WalletFfiError::Success
|
|
}
|
|
|
|
/// Writes elf data of amm into buffer.
|
|
///
|
|
/// WARNING: Result is not consisent and change between versions, use for testing purposes only.
|
|
///
|
|
/// # Parameters
|
|
/// - `ffi_program`: Valid pointer to `FfiProgram`
|
|
///
|
|
/// # Returns
|
|
/// - `Success` if deployment was submitted successfully
|
|
/// - Error code on other failures
|
|
///
|
|
/// # Memory
|
|
/// - `FfiProgram` can be freed with corresponding `wallet_ffi_free_ffi_program` function
|
|
///
|
|
/// # Safety
|
|
/// - `ffi_program` must be a non-null pointer
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn wallet_ffi_amm_elf(ffi_program: *mut FfiProgram) -> WalletFfiError {
|
|
if ffi_program.is_null() {
|
|
print_error("Null pointer argument");
|
|
return WalletFfiError::NullPointer;
|
|
}
|
|
|
|
let elf = programs::amm().elf().to_vec();
|
|
|
|
let (raw_elf_data, raw_elf_size, _) = elf.into_raw_parts();
|
|
|
|
unsafe {
|
|
(*ffi_program).elf_data = raw_elf_data;
|
|
(*ffi_program).elf_size = raw_elf_size;
|
|
};
|
|
|
|
WalletFfiError::Success
|
|
}
|
|
|
|
/// Writes elf data of ata into buffer.
|
|
///
|
|
/// WARNING: Result is not consisent and change between versions, use for testing purposes only.
|
|
///
|
|
/// # Parameters
|
|
/// - `ffi_program`: Valid pointer to `FfiProgram`
|
|
///
|
|
/// # Returns
|
|
/// - `Success` if deployment was submitted successfully
|
|
/// - Error code on other failures
|
|
///
|
|
/// # Memory
|
|
/// - `FfiProgram` can be freed with corresponding `wallet_ffi_free_ffi_program` function
|
|
///
|
|
/// # Safety
|
|
/// - `ffi_program` must be a non-null pointer
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn wallet_ffi_ata_elf(ffi_program: *mut FfiProgram) -> WalletFfiError {
|
|
if ffi_program.is_null() {
|
|
print_error("Null pointer argument");
|
|
return WalletFfiError::NullPointer;
|
|
}
|
|
|
|
let elf = programs::ata().elf().to_vec();
|
|
|
|
let (raw_elf_data, raw_elf_size, _) = elf.into_raw_parts();
|
|
|
|
unsafe {
|
|
(*ffi_program).elf_data = raw_elf_data;
|
|
(*ffi_program).elf_size = raw_elf_size;
|
|
};
|
|
|
|
WalletFfiError::Success
|
|
}
|
|
|
|
/// Free a ffi program returned by functions `wallet_ffi_*_elf`.
|
|
///
|
|
/// # Safety
|
|
/// The result must be either null or a valid result from a elf getter function.
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn wallet_ffi_free_ffi_program(ffi_program: *mut FfiProgram) {
|
|
if ffi_program.is_null() {
|
|
return;
|
|
}
|
|
|
|
unsafe {
|
|
let ffi_program = &*ffi_program;
|
|
|
|
if !ffi_program.elf_data.is_null() {
|
|
let elf = std::slice::from_raw_parts_mut(
|
|
ffi_program.elf_data.cast_mut(),
|
|
ffi_program.elf_size,
|
|
);
|
|
drop(Box::from_raw(std::ptr::from_mut::<[u8]>(elf)));
|
|
}
|
|
}
|
|
}
|