mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-05-12 02:59:29 +00:00
fix: correct free
This commit is contained in:
parent
1338dec951
commit
113a68c22c
14
Cargo.lock
generated
14
Cargo.lock
generated
@ -629,9 +629,9 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
|
||||
|
||||
[[package]]
|
||||
name = "astral-tokio-tar"
|
||||
version = "0.6.0"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c23f3af104b40a3430ccb90ed5f7bd877a8dc5c26fc92fde51a22b40890dcf9"
|
||||
checksum = "4ce73b17c62717c4b6a9af10b43e87c578b0cac27e00666d48304d3b7d2c0693"
|
||||
dependencies = [
|
||||
"filetime",
|
||||
"futures-core",
|
||||
@ -2108,7 +2108,7 @@ dependencies = [
|
||||
"libc",
|
||||
"option-ext",
|
||||
"redox_users",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2409,7 +2409,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -7090,7 +7090,7 @@ dependencies = [
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -8023,7 +8023,7 @@ dependencies = [
|
||||
"getrandom 0.4.2",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -9306,7 +9306,7 @@ version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
||||
dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@ -167,11 +167,15 @@ typedef struct FfiAccount {
|
||||
/**
|
||||
* Pointer to account data bytes.
|
||||
*/
|
||||
const uint8_t *data;
|
||||
uint8_t *data;
|
||||
/**
|
||||
* Length of account data.
|
||||
*/
|
||||
uintptr_t data_len;
|
||||
/**
|
||||
* Capacity of account data.
|
||||
*/
|
||||
uintptr_t data_cap;
|
||||
/**
|
||||
* Nonce as little-endian [u8; 16].
|
||||
*/
|
||||
@ -302,6 +306,66 @@ typedef struct PointerResult_FfiBlockOpt__OperationStatus {
|
||||
enum OperationStatus error;
|
||||
} PointerResult_FfiBlockOpt__OperationStatus;
|
||||
|
||||
/**
|
||||
* Simple wrapper around a pointer to a value or an error.
|
||||
*
|
||||
* Pointer is not guaranteed. You should check the error field before
|
||||
* dereferencing the pointer.
|
||||
*/
|
||||
typedef struct PointerResult_FfiAccount__OperationStatus {
|
||||
struct FfiAccount *value;
|
||||
enum OperationStatus error;
|
||||
} PointerResult_FfiAccount__OperationStatus;
|
||||
|
||||
typedef struct FfiOption_FfiTransaction {
|
||||
struct FfiTransaction *value;
|
||||
bool is_some;
|
||||
} FfiOption_FfiTransaction;
|
||||
|
||||
/**
|
||||
* Simple wrapper around a pointer to a value or an error.
|
||||
*
|
||||
* Pointer is not guaranteed. You should check the error field before
|
||||
* dereferencing the pointer.
|
||||
*/
|
||||
typedef struct PointerResult_FfiOption_FfiTransaction_____OperationStatus {
|
||||
struct FfiOption_FfiTransaction *value;
|
||||
enum OperationStatus error;
|
||||
} PointerResult_FfiOption_FfiTransaction_____OperationStatus;
|
||||
|
||||
typedef struct FfiVec_FfiBlock {
|
||||
struct FfiBlock *entries;
|
||||
uintptr_t len;
|
||||
uintptr_t capacity;
|
||||
} FfiVec_FfiBlock;
|
||||
|
||||
/**
|
||||
* Simple wrapper around a pointer to a value or an error.
|
||||
*
|
||||
* Pointer is not guaranteed. You should check the error field before
|
||||
* dereferencing the pointer.
|
||||
*/
|
||||
typedef struct PointerResult_FfiVec_FfiBlock_____OperationStatus {
|
||||
struct FfiVec_FfiBlock *value;
|
||||
enum OperationStatus error;
|
||||
} PointerResult_FfiVec_FfiBlock_____OperationStatus;
|
||||
|
||||
typedef struct FfiOption_u64 {
|
||||
uint64_t *value;
|
||||
bool is_some;
|
||||
} FfiOption_u64;
|
||||
|
||||
/**
|
||||
* Simple wrapper around a pointer to a value or an error.
|
||||
*
|
||||
* Pointer is not guaranteed. You should check the error field before
|
||||
* dereferencing the pointer.
|
||||
*/
|
||||
typedef struct PointerResult_FfiVec_FfiTransaction_____OperationStatus {
|
||||
struct FfiVec_FfiTransaction *value;
|
||||
enum OperationStatus error;
|
||||
} PointerResult_FfiVec_FfiTransaction_____OperationStatus;
|
||||
|
||||
/**
|
||||
* Creates and starts an indexer based on the provided
|
||||
* configuration file path.
|
||||
@ -347,46 +411,275 @@ enum OperationStatus stop_indexer(struct IndexerServiceFFI *indexer);
|
||||
void free_cstring(char *block);
|
||||
|
||||
/**
|
||||
* Stops and frees the resources associated with the given indexer service.
|
||||
* Query the last block id from indexer.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* - `indexer`: A pointer to the `IndexerServiceFFI` instance to be stopped.
|
||||
* - `indexer`: A pointer to the `IndexerServiceFFI` instance to be queried.
|
||||
*
|
||||
* # Returns
|
||||
*
|
||||
* An `OperationStatus` indicating success or failure.
|
||||
* A `PointerResult<u64, OperationStatus>` indicating success or failure.
|
||||
*
|
||||
* # Safety
|
||||
*
|
||||
* The caller must ensure that:
|
||||
* - `indexer` is a valid pointer to a `IndexerServiceFFI` instance
|
||||
* - The `IndexerServiceFFI` instance was created by this library
|
||||
* - The pointer will not be used after this function returns
|
||||
*/
|
||||
struct PointerResult_u64__OperationStatus query_last_block(const struct IndexerServiceFFI *indexer);
|
||||
|
||||
/**
|
||||
* Stops and frees the resources associated with the given indexer service.
|
||||
* Query the block by id from indexer.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* - `indexer`: A pointer to the `IndexerServiceFFI` instance to be stopped.
|
||||
* - `indexer`: A pointer to the `IndexerServiceFFI` instance to be queried.
|
||||
* - `block_id`: `u64` number of block id
|
||||
*
|
||||
* # Returns
|
||||
*
|
||||
* An `OperationStatus` indicating success or failure.
|
||||
* A `PointerResult<FfiBlockOpt, OperationStatus>` indicating success or failure.
|
||||
*
|
||||
* # Safety
|
||||
*
|
||||
* The caller must ensure that:
|
||||
* - `indexer` is a valid pointer to a `IndexerServiceFFI` instance
|
||||
* - The `IndexerServiceFFI` instance was created by this library
|
||||
* - The pointer will not be used after this function returns
|
||||
*/
|
||||
struct PointerResult_FfiBlockOpt__OperationStatus query_block(const struct IndexerServiceFFI *indexer,
|
||||
FfiBlockId block_id);
|
||||
|
||||
/**
|
||||
* Query the block by id from indexer.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* - `indexer`: A pointer to the `IndexerServiceFFI` instance to be queried.
|
||||
* - `hash`: `FfiHashType` - hash of block
|
||||
*
|
||||
* # Returns
|
||||
*
|
||||
* A `PointerResult<FfiBlockOpt, OperationStatus>` indicating success or failure.
|
||||
*
|
||||
* # Safety
|
||||
*
|
||||
* The caller must ensure that:
|
||||
* - `indexer` is a valid pointer to a `IndexerServiceFFI` instance
|
||||
*/
|
||||
struct PointerResult_FfiBlockOpt__OperationStatus query_block_by_hash(const struct IndexerServiceFFI *indexer,
|
||||
FfiHashType hash);
|
||||
|
||||
/**
|
||||
* Query the account by id from indexer.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* - `indexer`: A pointer to the `IndexerServiceFFI` instance to be queried.
|
||||
* - `account_id`: `FfiAccountId` - id of queried account
|
||||
*
|
||||
* # Returns
|
||||
*
|
||||
* A `PointerResult<FfiAccount, OperationStatus>` indicating success or failure.
|
||||
*
|
||||
* # Safety
|
||||
*
|
||||
* The caller must ensure that:
|
||||
* - `indexer` is a valid pointer to a `IndexerServiceFFI` instance
|
||||
*/
|
||||
struct PointerResult_FfiAccount__OperationStatus query_account(const struct IndexerServiceFFI *indexer,
|
||||
FfiAccountId account_id);
|
||||
|
||||
/**
|
||||
* Query the trasnaction by hash from indexer.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* - `indexer`: A pointer to the `IndexerServiceFFI` instance to be queried.
|
||||
* - `hash`: `FfiHashType` - hash of transaction
|
||||
*
|
||||
* # Returns
|
||||
*
|
||||
* A `PointerResult<FfiOption<FfiTransaction>, OperationStatus>` indicating success or failure.
|
||||
*
|
||||
* # Safety
|
||||
*
|
||||
* The caller must ensure that:
|
||||
* - `indexer` is a valid pointer to a `IndexerServiceFFI` instance
|
||||
*/
|
||||
struct PointerResult_FfiOption_FfiTransaction_____OperationStatus query_transaction(const struct IndexerServiceFFI *indexer,
|
||||
FfiHashType hash);
|
||||
|
||||
/**
|
||||
* Query the blocks by block range from indexer.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* - `indexer`: A pointer to the `IndexerServiceFFI` instance to be queried.
|
||||
* - `before`: `FfiOption<u64>` - end block of query
|
||||
* - `limit`: `u64` - number of blocks to query before `before`
|
||||
*
|
||||
* # Returns
|
||||
*
|
||||
* A `PointerResult<FfiVec<FfiBlock>, OperationStatus>` indicating success or failure.
|
||||
*
|
||||
* # Safety
|
||||
*
|
||||
* The caller must ensure that:
|
||||
* - `indexer` is a valid pointer to a `IndexerServiceFFI` instance
|
||||
*/
|
||||
struct PointerResult_FfiVec_FfiBlock_____OperationStatus query_block_vec(const struct IndexerServiceFFI *indexer,
|
||||
struct FfiOption_u64 before,
|
||||
uint64_t limit);
|
||||
|
||||
/**
|
||||
* Query the transactions range by account id from indexer.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* - `indexer`: A pointer to the `IndexerServiceFFI` instance to be queried.
|
||||
* - `account_id`: `FfiAccountId` - id of queried account
|
||||
* - `offset`: `u64` - first tx id of query
|
||||
* - `limit`: `u64` - number of tx ids to query after `offset`
|
||||
*
|
||||
* # Returns
|
||||
*
|
||||
* A `PointerResult<FfiVec<FfiBlock>, OperationStatus>` indicating success or failure.
|
||||
*
|
||||
* # Safety
|
||||
*
|
||||
* The caller must ensure that:
|
||||
* - `indexer` is a valid pointer to a `IndexerServiceFFI` instance
|
||||
*/
|
||||
struct PointerResult_FfiVec_FfiTransaction_____OperationStatus query_transactions_by_account(const struct IndexerServiceFFI *indexer,
|
||||
FfiAccountId account_id,
|
||||
uint64_t offset,
|
||||
uint64_t limit);
|
||||
|
||||
/**
|
||||
* Frees the resources associated with the given ffi account.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* - `val`: An instance of `FfiAccount`.
|
||||
*
|
||||
* # Returns
|
||||
*
|
||||
* void.
|
||||
*
|
||||
* # Safety
|
||||
*
|
||||
* The caller must ensure that:
|
||||
* - `val` is a valid instance of `FfiAccount`.
|
||||
*/
|
||||
void free_ffi_account(struct FfiAccount val);
|
||||
|
||||
/**
|
||||
* Frees the resources associated with the given ffi block.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* - `val`: An instance of `FfiBlock`.
|
||||
*
|
||||
* # Returns
|
||||
*
|
||||
* void.
|
||||
*
|
||||
* # Safety
|
||||
*
|
||||
* The caller must ensure that:
|
||||
* - `val` is a valid instance of `FfiBlock`.
|
||||
*/
|
||||
void free_ffi_block(struct FfiBlock val);
|
||||
|
||||
/**
|
||||
* Frees the resources associated with the given ffi block option.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* - `val`: An instance of `FfiBlockOpt`.
|
||||
*
|
||||
* # Returns
|
||||
*
|
||||
* void.
|
||||
*
|
||||
* # Safety
|
||||
*
|
||||
* The caller must ensure that:
|
||||
* - `val` is a valid instance of `FfiBlockOpt`.
|
||||
*/
|
||||
void free_ffi_block_opt(FfiBlockOpt val);
|
||||
|
||||
/**
|
||||
* Frees the resources associated with the given ffi block vector.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* - `val`: An instance of `FfiVec<FfiBlock>`.
|
||||
*
|
||||
* # Returns
|
||||
*
|
||||
* void.
|
||||
*
|
||||
* # Safety
|
||||
*
|
||||
* The caller must ensure that:
|
||||
* - `val` is a valid instance of `FfiVec<FfiBlock>`.
|
||||
*/
|
||||
void free_ffi_block_vec(struct FfiVec_FfiBlock val);
|
||||
|
||||
/**
|
||||
* Frees the resources associated with the given ffi transaction.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* - `val`: An instance of `FfiTransaction`.
|
||||
*
|
||||
* # Returns
|
||||
*
|
||||
* void.
|
||||
*
|
||||
* # Safety
|
||||
*
|
||||
* The caller must ensure that:
|
||||
* - `val` is a valid instance of `FfiTransaction`.
|
||||
*/
|
||||
void free_ffi_transaction(struct FfiTransaction val);
|
||||
|
||||
/**
|
||||
* Frees the resources associated with the given ffi transaction option.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* - `val`: An instance of `FfiOption<FfiTransaction>`.
|
||||
*
|
||||
* # Returns
|
||||
*
|
||||
* void.
|
||||
*
|
||||
* # Safety
|
||||
*
|
||||
* The caller must ensure that:
|
||||
* - `val` is a valid instance of `FfiOption<FfiTransaction>`.
|
||||
*/
|
||||
void free_ffi_transaction_opt(struct FfiOption_FfiTransaction val);
|
||||
|
||||
/**
|
||||
* Frees the resources associated with the given vector of ffi transactions.
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* - `val`: An instance of `FfiVec<FfiTransaction>`.
|
||||
*
|
||||
* # Returns
|
||||
*
|
||||
* void.
|
||||
*
|
||||
* # Safety
|
||||
*
|
||||
* The caller must ensure that:
|
||||
* - `val` is a valid instance of `FfiVec<FfiTransaction>`.
|
||||
*/
|
||||
void free_ffi_transaction_vec(struct FfiVec_FfiTransaction val);
|
||||
|
||||
bool is_ok(const enum OperationStatus *self);
|
||||
|
||||
bool is_error(const enum OperationStatus *self);
|
||||
|
||||
@ -1,30 +1,34 @@
|
||||
use indexer_service_protocol::{AccountId, HashType};
|
||||
use indexer_service_rpc::RpcClient as _;
|
||||
|
||||
use crate::{
|
||||
IndexerServiceFFI,
|
||||
api::{
|
||||
PointerResult,
|
||||
types::{FfiBlockId, block::FfiBlockOpt},
|
||||
types::{
|
||||
FfiAccountId, FfiBlockId, FfiHashType, FfiOption, FfiVec,
|
||||
account::FfiAccount,
|
||||
block::{FfiBlock, FfiBlockOpt},
|
||||
transaction::FfiTransaction,
|
||||
},
|
||||
},
|
||||
errors::OperationStatus,
|
||||
};
|
||||
|
||||
/// Stops and frees the resources associated with the given indexer service.
|
||||
/// Query the last block id from indexer.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `indexer`: A pointer to the `IndexerServiceFFI` instance to be stopped.
|
||||
/// - `indexer`: A pointer to the `IndexerServiceFFI` instance to be queried.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// An `OperationStatus` indicating success or failure.
|
||||
/// A `PointerResult<u64, OperationStatus>` indicating success or failure.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must ensure that:
|
||||
/// - `indexer` is a valid pointer to a `IndexerServiceFFI` instance
|
||||
/// - The `IndexerServiceFFI` instance was created by this library
|
||||
/// - The pointer will not be used after this function returns
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn query_last_block(
|
||||
indexer: *const IndexerServiceFFI,
|
||||
@ -47,22 +51,21 @@ pub unsafe extern "C" fn query_last_block(
|
||||
)
|
||||
}
|
||||
|
||||
/// Stops and frees the resources associated with the given indexer service.
|
||||
/// Query the block by id from indexer.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `indexer`: A pointer to the `IndexerServiceFFI` instance to be stopped.
|
||||
/// - `indexer`: A pointer to the `IndexerServiceFFI` instance to be queried.
|
||||
/// - `block_id`: `u64` number of block id
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// An `OperationStatus` indicating success or failure.
|
||||
/// A `PointerResult<FfiBlockOpt, OperationStatus>` indicating success or failure.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must ensure that:
|
||||
/// - `indexer` is a valid pointer to a `IndexerServiceFFI` instance
|
||||
/// - The `IndexerServiceFFI` instance was created by this library
|
||||
/// - The pointer will not be used after this function returns
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn query_block(
|
||||
indexer: *const IndexerServiceFFI,
|
||||
@ -91,3 +94,241 @@ pub unsafe extern "C" fn query_block(
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/// Query the block by id from indexer.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `indexer`: A pointer to the `IndexerServiceFFI` instance to be queried.
|
||||
/// - `hash`: `FfiHashType` - hash of block
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A `PointerResult<FfiBlockOpt, OperationStatus>` indicating success or failure.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must ensure that:
|
||||
/// - `indexer` is a valid pointer to a `IndexerServiceFFI` instance
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn query_block_by_hash(
|
||||
indexer: *const IndexerServiceFFI,
|
||||
hash: FfiHashType,
|
||||
) -> PointerResult<FfiBlockOpt, OperationStatus> {
|
||||
if indexer.is_null() {
|
||||
log::error!("Attempted to query a null indexer pointer. This is a bug. Aborting.");
|
||||
return PointerResult::from_error(OperationStatus::NullPointer);
|
||||
}
|
||||
|
||||
let indexer = unsafe { &*indexer };
|
||||
|
||||
let client = unsafe { indexer.client() };
|
||||
let runtime = unsafe { indexer.runtime() };
|
||||
|
||||
runtime
|
||||
.block_on(client.get_block_by_hash(HashType(hash.data)))
|
||||
.map_or_else(
|
||||
|_| PointerResult::from_error(OperationStatus::ClientError),
|
||||
|block_opt| {
|
||||
let block_ffi = block_opt.map_or_else(FfiBlockOpt::from_none, |block| {
|
||||
FfiBlockOpt::from_value(block.into())
|
||||
});
|
||||
|
||||
PointerResult::from_value(block_ffi)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/// Query the account by id from indexer.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `indexer`: A pointer to the `IndexerServiceFFI` instance to be queried.
|
||||
/// - `account_id`: `FfiAccountId` - id of queried account
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A `PointerResult<FfiAccount, OperationStatus>` indicating success or failure.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must ensure that:
|
||||
/// - `indexer` is a valid pointer to a `IndexerServiceFFI` instance
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn query_account(
|
||||
indexer: *const IndexerServiceFFI,
|
||||
account_id: FfiAccountId,
|
||||
) -> PointerResult<FfiAccount, OperationStatus> {
|
||||
if indexer.is_null() {
|
||||
log::error!("Attempted to query a null indexer pointer. This is a bug. Aborting.");
|
||||
return PointerResult::from_error(OperationStatus::NullPointer);
|
||||
}
|
||||
|
||||
let indexer = unsafe { &*indexer };
|
||||
|
||||
let client = unsafe { indexer.client() };
|
||||
let runtime = unsafe { indexer.runtime() };
|
||||
|
||||
runtime
|
||||
.block_on(client.get_account(AccountId {
|
||||
value: account_id.data,
|
||||
}))
|
||||
.map_or_else(
|
||||
|_| PointerResult::from_error(OperationStatus::ClientError),
|
||||
|acc| {
|
||||
let acc_nssa: nssa::Account =
|
||||
acc.try_into().expect("Source is in blocks, must fit");
|
||||
PointerResult::from_value(acc_nssa.into())
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/// Query the trasnaction by hash from indexer.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `indexer`: A pointer to the `IndexerServiceFFI` instance to be queried.
|
||||
/// - `hash`: `FfiHashType` - hash of transaction
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A `PointerResult<FfiOption<FfiTransaction>, OperationStatus>` indicating success or failure.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must ensure that:
|
||||
/// - `indexer` is a valid pointer to a `IndexerServiceFFI` instance
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn query_transaction(
|
||||
indexer: *const IndexerServiceFFI,
|
||||
hash: FfiHashType,
|
||||
) -> PointerResult<FfiOption<FfiTransaction>, OperationStatus> {
|
||||
if indexer.is_null() {
|
||||
log::error!("Attempted to query a null indexer pointer. This is a bug. Aborting.");
|
||||
return PointerResult::from_error(OperationStatus::NullPointer);
|
||||
}
|
||||
|
||||
let indexer = unsafe { &*indexer };
|
||||
|
||||
let client = unsafe { indexer.client() };
|
||||
let runtime = unsafe { indexer.runtime() };
|
||||
|
||||
runtime
|
||||
.block_on(client.get_transaction(HashType(hash.data)))
|
||||
.map_or_else(
|
||||
|_| PointerResult::from_error(OperationStatus::ClientError),
|
||||
|tx_opt| {
|
||||
let tx_ffi = tx_opt.map_or_else(FfiOption::<FfiTransaction>::from_none, |tx| {
|
||||
FfiOption::<FfiTransaction>::from_value(tx.into())
|
||||
});
|
||||
|
||||
PointerResult::from_value(tx_ffi)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/// Query the blocks by block range from indexer.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `indexer`: A pointer to the `IndexerServiceFFI` instance to be queried.
|
||||
/// - `before`: `FfiOption<u64>` - end block of query
|
||||
/// - `limit`: `u64` - number of blocks to query before `before`
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A `PointerResult<FfiVec<FfiBlock>, OperationStatus>` indicating success or failure.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must ensure that:
|
||||
/// - `indexer` is a valid pointer to a `IndexerServiceFFI` instance
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn query_block_vec(
|
||||
indexer: *const IndexerServiceFFI,
|
||||
before: FfiOption<u64>,
|
||||
limit: u64,
|
||||
) -> PointerResult<FfiVec<FfiBlock>, OperationStatus> {
|
||||
if indexer.is_null() {
|
||||
log::error!("Attempted to query a null indexer pointer. This is a bug. Aborting.");
|
||||
return PointerResult::from_error(OperationStatus::NullPointer);
|
||||
}
|
||||
|
||||
let indexer = unsafe { &*indexer };
|
||||
|
||||
let client = unsafe { indexer.client() };
|
||||
let runtime = unsafe { indexer.runtime() };
|
||||
|
||||
let before_std = before.is_some.then(|| unsafe { *before.value });
|
||||
|
||||
runtime
|
||||
.block_on(client.get_blocks(before_std, limit))
|
||||
.map_or_else(
|
||||
|_| PointerResult::from_error(OperationStatus::ClientError),
|
||||
|block_vec| {
|
||||
PointerResult::from_value(
|
||||
block_vec
|
||||
.into_iter()
|
||||
.map(Into::into)
|
||||
.collect::<Vec<_>>()
|
||||
.into(),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/// Query the transactions range by account id from indexer.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `indexer`: A pointer to the `IndexerServiceFFI` instance to be queried.
|
||||
/// - `account_id`: `FfiAccountId` - id of queried account
|
||||
/// - `offset`: `u64` - first tx id of query
|
||||
/// - `limit`: `u64` - number of tx ids to query after `offset`
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A `PointerResult<FfiVec<FfiBlock>, OperationStatus>` indicating success or failure.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must ensure that:
|
||||
/// - `indexer` is a valid pointer to a `IndexerServiceFFI` instance
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn query_transactions_by_account(
|
||||
indexer: *const IndexerServiceFFI,
|
||||
account_id: FfiAccountId,
|
||||
offset: u64,
|
||||
limit: u64,
|
||||
) -> PointerResult<FfiVec<FfiTransaction>, OperationStatus> {
|
||||
if indexer.is_null() {
|
||||
log::error!("Attempted to query a null indexer pointer. This is a bug. Aborting.");
|
||||
return PointerResult::from_error(OperationStatus::NullPointer);
|
||||
}
|
||||
|
||||
let indexer = unsafe { &*indexer };
|
||||
|
||||
let client = unsafe { indexer.client() };
|
||||
let runtime = unsafe { indexer.runtime() };
|
||||
|
||||
runtime
|
||||
.block_on(client.get_transactions_by_account(
|
||||
AccountId {
|
||||
value: account_id.data,
|
||||
},
|
||||
offset,
|
||||
limit,
|
||||
))
|
||||
.map_or_else(
|
||||
|_| PointerResult::from_error(OperationStatus::ClientError),
|
||||
|tx_vec| {
|
||||
PointerResult::from_value(
|
||||
tx_vec
|
||||
.into_iter()
|
||||
.map(Into::into)
|
||||
.collect::<Vec<_>>()
|
||||
.into(),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@ -1,48 +1,6 @@
|
||||
//! C-compatible type definitions for the FFI layer.
|
||||
|
||||
use std::ptr;
|
||||
|
||||
use indexer_service_protocol::ProgramId;
|
||||
|
||||
/// 32-byte array type for `AccountId`, keys, hashes, etc.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Default)]
|
||||
pub struct FfiBytes32 {
|
||||
pub data: [u8; 32],
|
||||
}
|
||||
|
||||
/// 64-byte array type for signatures, etc.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct FfiBytes64 {
|
||||
pub data: [u8; 64],
|
||||
}
|
||||
|
||||
impl Default for FfiBytes64 {
|
||||
fn default() -> Self {
|
||||
Self { data: [0; 64] }
|
||||
}
|
||||
}
|
||||
|
||||
/// Program ID - 8 u32 values (32 bytes total).
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Default)]
|
||||
pub struct FfiProgramId {
|
||||
pub data: [u32; 8],
|
||||
}
|
||||
|
||||
impl From<ProgramId> for FfiProgramId {
|
||||
fn from(value: ProgramId) -> Self {
|
||||
Self { data: value.0 }
|
||||
}
|
||||
}
|
||||
|
||||
/// U128 - 16 bytes little endian.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Default)]
|
||||
pub struct FfiU128 {
|
||||
pub data: [u8; 16],
|
||||
}
|
||||
use crate::api::types::{FfiBytes32, FfiProgramId, FfiU128};
|
||||
|
||||
/// Account data structure - C-compatible version of nssa Account.
|
||||
///
|
||||
@ -54,77 +12,17 @@ pub struct FfiAccount {
|
||||
/// Balance as little-endian [u8; 16].
|
||||
pub balance: FfiU128,
|
||||
/// Pointer to account data bytes.
|
||||
pub data: *const u8,
|
||||
pub data: *mut u8,
|
||||
/// Length of account data.
|
||||
pub data_len: usize,
|
||||
/// Capacity of account data.
|
||||
pub data_cap: usize,
|
||||
/// Nonce as little-endian [u8; 16].
|
||||
pub nonce: FfiU128,
|
||||
}
|
||||
|
||||
impl Default for FfiAccount {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
program_owner: FfiProgramId::default(),
|
||||
balance: FfiU128::default(),
|
||||
data: std::ptr::null(),
|
||||
data_len: 0,
|
||||
nonce: FfiU128::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Public keys for a private account (safe to expose).
|
||||
#[repr(C)]
|
||||
pub struct FfiPrivateAccountKeys {
|
||||
/// Nullifier public key (32 bytes).
|
||||
pub nullifier_public_key: FfiBytes32,
|
||||
/// viewing public key (compressed secp256k1 point).
|
||||
pub viewing_public_key: *const u8,
|
||||
/// Length of viewing public key (typically 33 bytes).
|
||||
pub viewing_public_key_len: usize,
|
||||
}
|
||||
|
||||
impl Default for FfiPrivateAccountKeys {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
nullifier_public_key: FfiBytes32::default(),
|
||||
viewing_public_key: std::ptr::null(),
|
||||
viewing_public_key_len: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Public key info for a public account.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Default)]
|
||||
pub struct FfiPublicAccountKey {
|
||||
pub public_key: FfiBytes32,
|
||||
}
|
||||
|
||||
// Helper functions to convert between Rust and FFI types
|
||||
|
||||
impl FfiBytes32 {
|
||||
/// Create from a 32-byte array.
|
||||
#[must_use]
|
||||
pub const fn from_bytes(bytes: [u8; 32]) -> Self {
|
||||
Self { data: bytes }
|
||||
}
|
||||
|
||||
/// Create from an `AccountId`.
|
||||
#[must_use]
|
||||
pub const fn from_account_id(id: &nssa::AccountId) -> Self {
|
||||
Self { data: *id.value() }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u128> for FfiU128 {
|
||||
fn from(value: u128) -> Self {
|
||||
Self {
|
||||
data: value.to_le_bytes(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&nssa::AccountId> for FfiBytes32 {
|
||||
fn from(id: &nssa::AccountId) -> Self {
|
||||
Self::from_account_id(id)
|
||||
@ -132,20 +30,8 @@ impl From<&nssa::AccountId> for FfiBytes32 {
|
||||
}
|
||||
|
||||
impl From<nssa::Account> for FfiAccount {
|
||||
#[expect(
|
||||
clippy::as_conversions,
|
||||
reason = "We need to convert to byte arrays for FFI"
|
||||
)]
|
||||
fn from(value: nssa::Account) -> Self {
|
||||
// Convert account data to FFI type
|
||||
let data_vec: Vec<u8> = value.data.into();
|
||||
let data_len = data_vec.len();
|
||||
let data = if data_len > 0 {
|
||||
let data_boxed = data_vec.into_boxed_slice();
|
||||
Box::into_raw(data_boxed) as *const u8
|
||||
} else {
|
||||
ptr::null()
|
||||
};
|
||||
let (data, data_len, data_cap) = value.data.into_inner().into_raw_parts();
|
||||
|
||||
let program_owner = FfiProgramId {
|
||||
data: value.program_owner,
|
||||
@ -155,15 +41,41 @@ impl From<nssa::Account> for FfiAccount {
|
||||
balance: value.balance.into(),
|
||||
data,
|
||||
data_len,
|
||||
data_cap,
|
||||
nonce: value.nonce.0.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<nssa::PublicKey> for FfiPublicAccountKey {
|
||||
fn from(value: nssa::PublicKey) -> Self {
|
||||
impl From<FfiAccount> for indexer_service_protocol::Account {
|
||||
fn from(value: FfiAccount) -> Self {
|
||||
Self {
|
||||
public_key: FfiBytes32::from_bytes(*value.value()),
|
||||
program_owner: ProgramId(value.program_owner.data),
|
||||
balance: value.balance.into(),
|
||||
data: indexer_service_protocol::Data(unsafe {
|
||||
Vec::from_raw_parts(value.data, value.data_len, value.data_cap)
|
||||
}),
|
||||
nonce: value.nonce.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Frees the resources associated with the given ffi account.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `val`: An instance of `FfiAccount`.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// void.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must ensure that:
|
||||
/// - `val` is a valid instance of `FfiAccount`.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn free_ffi_account(val: FfiAccount) {
|
||||
let orig_val: indexer_service_protocol::Account = val.into();
|
||||
drop(orig_val);
|
||||
}
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
use indexer_service_protocol::{BedrockStatus, Block, BlockHeader};
|
||||
use indexer_service_protocol::{
|
||||
BedrockStatus, Block, BlockHeader, HashType, MantleMsgId, Signature,
|
||||
};
|
||||
|
||||
use crate::api::types::{
|
||||
FfiBlockId, FfiHashType, FfiMsgId, FfiOption, FfiSignature, FfiTimestamp, vectors::FfiBlockBody,
|
||||
FfiBlockId, FfiHashType, FfiMsgId, FfiOption, FfiSignature, FfiTimestamp, FfiVec,
|
||||
transaction::free_ffi_transaction_vec, vectors::FfiBlockBody,
|
||||
};
|
||||
|
||||
#[repr(C)]
|
||||
@ -29,6 +32,23 @@ impl From<Block> for FfiBlock {
|
||||
}
|
||||
}
|
||||
|
||||
// impl From<Box<FfiBlock>> for Block {
|
||||
// fn from(value: Box<FfiBlock>) -> Self {
|
||||
// Self {
|
||||
// header: BlockHeader {
|
||||
// block_id: value.header.block_id,
|
||||
// prev_block_hash: HashType(value.header.prev_block_hash.data),
|
||||
// hash: HashType(value.header.hash.data),
|
||||
// timestamp: value.header.timestamp,
|
||||
// signature: Signature(value.header.signature.data),
|
||||
// },
|
||||
// body: (),
|
||||
// bedrock_status: value.bedrock_status.into(),
|
||||
// bedrock_parent_id: MantleMsgId(value.bedrock_parent_id.data),
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
pub type FfiBlockOpt = FfiOption<FfiBlock>;
|
||||
|
||||
#[repr(C)]
|
||||
@ -68,3 +88,115 @@ impl From<BedrockStatus> for FfiBedrockStatus {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FfiBedrockStatus> for BedrockStatus {
|
||||
fn from(value: FfiBedrockStatus) -> Self {
|
||||
match value {
|
||||
FfiBedrockStatus::Finalized => Self::Finalized,
|
||||
FfiBedrockStatus::Pending => Self::Pending,
|
||||
FfiBedrockStatus::Safe => Self::Safe,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Frees the resources associated with the given ffi block.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `val`: An instance of `FfiBlock`.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// void.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must ensure that:
|
||||
/// - `val` is a valid instance of `FfiBlock`.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn free_ffi_block(val: FfiBlock) {
|
||||
// We don't really need all the casts, but just in case
|
||||
// All except `ffi_tx_ffi_vec` is Copy types, so no need for Drop
|
||||
let _ = BlockHeader {
|
||||
block_id: val.header.block_id,
|
||||
prev_block_hash: HashType(val.header.prev_block_hash.data),
|
||||
hash: HashType(val.header.hash.data),
|
||||
timestamp: val.header.timestamp,
|
||||
signature: Signature(val.header.signature.data),
|
||||
};
|
||||
let ffi_tx_ffi_vec = val.body;
|
||||
|
||||
#[expect(clippy::let_underscore_must_use, reason = "No use for this Copy type")]
|
||||
let _: BedrockStatus = val.bedrock_status.into();
|
||||
|
||||
let _ = MantleMsgId(val.bedrock_parent_id.data);
|
||||
|
||||
unsafe {
|
||||
free_ffi_transaction_vec(ffi_tx_ffi_vec);
|
||||
};
|
||||
}
|
||||
|
||||
/// Frees the resources associated with the given ffi block option.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `val`: An instance of `FfiBlockOpt`.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// void.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must ensure that:
|
||||
/// - `val` is a valid instance of `FfiBlockOpt`.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn free_ffi_block_opt(val: FfiBlockOpt) {
|
||||
if val.is_some {
|
||||
let value = unsafe { Box::from_raw(val.value) };
|
||||
|
||||
// We don't really need all the casts, but just in case
|
||||
// All except `ffi_tx_ffi_vec` is Copy types, so no need for Drop
|
||||
let _ = BlockHeader {
|
||||
block_id: value.header.block_id,
|
||||
prev_block_hash: HashType(value.header.prev_block_hash.data),
|
||||
hash: HashType(value.header.hash.data),
|
||||
timestamp: value.header.timestamp,
|
||||
signature: Signature(value.header.signature.data),
|
||||
};
|
||||
let ffi_tx_ffi_vec = value.body;
|
||||
|
||||
#[expect(clippy::let_underscore_must_use, reason = "No use for this Copy type")]
|
||||
let _: BedrockStatus = value.bedrock_status.into();
|
||||
|
||||
let _ = MantleMsgId(value.bedrock_parent_id.data);
|
||||
|
||||
unsafe {
|
||||
free_ffi_transaction_vec(ffi_tx_ffi_vec);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// Frees the resources associated with the given ffi block vector.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `val`: An instance of `FfiVec<FfiBlock>`.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// void.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must ensure that:
|
||||
/// - `val` is a valid instance of `FfiVec<FfiBlock>`.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn free_ffi_block_vec(val: FfiVec<FfiBlock>) {
|
||||
let ffi_block_std_vec: Vec<_> = val.into();
|
||||
for block in ffi_block_std_vec {
|
||||
unsafe {
|
||||
free_ffi_block(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,72 @@
|
||||
use indexer_service_protocol::{AccountId, HashType, MantleMsgId, PublicKey, Signature};
|
||||
|
||||
use crate::api::types::account::{FfiBytes32, FfiBytes64, FfiU128};
|
||||
use indexer_service_protocol::{AccountId, HashType, MantleMsgId, ProgramId, PublicKey, Signature};
|
||||
|
||||
pub mod account;
|
||||
pub mod block;
|
||||
pub mod transaction;
|
||||
pub mod vectors;
|
||||
|
||||
/// 32-byte array type for `AccountId`, keys, hashes, etc.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Default)]
|
||||
pub struct FfiBytes32 {
|
||||
pub data: [u8; 32],
|
||||
}
|
||||
|
||||
/// 64-byte array type for signatures, etc.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct FfiBytes64 {
|
||||
pub data: [u8; 64],
|
||||
}
|
||||
|
||||
/// Program ID - 8 u32 values (32 bytes total).
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Default)]
|
||||
pub struct FfiProgramId {
|
||||
pub data: [u32; 8],
|
||||
}
|
||||
|
||||
impl From<ProgramId> for FfiProgramId {
|
||||
fn from(value: ProgramId) -> Self {
|
||||
Self { data: value.0 }
|
||||
}
|
||||
}
|
||||
|
||||
/// U128 - 16 bytes little endian.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Default)]
|
||||
pub struct FfiU128 {
|
||||
pub data: [u8; 16],
|
||||
}
|
||||
|
||||
impl FfiBytes32 {
|
||||
/// Create from a 32-byte array.
|
||||
#[must_use]
|
||||
pub const fn from_bytes(bytes: [u8; 32]) -> Self {
|
||||
Self { data: bytes }
|
||||
}
|
||||
|
||||
/// Create from an `AccountId`.
|
||||
#[must_use]
|
||||
pub const fn from_account_id(id: &nssa::AccountId) -> Self {
|
||||
Self { data: *id.value() }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u128> for FfiU128 {
|
||||
fn from(value: u128) -> Self {
|
||||
Self {
|
||||
data: value.to_le_bytes(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FfiU128> for u128 {
|
||||
fn from(value: FfiU128) -> Self {
|
||||
Self::from_le_bytes(value.data)
|
||||
}
|
||||
}
|
||||
|
||||
pub type FfiHashType = FfiBytes32;
|
||||
pub type FfiMsgId = FfiBytes32;
|
||||
pub type FfiBlockId = u64;
|
||||
@ -64,6 +124,12 @@ impl<T> From<Vec<T>> for FfiVec<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<FfiVec<T>> for Vec<T> {
|
||||
fn from(value: FfiVec<T>) -> Self {
|
||||
unsafe { Self::from_raw_parts(value.entries, value.len, value.capacity) }
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct FfiOption<T> {
|
||||
pub value: *mut T,
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
use indexer_service_protocol::{
|
||||
CommitmentSetDigest, EncryptedAccountData, Nullifier, PrivacyPreservingMessage,
|
||||
PrivacyPreservingTransaction, ProgramDeploymentTransaction, PublicKey, PublicMessage,
|
||||
PublicTransaction, Signature, Transaction, ValidityWindow,
|
||||
AccountId, Ciphertext, Commitment, CommitmentSetDigest, EncryptedAccountData,
|
||||
EphemeralPublicKey, HashType, Nullifier, PrivacyPreservingMessage,
|
||||
PrivacyPreservingTransaction, ProgramDeploymentMessage, ProgramDeploymentTransaction,
|
||||
ProgramId, Proof, PublicKey, PublicMessage, PublicTransaction, Signature, Transaction,
|
||||
ValidityWindow, WitnessSet,
|
||||
};
|
||||
|
||||
use crate::api::types::{
|
||||
FfiHashType, FfiPublicKey, FfiSignature,
|
||||
account::{FfiBytes32, FfiProgramId},
|
||||
FfiBytes32, FfiHashType, FfiOption, FfiProgramId, FfiPublicKey, FfiSignature, FfiVec,
|
||||
vectors::{
|
||||
FfiAccountIdList, FfiAccountList, FfiEncryptedAccountDataList, FfiInstructionDataList,
|
||||
FfiNonceList, FfiNullifierCommitmentSetList, FfiProgramDeploymentMessage, FfiProof,
|
||||
@ -37,6 +38,46 @@ impl From<PublicTransaction> for FfiPublicTransactionBody {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Box<FfiPublicTransactionBody>> for PublicTransaction {
|
||||
fn from(value: Box<FfiPublicTransactionBody>) -> Self {
|
||||
Self {
|
||||
hash: HashType(value.hash.data),
|
||||
message: PublicMessage {
|
||||
program_id: ProgramId(value.message.program_id.data),
|
||||
account_ids: {
|
||||
let std_vec: Vec<_> = value.message.account_ids.into();
|
||||
std_vec
|
||||
.into_iter()
|
||||
.map(|ffi_val| AccountId {
|
||||
value: ffi_val.data,
|
||||
})
|
||||
.collect()
|
||||
},
|
||||
nonces: {
|
||||
let std_vec: Vec<_> = value.message.nonces.into();
|
||||
std_vec.into_iter().map(Into::into).collect()
|
||||
},
|
||||
instruction_data: value.message.instruction_data.into(),
|
||||
},
|
||||
witness_set: WitnessSet {
|
||||
signatures_and_public_keys: {
|
||||
let std_vec: Vec<_> = value.witness_set.into();
|
||||
std_vec
|
||||
.into_iter()
|
||||
.map(|ffi_val| {
|
||||
(
|
||||
Signature(ffi_val.signature.data),
|
||||
PublicKey(ffi_val.public_key.data),
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
},
|
||||
proof: None,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct FfiPublicMessage {
|
||||
pub program_id: FfiProgramId,
|
||||
@ -96,6 +137,84 @@ impl From<PrivacyPreservingTransaction> for FfiPrivateTransactionBody {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Box<FfiPrivateTransactionBody>> for PrivacyPreservingTransaction {
|
||||
fn from(value: Box<FfiPrivateTransactionBody>) -> Self {
|
||||
Self {
|
||||
hash: HashType(value.hash.data),
|
||||
message: PrivacyPreservingMessage {
|
||||
public_account_ids: {
|
||||
let std_vec: Vec<_> = value.message.public_account_ids.into();
|
||||
std_vec
|
||||
.into_iter()
|
||||
.map(|ffi_val| AccountId {
|
||||
value: ffi_val.data,
|
||||
})
|
||||
.collect()
|
||||
},
|
||||
nonces: {
|
||||
let std_vec: Vec<_> = value.message.nonces.into();
|
||||
std_vec.into_iter().map(Into::into).collect()
|
||||
},
|
||||
public_post_states: {
|
||||
let std_vec: Vec<_> = value.message.public_post_states.into();
|
||||
std_vec.into_iter().map(Into::into).collect()
|
||||
},
|
||||
encrypted_private_post_states: {
|
||||
let std_vec: Vec<_> = value.message.encrypted_private_post_states.into();
|
||||
std_vec
|
||||
.into_iter()
|
||||
.map(|ffi_val| EncryptedAccountData {
|
||||
ciphertext: Ciphertext(ffi_val.ciphertext.into()),
|
||||
epk: EphemeralPublicKey(ffi_val.epk.into()),
|
||||
view_tag: ffi_val.view_tag,
|
||||
})
|
||||
.collect()
|
||||
},
|
||||
new_commitments: {
|
||||
let std_vec: Vec<_> = value.message.new_commitments.into();
|
||||
std_vec
|
||||
.into_iter()
|
||||
.map(|ffi_val| Commitment(ffi_val.data))
|
||||
.collect()
|
||||
},
|
||||
new_nullifiers: {
|
||||
let std_vec: Vec<_> = value.message.new_nullifiers.into();
|
||||
std_vec
|
||||
.into_iter()
|
||||
.map(|ffi_val| {
|
||||
(
|
||||
Nullifier(ffi_val.nullifier.data),
|
||||
CommitmentSetDigest(ffi_val.commitment_set_digest.data),
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
},
|
||||
block_validity_window: cast_ffi_validity_window(
|
||||
value.message.block_validity_window,
|
||||
),
|
||||
timestamp_validity_window: cast_ffi_validity_window(
|
||||
value.message.timestamp_validity_window,
|
||||
),
|
||||
},
|
||||
witness_set: WitnessSet {
|
||||
signatures_and_public_keys: {
|
||||
let std_vec: Vec<_> = value.witness_set.into();
|
||||
std_vec
|
||||
.into_iter()
|
||||
.map(|ffi_val| {
|
||||
(
|
||||
Signature(ffi_val.signature.data),
|
||||
PublicKey(ffi_val.public_key.data),
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
},
|
||||
proof: Some(Proof(value.proof.into())),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct FfiPrivacyPreservingMessage {
|
||||
pub public_account_ids: FfiAccountIdList,
|
||||
@ -209,6 +328,17 @@ pub struct FfiProgramDeploymentTransactionBody {
|
||||
pub message: FfiProgramDeploymentMessage,
|
||||
}
|
||||
|
||||
impl From<Box<FfiProgramDeploymentTransactionBody>> for ProgramDeploymentTransaction {
|
||||
fn from(value: Box<FfiProgramDeploymentTransactionBody>) -> Self {
|
||||
Self {
|
||||
hash: HashType(value.hash.data),
|
||||
message: ProgramDeploymentMessage {
|
||||
bytecode: value.message.into(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ProgramDeploymentTransaction> for FfiProgramDeploymentTransactionBody {
|
||||
fn from(value: ProgramDeploymentTransaction) -> Self {
|
||||
Self {
|
||||
@ -269,9 +399,123 @@ pub enum FfiTransactionKind {
|
||||
ProgramDeploy,
|
||||
}
|
||||
|
||||
/// Frees the resources associated with the given ffi transaction.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `val`: An instance of `FfiTransaction`.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// void.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must ensure that:
|
||||
/// - `val` is a valid instance of `FfiTransaction`.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn free_ffi_transaction(val: FfiTransaction) {
|
||||
match val.kind {
|
||||
FfiTransactionKind::Public => {
|
||||
let body = unsafe { Box::from_raw(val.body.public_body) };
|
||||
let std_body: PublicTransaction = body.into();
|
||||
drop(std_body);
|
||||
}
|
||||
FfiTransactionKind::Private => {
|
||||
let body = unsafe { Box::from_raw(val.body.private_body) };
|
||||
let std_body: PrivacyPreservingTransaction = body.into();
|
||||
drop(std_body);
|
||||
}
|
||||
FfiTransactionKind::ProgramDeploy => {
|
||||
let body = unsafe { Box::from_raw(val.body.program_deployment_body) };
|
||||
let std_body: ProgramDeploymentTransaction = body.into();
|
||||
drop(std_body);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Frees the resources associated with the given ffi transaction option.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `val`: An instance of `FfiOption<FfiTransaction>`.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// void.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must ensure that:
|
||||
/// - `val` is a valid instance of `FfiOption<FfiTransaction>`.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn free_ffi_transaction_opt(val: FfiOption<FfiTransaction>) {
|
||||
if val.is_some {
|
||||
let value = unsafe { Box::from_raw(val.value) };
|
||||
|
||||
match value.kind {
|
||||
FfiTransactionKind::Public => {
|
||||
let body = unsafe { Box::from_raw(value.body.public_body) };
|
||||
let std_body: PublicTransaction = body.into();
|
||||
drop(std_body);
|
||||
}
|
||||
FfiTransactionKind::Private => {
|
||||
let body = unsafe { Box::from_raw(value.body.private_body) };
|
||||
let std_body: PrivacyPreservingTransaction = body.into();
|
||||
drop(std_body);
|
||||
}
|
||||
FfiTransactionKind::ProgramDeploy => {
|
||||
let body = unsafe { Box::from_raw(value.body.program_deployment_body) };
|
||||
let std_body: ProgramDeploymentTransaction = body.into();
|
||||
drop(std_body);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Frees the resources associated with the given vector of ffi transactions.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `val`: An instance of `FfiVec<FfiTransaction>`.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// void.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must ensure that:
|
||||
/// - `val` is a valid instance of `FfiVec<FfiTransaction>`.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn free_ffi_transaction_vec(val: FfiVec<FfiTransaction>) {
|
||||
let ffi_tx_std_vec: Vec<_> = val.into();
|
||||
for tx in ffi_tx_std_vec {
|
||||
unsafe {
|
||||
free_ffi_transaction(tx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn cast_validity_window(window: ValidityWindow) -> [u64; 2] {
|
||||
[
|
||||
window.0.0.unwrap_or_default(),
|
||||
window.0.1.unwrap_or(u64::MAX),
|
||||
]
|
||||
}
|
||||
|
||||
const fn cast_ffi_validity_window(ffi_window: [u64; 2]) -> ValidityWindow {
|
||||
let left = if ffi_window[0] == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(ffi_window[0])
|
||||
};
|
||||
|
||||
let right = if ffi_window[1] == u64::MAX {
|
||||
None
|
||||
} else {
|
||||
Some(ffi_window[1])
|
||||
};
|
||||
|
||||
ValidityWindow((left, right))
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use crate::api::types::{
|
||||
FfiAccountId, FfiNonce, FfiVec,
|
||||
account::{FfiAccount, FfiBytes32},
|
||||
FfiAccountId, FfiBytes32, FfiNonce, FfiVec,
|
||||
account::FfiAccount,
|
||||
transaction::{
|
||||
FfiEncryptedAccountData, FfiNullifierCommitmentSet, FfiSignaturePubKeyEntry, FfiTransaction,
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user