mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-05-12 02:59:29 +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 = [
|
dependencies = [
|
||||||
"cbindgen",
|
"cbindgen",
|
||||||
"indexer_service",
|
"indexer_service",
|
||||||
|
"indexer_service_rpc",
|
||||||
"log",
|
"log",
|
||||||
"sequencer_core",
|
"sequencer_core",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
|||||||
@ -7,6 +7,7 @@ version = "0.1.0"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
indexer_service.workspace = true
|
indexer_service.workspace = true
|
||||||
sequencer_core.workspace = true
|
sequencer_core.workspace = true
|
||||||
|
indexer_service_rpc.workspace = true
|
||||||
|
|
||||||
url.workspace = true
|
url.workspace = true
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
|
|||||||
@ -7,6 +7,7 @@ typedef enum OperationStatus {
|
|||||||
Ok = 0,
|
Ok = 0,
|
||||||
NullPointer = 1,
|
NullPointer = 1,
|
||||||
InitializationError = 2,
|
InitializationError = 2,
|
||||||
|
ClientError = 3,
|
||||||
} OperationStatus;
|
} OperationStatus;
|
||||||
|
|
||||||
typedef struct IndexerServiceFFI {
|
typedef struct IndexerServiceFFI {
|
||||||
@ -28,6 +29,17 @@ typedef struct PointerResult_IndexerServiceFFI__OperationStatus {
|
|||||||
|
|
||||||
typedef struct PointerResult_IndexerServiceFFI__OperationStatus InitializedIndexerServiceFFIResult;
|
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
|
* Creates and starts an indexer based on the provided
|
||||||
* configuration file path.
|
* configuration file path.
|
||||||
@ -72,6 +84,26 @@ enum OperationStatus stop_indexer(struct IndexerServiceFFI *indexer);
|
|||||||
*/
|
*/
|
||||||
void free_cstring(char *block);
|
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_ok(const enum OperationStatus *self);
|
||||||
|
|
||||||
bool is_error(const enum OperationStatus *self);
|
bool is_error(const enum OperationStatus *self);
|
||||||
|
|||||||
@ -3,4 +3,5 @@ pub use result::PointerResult;
|
|||||||
pub mod client;
|
pub mod client;
|
||||||
pub mod lifecycle;
|
pub mod lifecycle;
|
||||||
pub mod memory;
|
pub mod memory;
|
||||||
|
pub mod query;
|
||||||
pub mod result;
|
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,
|
Ok = 0x0,
|
||||||
NullPointer = 0x1,
|
NullPointer = 0x1,
|
||||||
InitializationError = 0x2,
|
InitializationError = 0x2,
|
||||||
|
ClientError = 0x3,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OperationStatus {
|
impl OperationStatus {
|
||||||
|
|||||||
@ -88,6 +88,22 @@ impl IndexerServiceFFI {
|
|||||||
.expect("Indexer Client must be non-null pointer")
|
.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
|
// Implement Drop to prevent memory leaks
|
||||||
|
|||||||
@ -268,6 +268,11 @@ impl BlockingTestContextFFI {
|
|||||||
pub fn runtime_clone(&self) -> Arc<tokio::runtime::Runtime> {
|
pub fn runtime_clone(&self) -> Arc<tokio::runtime::Runtime> {
|
||||||
Arc::<tokio::runtime::Runtime>::clone(&self.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 {
|
impl Drop for BlockingTestContextFFI {
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
)]
|
)]
|
||||||
|
|
||||||
use anyhow::{Context as _, Result};
|
use anyhow::{Context as _, Result};
|
||||||
|
use indexer_ffi::{IndexerServiceFFI, OperationStatus, api::PointerResult};
|
||||||
use indexer_service_rpc::RpcClient as _;
|
use indexer_service_rpc::RpcClient as _;
|
||||||
use integration_tests::{
|
use integration_tests::{
|
||||||
TIME_TO_WAIT_FOR_BLOCK_SECONDS, format_private_account_id, format_public_account_id,
|
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.
|
/// Maximum time to wait for the indexer to catch up to the sequencer.
|
||||||
const L2_TO_L1_TIMEOUT_MILLIS: u64 = 180_000;
|
const L2_TO_L1_TIMEOUT_MILLIS: u64 = 180_000;
|
||||||
|
|
||||||
|
unsafe extern "C" {
|
||||||
|
unsafe fn query_last_block(
|
||||||
|
indexer: *const IndexerServiceFFI,
|
||||||
|
) -> PointerResult<u64, OperationStatus>;
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn indexer_test_run_ffi() -> Result<()> {
|
fn indexer_test_run_ffi() -> Result<()> {
|
||||||
let blocking_ctx = BlockingTestContextFFI::new()?;
|
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 = 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 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 > 1);
|
||||||
|
assert!(last_block_indexer_ffi > 1);
|
||||||
|
|
||||||
|
assert_eq!(last_block_indexer, last_block_indexer_ffi);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user