mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-05-13 03:30:05 +00:00
feat: indexer client added to ffi
This commit is contained in:
parent
ad6a55c55d
commit
9880a46bdc
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -3485,7 +3485,9 @@ dependencies = [
|
|||||||
"cbindgen",
|
"cbindgen",
|
||||||
"indexer_service",
|
"indexer_service",
|
||||||
"log",
|
"log",
|
||||||
|
"sequencer_core",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@ -6,6 +6,9 @@ version = "0.1.0"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
indexer_service.workspace = true
|
indexer_service.workspace = true
|
||||||
|
sequencer_core.workspace = true
|
||||||
|
|
||||||
|
url.workspace = true
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
tokio = { features = ["rt-multi-thread"], workspace = true }
|
tokio = { features = ["rt-multi-thread"], workspace = true }
|
||||||
|
|
||||||
|
|||||||
@ -12,6 +12,7 @@ typedef enum OperationStatus {
|
|||||||
typedef struct IndexerServiceFFI {
|
typedef struct IndexerServiceFFI {
|
||||||
void *indexer_handle;
|
void *indexer_handle;
|
||||||
void *runtime;
|
void *runtime;
|
||||||
|
void *indexer_client;
|
||||||
} IndexerServiceFFI;
|
} IndexerServiceFFI;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
36
indexer_ffi/src/api/client.rs
Normal file
36
indexer_ffi/src/api/client.rs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
use crate::OperationStatus;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub enum UrlProtocol {
|
||||||
|
Http,
|
||||||
|
Ws,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for UrlProtocol {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Http => write!(f, "http"),
|
||||||
|
Self::Ws => write!(f, "ws"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn addr_to_url(protocol: UrlProtocol, addr: SocketAddr) -> Result<Url, OperationStatus> {
|
||||||
|
// Convert 0.0.0.0 to 127.0.0.1 for client connections
|
||||||
|
// When binding to port 0, the server binds to 0.0.0.0:<random_port>
|
||||||
|
// but clients need to connect to 127.0.0.1:<port> to work reliably
|
||||||
|
let url_string = if addr.ip().is_unspecified() {
|
||||||
|
format!("{protocol}://127.0.0.1:{}", addr.port())
|
||||||
|
} else {
|
||||||
|
format!("{protocol}://{addr}")
|
||||||
|
};
|
||||||
|
|
||||||
|
url_string.parse().map_err(|e| {
|
||||||
|
log::error!("Could not parse indexer url: {e}");
|
||||||
|
OperationStatus::InitializationError
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -1,8 +1,16 @@
|
|||||||
use std::{ffi::c_char, path::PathBuf};
|
use std::{ffi::c_char, path::PathBuf};
|
||||||
|
|
||||||
|
use sequencer_core::indexer_client::{IndexerClient, IndexerClientTrait};
|
||||||
use tokio::runtime::Runtime;
|
use tokio::runtime::Runtime;
|
||||||
|
|
||||||
use crate::{IndexerServiceFFI, api::PointerResult, errors::OperationStatus};
|
use crate::{
|
||||||
|
IndexerServiceFFI,
|
||||||
|
api::{
|
||||||
|
PointerResult,
|
||||||
|
client::{UrlProtocol, addr_to_url},
|
||||||
|
},
|
||||||
|
errors::OperationStatus,
|
||||||
|
};
|
||||||
|
|
||||||
pub type InitializedIndexerServiceFFIResult = PointerResult<IndexerServiceFFI, OperationStatus>;
|
pub type InitializedIndexerServiceFFIResult = PointerResult<IndexerServiceFFI, OperationStatus>;
|
||||||
|
|
||||||
@ -67,7 +75,13 @@ fn setup_indexer(
|
|||||||
OperationStatus::InitializationError
|
OperationStatus::InitializationError
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(IndexerServiceFFI::new(indexer_handle, rt))
|
let indexer_url = addr_to_url(UrlProtocol::Ws, indexer_handle.addr())?;
|
||||||
|
let indexer_client = rt.block_on(IndexerClient::new(&indexer_url)).map_err(|e| {
|
||||||
|
log::error!("Could not start indexer client: {e}");
|
||||||
|
OperationStatus::InitializationError
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(IndexerServiceFFI::new(indexer_handle, rt, indexer_client))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stops and frees the resources associated with the given indexer service.
|
/// Stops and frees the resources associated with the given indexer service.
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
pub use result::PointerResult;
|
pub use result::PointerResult;
|
||||||
|
|
||||||
|
pub mod client;
|
||||||
pub mod lifecycle;
|
pub mod lifecycle;
|
||||||
pub mod memory;
|
pub mod memory;
|
||||||
pub mod result;
|
pub mod result;
|
||||||
|
|||||||
@ -1,20 +1,27 @@
|
|||||||
use std::{ffi::c_void, net::SocketAddr};
|
use std::{ffi::c_void, net::SocketAddr};
|
||||||
|
|
||||||
use indexer_service::IndexerHandle;
|
use indexer_service::IndexerHandle;
|
||||||
|
use sequencer_core::indexer_client::IndexerClient;
|
||||||
use tokio::runtime::Runtime;
|
use tokio::runtime::Runtime;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct IndexerServiceFFI {
|
pub struct IndexerServiceFFI {
|
||||||
indexer_handle: *mut c_void,
|
indexer_handle: *mut c_void,
|
||||||
runtime: *mut c_void,
|
runtime: *mut c_void,
|
||||||
|
indexer_client: *mut c_void,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IndexerServiceFFI {
|
impl IndexerServiceFFI {
|
||||||
pub fn new(indexer_handle: indexer_service::IndexerHandle, runtime: Runtime) -> Self {
|
pub fn new(
|
||||||
|
indexer_handle: indexer_service::IndexerHandle,
|
||||||
|
runtime: Runtime,
|
||||||
|
indexer_client: IndexerClient,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
// Box the complex types and convert to opaque pointers
|
// Box the complex types and convert to opaque pointers
|
||||||
indexer_handle: Box::into_raw(Box::new(indexer_handle)).cast::<c_void>(),
|
indexer_handle: Box::into_raw(Box::new(indexer_handle)).cast::<c_void>(),
|
||||||
runtime: Box::into_raw(Box::new(runtime)).cast::<c_void>(),
|
runtime: Box::into_raw(Box::new(runtime)).cast::<c_void>(),
|
||||||
|
indexer_client: Box::into_raw(Box::new(indexer_client)).cast::<c_void>(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,10 +32,11 @@ impl IndexerServiceFFI {
|
|||||||
/// The caller must ensure that:
|
/// The caller must ensure that:
|
||||||
/// - `self` is a valid object(contains valid pointers in all fields)
|
/// - `self` is a valid object(contains valid pointers in all fields)
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub unsafe fn into_parts(self) -> (Box<IndexerHandle>, Box<Runtime>) {
|
pub unsafe fn into_parts(self) -> (Box<IndexerHandle>, Box<Runtime>, Box<IndexerClient>) {
|
||||||
let indexer_handle = unsafe { Box::from_raw(self.indexer_handle.cast::<IndexerHandle>()) };
|
let indexer_handle = unsafe { Box::from_raw(self.indexer_handle.cast::<IndexerHandle>()) };
|
||||||
let runtime = unsafe { Box::from_raw(self.runtime.cast::<Runtime>()) };
|
let runtime = unsafe { Box::from_raw(self.runtime.cast::<Runtime>()) };
|
||||||
(indexer_handle, runtime)
|
let indexer_client = unsafe { Box::from_raw(self.indexer_client.cast::<IndexerClient>()) };
|
||||||
|
(indexer_handle, runtime, indexer_client)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper to get indexer handle addr.
|
/// Helper to get indexer handle addr.
|
||||||
@ -49,7 +57,7 @@ impl IndexerServiceFFI {
|
|||||||
indexer_handle.addr()
|
indexer_handle.addr()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper to get indexer handle addr.
|
/// Helper to get indexer handle ref.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
@ -64,6 +72,22 @@ impl IndexerServiceFFI {
|
|||||||
.expect("Indexer Handle must be non-null pointer")
|
.expect("Indexer Handle must be non-null pointer")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Helper to get indexer client ref.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// The caller must ensure that:
|
||||||
|
/// - `self` is a valid object(contains valid pointers in all fields)
|
||||||
|
#[must_use]
|
||||||
|
pub const unsafe fn client(&self) -> &IndexerClient {
|
||||||
|
unsafe {
|
||||||
|
self.indexer_client
|
||||||
|
.cast::<IndexerClient>()
|
||||||
|
.as_ref()
|
||||||
|
.expect("Indexer Client must be non-null pointer")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implement Drop to prevent memory leaks
|
// Implement Drop to prevent memory leaks
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user