Use bytearray instead of hi/lo for u128

This commit is contained in:
Daniel 2026-01-26 10:15:23 +01:00
parent ec6caee2dc
commit 6d883d5528
4 changed files with 31 additions and 70 deletions

View File

@ -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;
}

View File

@ -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);

View File

@ -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<FfiBytes32> 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)
}

View File

@ -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);
/**