mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-05-08 17:19:45 +00:00
fix: all ffi tests added
This commit is contained in:
parent
a921d63750
commit
dd3ac54318
38
Cargo.lock
generated
38
Cargo.lock
generated
@ -1111,7 +1111,7 @@ dependencies = [
|
||||
"log",
|
||||
"num",
|
||||
"pin-project-lite",
|
||||
"rand 0.9.2",
|
||||
"rand 0.9.3",
|
||||
"rustls",
|
||||
"rustls-native-certs",
|
||||
"rustls-pki-types",
|
||||
@ -2506,7 +2506,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb330bbd4cb7a5b9f559427f06f98a4f853a137c8298f3bd3f8ca57663e21986"
|
||||
dependencies = [
|
||||
"portable-atomic",
|
||||
"rand 0.9.2",
|
||||
"rand 0.9.3",
|
||||
"web-time",
|
||||
]
|
||||
|
||||
@ -3838,7 +3838,7 @@ dependencies = [
|
||||
"jsonrpsee-types",
|
||||
"parking_lot",
|
||||
"pin-project",
|
||||
"rand 0.9.2",
|
||||
"rand 0.9.3",
|
||||
"rustc-hash",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@ -4055,7 +4055,7 @@ dependencies = [
|
||||
"oco_ref",
|
||||
"or_poisoned",
|
||||
"paste",
|
||||
"rand 0.9.2",
|
||||
"rand 0.9.3",
|
||||
"reactive_graph",
|
||||
"rustc-hash",
|
||||
"rustc_version",
|
||||
@ -5934,7 +5934,7 @@ checksum = "37566cb3fdacef14c0737f9546df7cfeadbfbc9fef10991038bf5015d0c80532"
|
||||
dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"num-traits",
|
||||
"rand 0.9.2",
|
||||
"rand 0.9.3",
|
||||
"rand_chacha 0.9.0",
|
||||
"rand_xorshift",
|
||||
"unarray",
|
||||
@ -5967,7 +5967,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.11.0",
|
||||
"itertools 0.14.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.117",
|
||||
@ -5980,7 +5980,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.11.0",
|
||||
"itertools 0.14.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.117",
|
||||
@ -6038,7 +6038,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"getrandom 0.3.4",
|
||||
"lru-slab",
|
||||
"rand 0.9.2",
|
||||
"rand 0.9.3",
|
||||
"ring",
|
||||
"rustc-hash",
|
||||
"rustls",
|
||||
@ -6126,9 +6126,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.9.2"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
|
||||
checksum = "7ec095654a25171c2124e9e3393a930bddbffdc939556c914957a4c3e0a87166"
|
||||
dependencies = [
|
||||
"rand_chacha 0.9.0",
|
||||
"rand_core 0.9.5",
|
||||
@ -6430,7 +6430,7 @@ dependencies = [
|
||||
"elf",
|
||||
"lazy_static",
|
||||
"postcard",
|
||||
"rand 0.9.2",
|
||||
"rand 0.9.3",
|
||||
"risc0-zkp",
|
||||
"risc0-zkvm-platform",
|
||||
"ruint",
|
||||
@ -6526,7 +6526,7 @@ dependencies = [
|
||||
"hex",
|
||||
"lazy-regex",
|
||||
"metal",
|
||||
"rand 0.9.2",
|
||||
"rand 0.9.3",
|
||||
"rayon",
|
||||
"risc0-circuit-recursion-sys",
|
||||
"risc0-core",
|
||||
@ -6570,7 +6570,7 @@ dependencies = [
|
||||
"num-traits",
|
||||
"paste",
|
||||
"postcard",
|
||||
"rand 0.9.2",
|
||||
"rand 0.9.3",
|
||||
"rayon",
|
||||
"ringbuffer",
|
||||
"risc0-binfmt",
|
||||
@ -6677,7 +6677,7 @@ dependencies = [
|
||||
"ndarray",
|
||||
"parking_lot",
|
||||
"paste",
|
||||
"rand 0.9.2",
|
||||
"rand 0.9.3",
|
||||
"rand_core 0.9.5",
|
||||
"rayon",
|
||||
"risc0-core",
|
||||
@ -6715,7 +6715,7 @@ dependencies = [
|
||||
"num-traits",
|
||||
"object",
|
||||
"prost 0.13.5",
|
||||
"rand 0.9.2",
|
||||
"rand 0.9.3",
|
||||
"rayon",
|
||||
"risc0-binfmt",
|
||||
"risc0-build",
|
||||
@ -6803,7 +6803,7 @@ dependencies = [
|
||||
"futures",
|
||||
"light-poseidon",
|
||||
"quote",
|
||||
"rand 0.9.2",
|
||||
"rand 0.9.3",
|
||||
"syn 1.0.109",
|
||||
"thiserror 2.0.18",
|
||||
"tiny-keccak",
|
||||
@ -6854,7 +6854,7 @@ dependencies = [
|
||||
"borsh",
|
||||
"proptest",
|
||||
"rand 0.8.5",
|
||||
"rand 0.9.2",
|
||||
"rand 0.9.3",
|
||||
"ruint-macro",
|
||||
"serde_core",
|
||||
"valuable",
|
||||
@ -6956,7 +6956,7 @@ dependencies = [
|
||||
"security-framework",
|
||||
"security-framework-sys",
|
||||
"webpki-root-certs 0.26.11",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -8407,7 +8407,7 @@ dependencies = [
|
||||
"http",
|
||||
"httparse",
|
||||
"log",
|
||||
"rand 0.9.2",
|
||||
"rand 0.9.3",
|
||||
"sha1",
|
||||
"thiserror 2.0.18",
|
||||
"utf-8",
|
||||
|
||||
@ -122,37 +122,40 @@ impl IndexerStore {
|
||||
{
|
||||
let mut state_guard = self.current_state.write().await;
|
||||
|
||||
let (clock_tx, user_txs) = block
|
||||
.body
|
||||
.transactions
|
||||
.split_last()
|
||||
.ok_or_else(|| anyhow::anyhow!("Block has no transactions"))?;
|
||||
// Genesis block do not update clocks
|
||||
if block.header.block_id != 1 {
|
||||
let (clock_tx, user_txs) = block
|
||||
.body
|
||||
.transactions
|
||||
.split_last()
|
||||
.ok_or_else(|| anyhow::anyhow!("Block has no transactions"))?;
|
||||
|
||||
anyhow::ensure!(
|
||||
*clock_tx == NSSATransaction::Public(clock_invocation(block.header.timestamp)),
|
||||
"Last transaction in block must be the clock invocation for the block timestamp"
|
||||
);
|
||||
anyhow::ensure!(
|
||||
*clock_tx == NSSATransaction::Public(clock_invocation(block.header.timestamp)),
|
||||
"Last transaction in block must be the clock invocation for the block timestamp"
|
||||
);
|
||||
|
||||
for transaction in user_txs {
|
||||
transaction
|
||||
.clone()
|
||||
.transaction_stateless_check()?
|
||||
.execute_check_on_state(
|
||||
&mut state_guard,
|
||||
block.header.block_id,
|
||||
block.header.timestamp,
|
||||
)?;
|
||||
for transaction in user_txs {
|
||||
transaction
|
||||
.clone()
|
||||
.transaction_stateless_check()?
|
||||
.execute_check_on_state(
|
||||
&mut state_guard,
|
||||
block.header.block_id,
|
||||
block.header.timestamp,
|
||||
)?;
|
||||
}
|
||||
|
||||
// Apply the clock invocation directly (it is expected to modify clock accounts).
|
||||
let NSSATransaction::Public(clock_public_tx) = clock_tx else {
|
||||
anyhow::bail!("Clock invocation must be a public transaction");
|
||||
};
|
||||
state_guard.transition_from_public_transaction(
|
||||
clock_public_tx,
|
||||
block.header.block_id,
|
||||
block.header.timestamp,
|
||||
)?;
|
||||
}
|
||||
|
||||
// Apply the clock invocation directly (it is expected to modify clock accounts).
|
||||
let NSSATransaction::Public(clock_public_tx) = clock_tx else {
|
||||
anyhow::bail!("Clock invocation must be a public transaction");
|
||||
};
|
||||
state_guard.transition_from_public_transaction(
|
||||
clock_public_tx,
|
||||
block.header.block_id,
|
||||
block.header.timestamp,
|
||||
)?;
|
||||
}
|
||||
|
||||
// ToDo: Currently we are fetching only finalized blocks
|
||||
|
||||
@ -143,8 +143,9 @@ impl IndexerCore {
|
||||
l2_blocks_parsed_ids.sort_unstable();
|
||||
info!("Parsed {} L2 blocks with ids {:?}", l2_block_vec.len(), l2_blocks_parsed_ids);
|
||||
|
||||
for l2_block in l2_block_vec {
|
||||
self.store.put_block(l2_block.clone(), l1_header).await?;
|
||||
for l2_block in l2_block_vec {
|
||||
self.store.put_block(l2_block.clone(), l1_header).await
|
||||
.inspect_err(|err| error!("Failed to put block with err {err:?}"))?;
|
||||
|
||||
yield Ok(l2_block);
|
||||
}
|
||||
|
||||
@ -438,10 +438,20 @@ impl BlockingTestContextFFI {
|
||||
self.ctx.as_ref().expect("TestContext is set")
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn ctx_mut(&mut self) -> &mut TestContextFFI {
|
||||
self.ctx.as_mut().expect("TestContext is set")
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn runtime(&self) -> &Arc<tokio::runtime::Runtime> {
|
||||
&self.runtime
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn runtime_clone(&self) -> Arc<tokio::runtime::Runtime> {
|
||||
Arc::<tokio::runtime::Runtime>::clone(&self.runtime)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for BlockingTestContextFFI {
|
||||
|
||||
@ -272,7 +272,256 @@ fn indexer_test_run_ffi() -> Result<()> {
|
||||
|
||||
let last_block_indexer = blocking_ctx.ctx().get_last_block_indexer(runtime_wrapped)?;
|
||||
|
||||
info!("Last block on ind now is {last_block_indexer}");
|
||||
|
||||
assert!(last_block_indexer > 1);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn indexer_ffi_block_batching() -> Result<()> {
|
||||
let blocking_ctx = BlockingTestContextFFI::new()?;
|
||||
let runtime_wrapped = blocking_ctx.runtime();
|
||||
let ctx = blocking_ctx.ctx();
|
||||
|
||||
// WAIT
|
||||
info!("Waiting for indexer to parse blocks");
|
||||
runtime_wrapped.block_on(async {
|
||||
tokio::time::sleep(std::time::Duration::from_millis(L2_TO_L1_TIMEOUT_MILLIS)).await;
|
||||
});
|
||||
|
||||
let last_block_indexer = runtime_wrapped
|
||||
.block_on(ctx.indexer_client().get_last_finalized_block_id())
|
||||
.unwrap();
|
||||
|
||||
info!("Last block on ind now is {last_block_indexer}");
|
||||
|
||||
assert!(last_block_indexer > 1);
|
||||
|
||||
// Getting wide batch to fit all blocks (from latest backwards)
|
||||
let mut block_batch = runtime_wrapped
|
||||
.block_on(ctx.indexer_client().get_blocks(None, 100))
|
||||
.unwrap();
|
||||
|
||||
// Reverse to check chain consistency from oldest to newest
|
||||
block_batch.reverse();
|
||||
|
||||
// Checking chain consistency
|
||||
let mut prev_block_hash = block_batch.first().unwrap().header.hash;
|
||||
|
||||
for block in &block_batch[1..] {
|
||||
assert_eq!(block.header.prev_block_hash, prev_block_hash);
|
||||
|
||||
info!("Block {} chain-consistent", block.header.block_id);
|
||||
|
||||
prev_block_hash = block.header.hash;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn indexer_ffi_state_consistency() -> Result<()> {
|
||||
let mut blocking_ctx = BlockingTestContextFFI::new()?;
|
||||
let runtime_wrapped = blocking_ctx.runtime_clone();
|
||||
let ctx = blocking_ctx.ctx_mut();
|
||||
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: Some(format_public_account_id(ctx.existing_public_accounts()[0])),
|
||||
from_label: None,
|
||||
to: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: 100,
|
||||
});
|
||||
|
||||
runtime_wrapped.block_on(wallet::cli::execute_subcommand(ctx.wallet_mut(), command))?;
|
||||
|
||||
info!("Waiting for next block creation");
|
||||
runtime_wrapped.block_on(async {
|
||||
tokio::time::sleep(std::time::Duration::from_millis(
|
||||
TIME_TO_WAIT_FOR_BLOCK_SECONDS,
|
||||
))
|
||||
.await;
|
||||
});
|
||||
|
||||
info!("Checking correct balance move");
|
||||
let acc_1_balance =
|
||||
runtime_wrapped.block_on(sequencer_service_rpc::RpcClient::get_account_balance(
|
||||
ctx.sequencer_client(),
|
||||
ctx.existing_public_accounts()[0],
|
||||
))?;
|
||||
let acc_2_balance =
|
||||
runtime_wrapped.block_on(sequencer_service_rpc::RpcClient::get_account_balance(
|
||||
ctx.sequencer_client(),
|
||||
ctx.existing_public_accounts()[1],
|
||||
))?;
|
||||
|
||||
info!("Balance of sender: {acc_1_balance:#?}");
|
||||
info!("Balance of receiver: {acc_2_balance:#?}");
|
||||
|
||||
assert_eq!(acc_1_balance, 9900);
|
||||
assert_eq!(acc_2_balance, 20100);
|
||||
|
||||
let from: AccountId = ctx.existing_private_accounts()[0];
|
||||
let to: AccountId = ctx.existing_private_accounts()[1];
|
||||
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: Some(format_private_account_id(from)),
|
||||
from_label: None,
|
||||
to: Some(format_private_account_id(to)),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: 100,
|
||||
});
|
||||
|
||||
runtime_wrapped.block_on(wallet::cli::execute_subcommand(ctx.wallet_mut(), command))?;
|
||||
|
||||
info!("Waiting for next block creation");
|
||||
runtime_wrapped.block_on(async {
|
||||
tokio::time::sleep(std::time::Duration::from_millis(
|
||||
TIME_TO_WAIT_FOR_BLOCK_SECONDS,
|
||||
))
|
||||
.await;
|
||||
});
|
||||
|
||||
let new_commitment1 = ctx
|
||||
.wallet()
|
||||
.get_private_account_commitment(from)
|
||||
.context("Failed to get private account commitment for sender")?;
|
||||
let commitment_check1 = runtime_wrapped.block_on(verify_commitment_is_in_state(
|
||||
new_commitment1,
|
||||
ctx.sequencer_client(),
|
||||
));
|
||||
assert!(commitment_check1);
|
||||
|
||||
let new_commitment2 = ctx
|
||||
.wallet()
|
||||
.get_private_account_commitment(to)
|
||||
.context("Failed to get private account commitment for receiver")?;
|
||||
let commitment_check2 = runtime_wrapped.block_on(verify_commitment_is_in_state(
|
||||
new_commitment2,
|
||||
ctx.sequencer_client(),
|
||||
));
|
||||
assert!(commitment_check2);
|
||||
|
||||
info!("Successfully transferred privately to owned account");
|
||||
|
||||
// WAIT
|
||||
info!("Waiting for indexer to parse blocks");
|
||||
runtime_wrapped.block_on(async {
|
||||
tokio::time::sleep(std::time::Duration::from_millis(L2_TO_L1_TIMEOUT_MILLIS)).await;
|
||||
});
|
||||
|
||||
let acc1_ind_state = runtime_wrapped.block_on(
|
||||
ctx.indexer_client()
|
||||
.get_account(ctx.existing_public_accounts()[0].into()),
|
||||
)?;
|
||||
let acc2_ind_state = runtime_wrapped.block_on(
|
||||
ctx.indexer_client()
|
||||
.get_account(ctx.existing_public_accounts()[1].into()),
|
||||
)?;
|
||||
|
||||
info!("Checking correct state transition");
|
||||
let acc1_seq_state =
|
||||
runtime_wrapped.block_on(sequencer_service_rpc::RpcClient::get_account(
|
||||
ctx.sequencer_client(),
|
||||
ctx.existing_public_accounts()[0],
|
||||
))?;
|
||||
let acc2_seq_state =
|
||||
runtime_wrapped.block_on(sequencer_service_rpc::RpcClient::get_account(
|
||||
ctx.sequencer_client(),
|
||||
ctx.existing_public_accounts()[1],
|
||||
))?;
|
||||
|
||||
assert_eq!(acc1_ind_state, acc1_seq_state.into());
|
||||
assert_eq!(acc2_ind_state, acc2_seq_state.into());
|
||||
|
||||
// ToDo: Check private state transition
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn indexer_ffi_state_consistency_with_labels() -> Result<()> {
|
||||
let mut blocking_ctx = BlockingTestContextFFI::new()?;
|
||||
let runtime_wrapped = blocking_ctx.runtime_clone();
|
||||
let ctx = blocking_ctx.ctx_mut();
|
||||
|
||||
// Assign labels to both accounts
|
||||
let from_label = "idx-sender-label".to_owned();
|
||||
let to_label_str = "idx-receiver-label".to_owned();
|
||||
|
||||
let label_cmd = Command::Account(wallet::cli::account::AccountSubcommand::Label {
|
||||
account_id: Some(format_public_account_id(ctx.existing_public_accounts()[0])),
|
||||
account_label: None,
|
||||
label: from_label.clone(),
|
||||
});
|
||||
runtime_wrapped.block_on(wallet::cli::execute_subcommand(ctx.wallet_mut(), label_cmd))?;
|
||||
|
||||
let label_cmd = Command::Account(wallet::cli::account::AccountSubcommand::Label {
|
||||
account_id: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
|
||||
account_label: None,
|
||||
label: to_label_str.clone(),
|
||||
});
|
||||
runtime_wrapped.block_on(wallet::cli::execute_subcommand(ctx.wallet_mut(), label_cmd))?;
|
||||
|
||||
// Send using labels instead of account IDs
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: None,
|
||||
from_label: Some(from_label),
|
||||
to: None,
|
||||
to_label: Some(to_label_str),
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: 100,
|
||||
});
|
||||
|
||||
runtime_wrapped.block_on(wallet::cli::execute_subcommand(ctx.wallet_mut(), command))?;
|
||||
|
||||
info!("Waiting for next block creation");
|
||||
runtime_wrapped.block_on(async {
|
||||
tokio::time::sleep(std::time::Duration::from_millis(
|
||||
TIME_TO_WAIT_FOR_BLOCK_SECONDS,
|
||||
))
|
||||
.await;
|
||||
});
|
||||
|
||||
let acc_1_balance =
|
||||
runtime_wrapped.block_on(sequencer_service_rpc::RpcClient::get_account_balance(
|
||||
ctx.sequencer_client(),
|
||||
ctx.existing_public_accounts()[0],
|
||||
))?;
|
||||
let acc_2_balance =
|
||||
runtime_wrapped.block_on(sequencer_service_rpc::RpcClient::get_account_balance(
|
||||
ctx.sequencer_client(),
|
||||
ctx.existing_public_accounts()[1],
|
||||
))?;
|
||||
|
||||
assert_eq!(acc_1_balance, 9900);
|
||||
assert_eq!(acc_2_balance, 20100);
|
||||
|
||||
info!("Waiting for indexer to parse blocks");
|
||||
runtime_wrapped.block_on(async {
|
||||
tokio::time::sleep(std::time::Duration::from_millis(L2_TO_L1_TIMEOUT_MILLIS)).await;
|
||||
});
|
||||
|
||||
let acc1_ind_state = runtime_wrapped.block_on(
|
||||
ctx.indexer_client()
|
||||
.get_account(ctx.existing_public_accounts()[0].into()),
|
||||
)?;
|
||||
let acc1_seq_state =
|
||||
runtime_wrapped.block_on(sequencer_service_rpc::RpcClient::get_account(
|
||||
ctx.sequencer_client(),
|
||||
ctx.existing_public_accounts()[0],
|
||||
))?;
|
||||
|
||||
assert_eq!(acc1_ind_state, acc1_seq_state.into());
|
||||
|
||||
info!("Indexer state is consistent after label-based transfer");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user