From b736b229ef69d39adbf210f08384a54489c442ba Mon Sep 17 00:00:00 2001 From: Pravdyvy Date: Fri, 24 Apr 2026 17:37:09 +0300 Subject: [PATCH] fix: types halfway done --- indexer_ffi/indexer_ffi.h | 113 +++++++++++++++++++++++++++++++++ indexer_ffi/src/api/convert.rs | 12 ++++ indexer_ffi/src/api/mod.rs | 2 + indexer_ffi/src/api/query.rs | 41 +++++++++++- indexer_ffi/src/api/types.rs | 99 +++++++++++++++++++++++++++++ 5 files changed, 266 insertions(+), 1 deletion(-) create mode 100644 indexer_ffi/src/api/convert.rs create mode 100644 indexer_ffi/src/api/types.rs diff --git a/indexer_ffi/indexer_ffi.h b/indexer_ffi/indexer_ffi.h index 1db1784a..b734b59f 100644 --- a/indexer_ffi/indexer_ffi.h +++ b/indexer_ffi/indexer_ffi.h @@ -10,6 +10,24 @@ typedef enum OperationStatus { ClientError = 3, } OperationStatus; +typedef enum TransactionKind { + Public = 0, + Private, + ProgramDeploy, +} TransactionKind; + +typedef enum BedrockStatus { + Pending = 0, + Safe, + Finalized, +} BedrockStatus; + +typedef struct Vec_AccountId Vec_AccountId; + +typedef struct Vec_Nonce Vec_Nonce; + +typedef struct Vec_u32 Vec_u32; + typedef struct IndexerServiceFFI { void *indexer_handle; void *runtime; @@ -40,6 +58,80 @@ typedef struct PointerResult_u64__OperationStatus { enum OperationStatus error; } PointerResult_u64__OperationStatus; +typedef uint64_t BlockId; + +typedef uint8_t HashType[32]; + +typedef uint64_t Timestamp; + +typedef uint8_t Signature[64]; + +typedef struct BlockHeader { + BlockId block_id; + HashType prev_block_hash; + HashType hash; + Timestamp timestamp; + Signature signature; +} BlockHeader; + +typedef uint32_t ProgramId[8]; + +typedef struct PublicMessage { + ProgramId program_id; + struct Vec_AccountId account_ids; + struct Vec_Nonce nonces; + struct Vec_u32 instruction_data; +} PublicMessage; + +typedef struct WitnessSet { + +} WitnessSet; + +typedef struct PublicTransactionBody { + HashType hash; + struct PublicMessage message; + struct WitnessSet witness_set; +} PublicTransactionBody; + +typedef struct TransactionBody { + struct PublicTransactionBody *public_body; +} TransactionBody; + +typedef struct Transaction { + struct TransactionBody body; + enum TransactionKind kind; +} Transaction; + +typedef struct BlockBody { + struct Transaction *txs; + uintptr_t len; +} BlockBody; + +typedef uint8_t MsgId[32]; + +typedef struct Block { + struct BlockHeader header; + struct BlockBody body; + enum BedrockStatus bedrock_status; + MsgId bedrock_parent_id; +} Block; + +typedef struct BlockOpt { + struct Block *block; + bool is_ok; +} BlockOpt; + +/** + * 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_BlockOpt__OperationStatus { + struct BlockOpt *value; + enum OperationStatus error; +} PointerResult_BlockOpt__OperationStatus; + /** * Creates and starts an indexer based on the provided * configuration file path. @@ -104,6 +196,27 @@ void free_cstring(char *block); */ struct PointerResult_u64__OperationStatus query_last_block(const struct IndexerServiceFFI *indexer); +/** + * Stops and frees the resources associated with the given indexer service. + * + * # Arguments + * + * - `indexer`: A pointer to the `IndexerServiceFFI` instance to be stopped. + * + * # Returns + * + * An `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_BlockOpt__OperationStatus query_block(const struct IndexerServiceFFI *indexer, + BlockId block_id); + bool is_ok(const enum OperationStatus *self); bool is_error(const enum OperationStatus *self); diff --git a/indexer_ffi/src/api/convert.rs b/indexer_ffi/src/api/convert.rs new file mode 100644 index 00000000..d970de38 --- /dev/null +++ b/indexer_ffi/src/api/convert.rs @@ -0,0 +1,12 @@ +use crate::api::types::BlockOpt; + +impl From> for BlockOpt { + fn from(value: Option) -> Self { + match value { + None => BlockOpt { block: std::ptr::null_mut(), is_ok: false }, + Some(block_orig) => BlockOpt { block: block_orig.into(), is_ok: true } + } + } +} + +impl From<> \ No newline at end of file diff --git a/indexer_ffi/src/api/mod.rs b/indexer_ffi/src/api/mod.rs index 43284dc8..9221a65c 100644 --- a/indexer_ffi/src/api/mod.rs +++ b/indexer_ffi/src/api/mod.rs @@ -5,3 +5,5 @@ pub mod lifecycle; pub mod memory; pub mod query; pub mod result; +pub mod types; +pub mod convert; diff --git a/indexer_ffi/src/api/query.rs b/indexer_ffi/src/api/query.rs index 9f9523cf..c4dd26b1 100644 --- a/indexer_ffi/src/api/query.rs +++ b/indexer_ffi/src/api/query.rs @@ -1,6 +1,6 @@ use indexer_service_rpc::RpcClient; -use crate::{IndexerServiceFFI, api::PointerResult, errors::OperationStatus}; +use crate::{IndexerServiceFFI, api::{PointerResult, types::{Block, BlockId, BlockOpt}}, errors::OperationStatus}; /// Stops and frees the resources associated with the given indexer service. /// @@ -39,3 +39,42 @@ pub unsafe extern "C" fn query_last_block( PointerResult::from_value, ) } + +/// Stops and frees the resources associated with the given indexer service. +/// +/// # Arguments +/// +/// - `indexer`: A pointer to the `IndexerServiceFFI` instance to be stopped. +/// +/// # Returns +/// +/// An `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, + block_id: BlockId, +) -> PointerResult { + 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_id(block_id)) + .map_or_else( + |_| PointerResult::from_error(OperationStatus::ClientError), + |block| PointerResult::from_value(block.into()), + ) +} diff --git a/indexer_ffi/src/api/types.rs b/indexer_ffi/src/api/types.rs new file mode 100644 index 00000000..920b4764 --- /dev/null +++ b/indexer_ffi/src/api/types.rs @@ -0,0 +1,99 @@ +pub type HashType = [u8; 32]; +pub type MsgId = [u8; 32]; +pub type BlockId = u64; +pub type Timestamp = u64; +pub type Signature = [u8; 64]; +pub type ProgramId = [u32; 8]; +pub type AccountId = [u8; 32]; +pub type Nonce = u128; +pub type PublicKey = [u8; 32]; + +#[repr(C)] +pub struct Block { + pub header: BlockHeader, + pub body: BlockBody, + pub bedrock_status: BedrockStatus, + pub bedrock_parent_id: MsgId, +} + +#[repr(C)] +pub struct BlockOpt { + pub block: *const Block, + pub is_ok: bool, +} + +#[repr(C)] +pub struct PublicMessage { + pub program_id: ProgramId, + pub account_ids: Vec, + pub nonces: Vec, + pub instruction_data: Vec, +} + +#[repr(C)] +pub struct PublicTransactionBody { + pub hash: HashType, + pub message: PublicMessage, + pub witness_set: Vec<(Signature, PublicKey)>, +} + +#[repr(C)] +pub struct PrivateTransactionBody { + +} + +#[repr(C)] +pub struct ProgramDeploymentTransactionBody { + +} + +#[repr(C)] +pub struct TransactionBody { + pub public_body: *const PublicTransactionBody, + pub private_body: *const PrivateTransactionBody, + pub program_deployment_body: *const ProgramDeploymentTransactionBody, +} + +#[repr(C)] +pub struct Transaction { + pub body: TransactionBody, + pub kind: TransactionKind, +} + +#[repr(C)] +pub struct BlockBody { + pub txs: *const Transaction, + pub len: usize, +} + +impl Default for BlockBody { + fn default() -> Self { + Self { + txs: std::ptr::null_mut(), + len: 0, + } + } +} + +#[repr(C)] +pub struct BlockHeader { + pub block_id: BlockId, + pub prev_block_hash: HashType, + pub hash: HashType, + pub timestamp: Timestamp, + pub signature: Signature, +} + +#[repr(C)] +pub enum BedrockStatus { + Pending = 0x0, + Safe, + Finalized, +} + +#[repr(C)] +pub enum TransactionKind { + Public = 0x0, + Private, + ProgramDeploy, +} \ No newline at end of file