diff --git a/artifacts/test_program_methods/group_pda_spender.bin b/artifacts/test_program_methods/group_pda_spender.bin new file mode 100644 index 00000000..16efb8a4 Binary files /dev/null and b/artifacts/test_program_methods/group_pda_spender.bin differ diff --git a/artifacts/test_program_methods/private_pda_claimer.bin b/artifacts/test_program_methods/private_pda_claimer.bin new file mode 100644 index 00000000..5a64c66d Binary files /dev/null and b/artifacts/test_program_methods/private_pda_claimer.bin differ diff --git a/indexer_ffi/Cargo.toml b/indexer_ffi/Cargo.toml deleted file mode 100644 index b55230c6..00000000 --- a/indexer_ffi/Cargo.toml +++ /dev/null @@ -1,25 +0,0 @@ -[package] -edition = "2024" -license = { workspace = true } -name = "indexer_ffi" -version = "0.1.0" - -[dependencies] -indexer_service.workspace = true -log = { workspace = true } -tokio = { features = ["rt-multi-thread"], workspace = true } - -[build-dependencies] -cbindgen = "0.29" - -[lib] -crate-type = ["rlib", "cdylib", "staticlib"] -name = "indexer_ffi" - -[lints] -workspace = true - -[package.metadata.cargo-machete] -ignored = [ - "cbindgen", -] # machete does not recognize this for build dep and complains. diff --git a/indexer_ffi/build.rs b/indexer_ffi/build.rs deleted file mode 100644 index 92c95407..00000000 --- a/indexer_ffi/build.rs +++ /dev/null @@ -1,12 +0,0 @@ -use std::env; - -fn main() { - let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); - println!("cargo:rerun-if-changed=src/"); - cbindgen::Builder::new() - .with_crate(crate_dir) - .with_language(cbindgen::Language::C) - .generate() - .expect("Unable to generate bindings") - .write_to_file("indexer_ffi.h"); -} diff --git a/indexer_ffi/cbindgen.toml b/indexer_ffi/cbindgen.toml deleted file mode 100644 index 79f622b7..00000000 --- a/indexer_ffi/cbindgen.toml +++ /dev/null @@ -1,2 +0,0 @@ -language = "C" # For increased compatibility -no_includes = true diff --git a/indexer_ffi/indexer_ffi.h b/indexer_ffi/indexer_ffi.h deleted file mode 100644 index 7c7d9a4d..00000000 --- a/indexer_ffi/indexer_ffi.h +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include -#include -#include - -typedef enum OperationStatus { - Ok = 0, - NullPointer = 1, - InitializationError = 2, -} OperationStatus; - -typedef struct IndexerServiceFFI { - void *indexer_handle; - void *runtime; -} IndexerServiceFFI; - -/** - * 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_IndexerServiceFFI__OperationStatus { - struct IndexerServiceFFI *value; - enum OperationStatus error; -} PointerResult_IndexerServiceFFI__OperationStatus; - -typedef struct PointerResult_IndexerServiceFFI__OperationStatus InitializedIndexerServiceFFIResult; - -/** - * Creates and starts an indexer based on the provided - * configuration file path. - * - * # Arguments - * - * - `config_path`: A pointer to a string representing the path to the configuration file. - * - `port`: Number representing a port, on which indexers RPC will start. - * - * # Returns - * - * An `InitializedIndexerServiceFFIResult` containing either a pointer to the - * initialized `IndexerServiceFFI` or an error code. - */ -InitializedIndexerServiceFFIResult start_indexer(const char *config_path, uint16_t port); - -/** - * 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 - */ -enum OperationStatus stop_indexer(struct IndexerServiceFFI *indexer); - -/** - * # Safety - * It's up to the caller to pass a proper pointer, if somehow from c/c++ side - * this is called with a type which doesn't come from a returned `CString` it - * will cause a segfault. - */ -void free_cstring(char *block); - -bool is_ok(const enum OperationStatus *self); - -bool is_error(const enum OperationStatus *self); diff --git a/indexer_ffi/src/api/lifecycle.rs b/indexer_ffi/src/api/lifecycle.rs deleted file mode 100644 index 735efd4d..00000000 --- a/indexer_ffi/src/api/lifecycle.rs +++ /dev/null @@ -1,100 +0,0 @@ -use std::{ffi::c_char, path::PathBuf}; - -use tokio::runtime::Runtime; - -use crate::{IndexerServiceFFI, api::PointerResult, errors::OperationStatus}; - -pub type InitializedIndexerServiceFFIResult = PointerResult; - -/// Creates and starts an indexer based on the provided -/// configuration file path. -/// -/// # Arguments -/// -/// - `config_path`: A pointer to a string representing the path to the configuration file. -/// - `port`: Number representing a port, on which indexers RPC will start. -/// -/// # Returns -/// -/// An `InitializedIndexerServiceFFIResult` containing either a pointer to the -/// initialized `IndexerServiceFFI` or an error code. -#[unsafe(no_mangle)] -pub extern "C" fn start_indexer( - config_path: *const c_char, - port: u16, -) -> InitializedIndexerServiceFFIResult { - setup_indexer(config_path, port).map_or_else( - InitializedIndexerServiceFFIResult::from_error, - InitializedIndexerServiceFFIResult::from_value, - ) -} - -/// Initializes and starts an indexer based on the provided -/// configuration file path. -/// -/// # Arguments -/// -/// - `config_path`: A pointer to a string representing the path to the configuration file. -/// - `port`: Number representing a port, on which indexers RPC will start. -/// -/// # Returns -/// -/// A `Result` containing either the initialized `IndexerServiceFFI` or an -/// error code. -fn setup_indexer( - config_path: *const c_char, - port: u16, -) -> Result { - let user_config_path = PathBuf::from( - unsafe { std::ffi::CStr::from_ptr(config_path) } - .to_str() - .map_err(|e| { - log::error!("Could not convert the config path to string: {e}"); - OperationStatus::InitializationError - })?, - ); - let config = indexer_service::IndexerConfig::from_path(&user_config_path).map_err(|e| { - log::error!("Failed to read config: {e}"); - OperationStatus::InitializationError - })?; - - let rt = Runtime::new().unwrap(); - - let indexer_handle = rt - .block_on(indexer_service::run_server(config, port)) - .map_err(|e| { - log::error!("Could not start indexer service: {e}"); - OperationStatus::InitializationError - })?; - - Ok(IndexerServiceFFI::new(indexer_handle, rt)) -} - -/// 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 stop_indexer(indexer: *mut IndexerServiceFFI) -> OperationStatus { - if indexer.is_null() { - log::error!("Attempted to stop a null indexer pointer. This is a bug. Aborting."); - return OperationStatus::NullPointer; - } - - let indexer = unsafe { Box::from_raw(indexer) }; - drop(indexer); - - OperationStatus::Ok -} diff --git a/indexer_ffi/src/api/memory.rs b/indexer_ffi/src/api/memory.rs deleted file mode 100644 index f266d309..00000000 --- a/indexer_ffi/src/api/memory.rs +++ /dev/null @@ -1,14 +0,0 @@ -use std::ffi::{CString, c_char}; - -/// # Safety -/// It's up to the caller to pass a proper pointer, if somehow from c/c++ side -/// this is called with a type which doesn't come from a returned `CString` it -/// will cause a segfault. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn free_cstring(block: *mut c_char) { - if block.is_null() { - log::error!("Trying to free a null pointer. Exiting"); - return; - } - drop(unsafe { CString::from_raw(block) }); -} diff --git a/indexer_ffi/src/api/mod.rs b/indexer_ffi/src/api/mod.rs deleted file mode 100644 index e84a3913..00000000 --- a/indexer_ffi/src/api/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub use result::PointerResult; - -pub mod lifecycle; -pub mod memory; -pub mod result; diff --git a/indexer_ffi/src/api/result.rs b/indexer_ffi/src/api/result.rs deleted file mode 100644 index 96cbcdd8..00000000 --- a/indexer_ffi/src/api/result.rs +++ /dev/null @@ -1,29 +0,0 @@ -/// 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. -#[repr(C)] -pub struct PointerResult { - pub value: *mut Type, - pub error: Error, -} - -impl PointerResult { - pub fn from_pointer(pointer: *mut Type) -> Self { - Self { - value: pointer, - error: Error::default(), - } - } - - pub fn from_value(value: Type) -> Self { - Self::from_pointer(Box::into_raw(Box::new(value))) - } - - pub const fn from_error(error: Error) -> Self { - Self { - value: std::ptr::null_mut(), - error, - } - } -} diff --git a/indexer_ffi/src/errors.rs b/indexer_ffi/src/errors.rs deleted file mode 100644 index 46aa0f9f..00000000 --- a/indexer_ffi/src/errors.rs +++ /dev/null @@ -1,22 +0,0 @@ -#[derive(Debug, Default, PartialEq, Eq)] -#[repr(C)] -pub enum OperationStatus { - #[default] - Ok = 0x0, - NullPointer = 0x1, - InitializationError = 0x2, -} - -impl OperationStatus { - #[must_use] - #[unsafe(no_mangle)] - pub extern "C" fn is_ok(&self) -> bool { - *self == Self::Ok - } - - #[must_use] - #[unsafe(no_mangle)] - pub extern "C" fn is_error(&self) -> bool { - !self.is_ok() - } -} diff --git a/indexer_ffi/src/indexer.rs b/indexer_ffi/src/indexer.rs deleted file mode 100644 index c110b183..00000000 --- a/indexer_ffi/src/indexer.rs +++ /dev/null @@ -1,86 +0,0 @@ -use std::{ffi::c_void, net::SocketAddr}; - -use indexer_service::IndexerHandle; -use tokio::runtime::Runtime; - -#[repr(C)] -pub struct IndexerServiceFFI { - indexer_handle: *mut c_void, - runtime: *mut c_void, -} - -impl IndexerServiceFFI { - pub fn new(indexer_handle: indexer_service::IndexerHandle, runtime: Runtime) -> Self { - Self { - // Box the complex types and convert to opaque pointers - indexer_handle: Box::into_raw(Box::new(indexer_handle)).cast::(), - runtime: Box::into_raw(Box::new(runtime)).cast::(), - } - } - - /// Helper to take ownership back. - /// - /// # Safety - /// - /// The caller must ensure that: - /// - `self` is a valid object(contains valid pointers in all fields) - #[must_use] - pub unsafe fn into_parts(self) -> (Box, Box) { - let indexer_handle = unsafe { Box::from_raw(self.indexer_handle.cast::()) }; - let runtime = unsafe { Box::from_raw(self.runtime.cast::()) }; - (indexer_handle, runtime) - } - - /// Helper to get indexer handle addr. - /// - /// # Safety - /// - /// The caller must ensure that: - /// - `self` is a valid object(contains valid pointers in all fields) - #[must_use] - pub const unsafe fn addr(&self) -> SocketAddr { - let indexer_handle = unsafe { - self.indexer_handle - .cast::() - .as_ref() - .expect("Indexer Handle must be non-null pointer") - }; - - indexer_handle.addr() - } - - /// Helper to get indexer handle addr. - /// - /// # Safety - /// - /// The caller must ensure that: - /// - `self` is a valid object(contains valid pointers in all fields) - #[must_use] - pub const unsafe fn handle(&self) -> &IndexerHandle { - unsafe { - self.indexer_handle - .cast::() - .as_ref() - .expect("Indexer Handle must be non-null pointer") - } - } -} - -// Implement Drop to prevent memory leaks -impl Drop for IndexerServiceFFI { - fn drop(&mut self) { - let Self { - indexer_handle, - runtime, - } = self; - - if indexer_handle.is_null() { - log::error!("Attempted to drop a null indexer pointer. This is a bug"); - } - if runtime.is_null() { - log::error!("Attempted to drop a null tokio runtime pointer. This is a bug"); - } - drop(unsafe { Box::from_raw(indexer_handle.cast::()) }); - drop(unsafe { Box::from_raw(runtime.cast::()) }); - } -} diff --git a/indexer_ffi/src/lib.rs b/indexer_ffi/src/lib.rs deleted file mode 100644 index fe594ec0..00000000 --- a/indexer_ffi/src/lib.rs +++ /dev/null @@ -1,8 +0,0 @@ -#![allow(clippy::undocumented_unsafe_blocks, reason = "It is an FFI")] - -pub use errors::OperationStatus; -pub use indexer::IndexerServiceFFI; - -pub mod api; -mod errors; -mod indexer;