mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-05-12 12:49:36 +00:00
feat: first query api
This commit is contained in:
parent
9880a46bdc
commit
9fc2e39c10
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -3484,6 +3484,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"cbindgen",
|
||||
"indexer_service",
|
||||
"indexer_service_rpc",
|
||||
"log",
|
||||
"sequencer_core",
|
||||
"tokio",
|
||||
|
||||
@ -7,6 +7,7 @@ version = "0.1.0"
|
||||
[dependencies]
|
||||
indexer_service.workspace = true
|
||||
sequencer_core.workspace = true
|
||||
indexer_service_rpc.workspace = true
|
||||
|
||||
url.workspace = true
|
||||
log = { workspace = true }
|
||||
|
||||
@ -7,6 +7,7 @@ typedef enum OperationStatus {
|
||||
Ok = 0,
|
||||
NullPointer = 1,
|
||||
InitializationError = 2,
|
||||
ClientError = 3,
|
||||
} OperationStatus;
|
||||
|
||||
typedef struct IndexerServiceFFI {
|
||||
@ -28,6 +29,17 @@ typedef struct PointerResult_IndexerServiceFFI__OperationStatus {
|
||||
|
||||
typedef struct PointerResult_IndexerServiceFFI__OperationStatus InitializedIndexerServiceFFIResult;
|
||||
|
||||
/**
|
||||
* 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_u64__OperationStatus {
|
||||
uint64_t *value;
|
||||
enum OperationStatus error;
|
||||
} PointerResult_u64__OperationStatus;
|
||||
|
||||
/**
|
||||
* Creates and starts an indexer based on the provided
|
||||
* configuration file path.
|
||||
@ -72,6 +84,26 @@ enum OperationStatus stop_indexer(struct IndexerServiceFFI *indexer);
|
||||
*/
|
||||
void free_cstring(char *block);
|
||||
|
||||
/**
|
||||
* 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_u64__OperationStatus query_last_block(const struct IndexerServiceFFI *indexer);
|
||||
|
||||
bool is_ok(const enum OperationStatus *self);
|
||||
|
||||
bool is_error(const enum OperationStatus *self);
|
||||
|
||||
@ -3,4 +3,5 @@ pub use result::PointerResult;
|
||||
pub mod client;
|
||||
pub mod lifecycle;
|
||||
pub mod memory;
|
||||
pub mod query;
|
||||
pub mod result;
|
||||
|
||||
41
indexer_ffi/src/api/query.rs
Normal file
41
indexer_ffi/src/api/query.rs
Normal file
@ -0,0 +1,41 @@
|
||||
use indexer_service_rpc::RpcClient;
|
||||
|
||||
use crate::{IndexerServiceFFI, api::PointerResult, errors::OperationStatus};
|
||||
|
||||
/// 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_last_block(
|
||||
indexer: *const IndexerServiceFFI,
|
||||
) -> PointerResult<u64, 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_last_finalized_block_id())
|
||||
.map_or_else(
|
||||
|_| PointerResult::from_error(OperationStatus::ClientError),
|
||||
PointerResult::from_value,
|
||||
)
|
||||
}
|
||||
@ -5,6 +5,7 @@ pub enum OperationStatus {
|
||||
Ok = 0x0,
|
||||
NullPointer = 0x1,
|
||||
InitializationError = 0x2,
|
||||
ClientError = 0x3,
|
||||
}
|
||||
|
||||
impl OperationStatus {
|
||||
|
||||
@ -88,6 +88,22 @@ impl IndexerServiceFFI {
|
||||
.expect("Indexer Client must be non-null pointer")
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper to get indexer runtime ref.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must ensure that:
|
||||
/// - `self` is a valid object(contains valid pointers in all fields)
|
||||
#[must_use]
|
||||
pub const unsafe fn runtime(&self) -> &Runtime {
|
||||
unsafe {
|
||||
self.runtime
|
||||
.cast::<Runtime>()
|
||||
.as_ref()
|
||||
.expect("Indexer Runtime must be non-null pointer")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Implement Drop to prevent memory leaks
|
||||
|
||||
@ -268,6 +268,11 @@ impl BlockingTestContextFFI {
|
||||
pub fn runtime_clone(&self) -> Arc<tokio::runtime::Runtime> {
|
||||
Arc::<tokio::runtime::Runtime>::clone(&self.runtime)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn indexer_ffi(&self) -> *const IndexerServiceFFI {
|
||||
&(self.indexer_ffi)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for BlockingTestContextFFI {
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
)]
|
||||
|
||||
use anyhow::{Context as _, Result};
|
||||
use indexer_ffi::{IndexerServiceFFI, OperationStatus, api::PointerResult};
|
||||
use indexer_service_rpc::RpcClient as _;
|
||||
use integration_tests::{
|
||||
TIME_TO_WAIT_FOR_BLOCK_SECONDS, format_private_account_id, format_public_account_id,
|
||||
@ -17,6 +18,12 @@ use wallet::cli::{Command, programs::native_token_transfer::AuthTransferSubcomma
|
||||
/// Maximum time to wait for the indexer to catch up to the sequencer.
|
||||
const L2_TO_L1_TIMEOUT_MILLIS: u64 = 180_000;
|
||||
|
||||
unsafe extern "C" {
|
||||
unsafe fn query_last_block(
|
||||
indexer: *const IndexerServiceFFI,
|
||||
) -> PointerResult<u64, OperationStatus>;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn indexer_test_run_ffi() -> Result<()> {
|
||||
let blocking_ctx = BlockingTestContextFFI::new()?;
|
||||
@ -28,10 +35,19 @@ fn indexer_test_run_ffi() -> Result<()> {
|
||||
});
|
||||
|
||||
let last_block_indexer = blocking_ctx.ctx().get_last_block_indexer(runtime_wrapped)?;
|
||||
let last_block_indexer_ffi_res = unsafe { query_last_block(blocking_ctx.indexer_ffi()) };
|
||||
|
||||
assert!(last_block_indexer_ffi_res.error.is_ok());
|
||||
|
||||
let last_block_indexer_ffi = unsafe { *last_block_indexer_ffi_res.value };
|
||||
|
||||
info!("Last block on ind now is {last_block_indexer}");
|
||||
info!("Last block on ind ffi now is {last_block_indexer_ffi}");
|
||||
|
||||
assert!(last_block_indexer > 1);
|
||||
assert!(last_block_indexer_ffi > 1);
|
||||
|
||||
assert_eq!(last_block_indexer, last_block_indexer_ffi);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user