From 6d883d5528737ec10a7a3c440d9417af810d748c Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 26 Jan 2026 10:15:23 +0100 Subject: [PATCH] Use bytearray instead of hi/lo for u128 --- wallet-ffi/src/account.rs | 24 +++++++----------------- wallet-ffi/src/transfer.rs | 14 ++++++-------- wallet-ffi/src/types.rs | 31 ++++++++----------------------- wallet-ffi/wallet_ffi.h | 32 ++++++++++---------------------- 4 files changed, 31 insertions(+), 70 deletions(-) diff --git a/wallet-ffi/src/account.rs b/wallet-ffi/src/account.rs index 53abb54f..db668e75 100644 --- a/wallet-ffi/src/account.rs +++ b/wallet-ffi/src/account.rs @@ -7,8 +7,7 @@ use nssa::AccountId; use crate::block_on; use crate::error::{set_last_error, WalletFfiError}; use crate::types::{ - split_u128, FfiAccount, FfiAccountList, FfiAccountListEntry, FfiBytes32, FfiProgramId, - WalletHandle, + FfiAccount, FfiAccountList, FfiAccountListEntry, FfiBytes32, FfiProgramId, WalletHandle, }; use crate::wallet::get_wallet; @@ -220,8 +219,7 @@ pub extern "C" fn wallet_ffi_free_account_list(list: *mut FfiAccountList) { /// - `handle`: Valid wallet handle /// - `account_id`: The account ID (32 bytes) /// - `is_public`: Whether this is a public account -/// - `out_balance_lo`: Output for lower 64 bits of balance -/// - `out_balance_hi`: Output for upper 64 bits of balance +/// - `out_balance`: Output for balance as little-endian [u8; 16] /// /// # Returns /// - `Success` on successful query @@ -231,15 +229,14 @@ pub extern "C" fn wallet_ffi_get_balance( handle: *mut WalletHandle, account_id: *const FfiBytes32, is_public: bool, - out_balance_lo: *mut u64, - out_balance_hi: *mut u64, + out_balance: *mut [u8; 16], ) -> WalletFfiError { let wrapper = match get_wallet(handle) { Ok(w) => w, Err(e) => return e, }; - if account_id.is_null() || out_balance_lo.is_null() || out_balance_hi.is_null() { + if account_id.is_null() || out_balance.is_null() { set_last_error("Null pointer argument"); return WalletFfiError::NullPointer; } @@ -273,10 +270,8 @@ pub extern "C" fn wallet_ffi_get_balance( } }; - let (lo, hi) = split_u128(balance); unsafe { - *out_balance_lo = lo; - *out_balance_hi = hi; + *out_balance = balance.to_le_bytes(); } WalletFfiError::Success @@ -340,19 +335,14 @@ pub extern "C" fn wallet_ffi_get_account_public( ptr::null() }; - let (balance_lo, balance_hi) = split_u128(account.balance); - let (nonce_lo, nonce_hi) = split_u128(account.nonce); - let program_owner = FfiProgramId { data: account.program_owner, }; unsafe { (*out_account).program_owner = program_owner; - (*out_account).balance_lo = balance_lo; - (*out_account).balance_hi = balance_hi; - (*out_account).nonce_lo = nonce_lo; - (*out_account).nonce_hi = nonce_hi; + (*out_account).balance = account.balance.to_le_bytes(); + (*out_account).nonce = account.nonce.to_le_bytes(); (*out_account).data = data_ptr; (*out_account).data_len = data_len; } diff --git a/wallet-ffi/src/transfer.rs b/wallet-ffi/src/transfer.rs index 3c0c8edb..e11858da 100644 --- a/wallet-ffi/src/transfer.rs +++ b/wallet-ffi/src/transfer.rs @@ -1,6 +1,6 @@ //! Token transfer functions. -use std::ffi::{c_ulonglong, CString}; +use std::ffi::CString; use std::ptr; use common::error::ExecutionFailureKind; @@ -9,7 +9,7 @@ use wallet::program_facades::native_token_transfer::NativeTokenTransfer; use crate::block_on; use crate::error::{set_last_error, WalletFfiError}; -use crate::types::{combine_u128, FfiBytes32, FfiTransferResult, WalletHandle}; +use crate::types::{FfiBytes32, FfiTransferResult, WalletHandle}; use crate::wallet::get_wallet; /// Send a public token transfer. @@ -20,8 +20,7 @@ use crate::wallet::get_wallet; /// - `handle`: Valid wallet handle /// - `from`: Source account ID (must be owned by this wallet) /// - `to`: Destination account ID -/// - `amount_lo`: Lower 64 bits of amount to transfer -/// - `amount_hi`: Upper 64 bits of amount to transfer +/// - `amount`: Amount to transfer as little-endian [u8; 16] /// - `out_result`: Output pointer for transfer result /// /// # Returns @@ -37,8 +36,7 @@ pub extern "C" fn wallet_ffi_transfer_public( handle: *mut WalletHandle, from: *const FfiBytes32, to: *const FfiBytes32, - amount_lo: u64, - amount_hi: u64, + amount: *const [u8; 16], out_result: *mut FfiTransferResult, ) -> WalletFfiError { let wrapper = match get_wallet(handle) { @@ -46,7 +44,7 @@ pub extern "C" fn wallet_ffi_transfer_public( Err(e) => return e, }; - if from.is_null() || to.is_null() || out_result.is_null() { + if from.is_null() || to.is_null() || amount.is_null() || out_result.is_null() { set_last_error("Null pointer argument"); return WalletFfiError::NullPointer; } @@ -61,7 +59,7 @@ pub extern "C" fn wallet_ffi_transfer_public( let from_id = AccountId::new(unsafe { (*from).data }); let to_id = AccountId::new(unsafe { (*to).data }); - let amount = combine_u128(amount_lo, amount_hi); + let amount = u128::from_le_bytes(unsafe { *amount }); let transfer = NativeTokenTransfer(&wallet); diff --git a/wallet-ffi/src/types.rs b/wallet-ffi/src/types.rs index ab199d7c..9bb67f19 100644 --- a/wallet-ffi/src/types.rs +++ b/wallet-ffi/src/types.rs @@ -27,35 +27,29 @@ pub struct FfiProgramId { /// Account data structure - C-compatible version of nssa Account. /// -/// Note: `balance` and `nonce` are u128 values split into lo/hi u64 parts -/// since C doesn't have native u128 support. +/// Note: `balance` and `nonce` are u128 values represented as little-endian +/// byte arrays since C doesn't have native u128 support. #[repr(C)] pub struct FfiAccount { pub program_owner: FfiProgramId, - /// Lower 64 bits of balance (u128) - pub balance_lo: u64, - /// Upper 64 bits of balance (u128) - pub balance_hi: u64, + /// Balance as little-endian [u8; 16] + pub balance: [u8; 16], /// Pointer to account data bytes pub data: *const u8, /// Length of account data pub data_len: usize, - /// Lower 64 bits of nonce (u128) - pub nonce_lo: u64, - /// Upper 64 bits of nonce (u128) - pub nonce_hi: u64, + /// Nonce as little-endian [u8; 16] + pub nonce: [u8; 16], } impl Default for FfiAccount { fn default() -> Self { Self { program_owner: FfiProgramId::default(), - balance_lo: 0, - balance_hi: 0, + balance: [0u8; 16], data: std::ptr::null(), data_len: 0, - nonce_lo: 0, - nonce_hi: 0, + nonce: [0u8; 16], } } } @@ -156,12 +150,3 @@ impl From for nssa::AccountId { } } -/// Helper to split a u128 into lo/hi u64 parts. -pub fn split_u128(value: u128) -> (u64, u64) { - (value as u64, (value >> 64) as u64) -} - -/// Helper to combine lo/hi u64 parts into a u128. -pub fn combine_u128(lo: u64, hi: u64) -> u128 { - (hi as u128) << 64 | (lo as u128) -} diff --git a/wallet-ffi/wallet_ffi.h b/wallet-ffi/wallet_ffi.h index c1f46653..6465ac25 100644 --- a/wallet-ffi/wallet_ffi.h +++ b/wallet-ffi/wallet_ffi.h @@ -144,19 +144,15 @@ typedef struct FfiProgramId { /** * Account data structure - C-compatible version of nssa Account. * - * Note: `balance` and `nonce` are u128 values split into lo/hi u64 parts - * since C doesn't have native u128 support. + * Note: `balance` and `nonce` are u128 values represented as little-endian + * byte arrays since C doesn't have native u128 support. */ typedef struct FfiAccount { struct FfiProgramId program_owner; /** - * Lower 64 bits of balance (u128) + * Balance as little-endian [u8; 16] */ - uint64_t balance_lo; - /** - * Upper 64 bits of balance (u128) - */ - uint64_t balance_hi; + uint8_t balance[16]; /** * Pointer to account data bytes */ @@ -166,13 +162,9 @@ typedef struct FfiAccount { */ uintptr_t data_len; /** - * Lower 64 bits of nonce (u128) + * Nonce as little-endian [u8; 16] */ - uint64_t nonce_lo; - /** - * Upper 64 bits of nonce (u128) - */ - uint64_t nonce_hi; + uint8_t nonce[16]; } FfiAccount; /** @@ -306,8 +298,7 @@ void wallet_ffi_free_account_list(struct FfiAccountList *list); * - `handle`: Valid wallet handle * - `account_id`: The account ID (32 bytes) * - `is_public`: Whether this is a public account - * - `out_balance_lo`: Output for lower 64 bits of balance - * - `out_balance_hi`: Output for upper 64 bits of balance + * - `out_balance`: Output for balance as little-endian [u8; 16] * * # Returns * - `Success` on successful query @@ -316,8 +307,7 @@ void wallet_ffi_free_account_list(struct FfiAccountList *list); enum WalletFfiError wallet_ffi_get_balance(struct WalletHandle *handle, const struct FfiBytes32 *account_id, bool is_public, - uint64_t *out_balance_lo, - uint64_t *out_balance_hi); + uint8_t (*out_balance)[16]); /** * Get full public account data from the network. @@ -505,8 +495,7 @@ enum WalletFfiError wallet_ffi_get_current_block_height(struct WalletHandle *han * - `handle`: Valid wallet handle * - `from`: Source account ID (must be owned by this wallet) * - `to`: Destination account ID - * - `amount_lo`: Lower 64 bits of amount to transfer - * - `amount_hi`: Upper 64 bits of amount to transfer + * - `amount`: Amount to transfer as little-endian [u8; 16] * - `out_result`: Output pointer for transfer result * * # Returns @@ -521,8 +510,7 @@ enum WalletFfiError wallet_ffi_get_current_block_height(struct WalletHandle *han enum WalletFfiError wallet_ffi_transfer_public(struct WalletHandle *handle, const struct FfiBytes32 *from, const struct FfiBytes32 *to, - uint64_t amount_lo, - uint64_t amount_hi, + const uint8_t (*amount)[16], struct FfiTransferResult *out_result); /**