mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-07-11 08:19:35 +00:00
fix(wallet_ffi): wallet_ffi fix
This commit is contained in:
parent
562696929c
commit
675e845237
@ -27,7 +27,7 @@ use wallet::WalletCore;
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
// Initialize wallet
|
||||
let wallet_core = WalletCore::from_env().unwrap();
|
||||
let wallet_core = WalletCore::from_env().await.unwrap();
|
||||
|
||||
// Parse arguments
|
||||
// First argument is the path to the program binary
|
||||
@ -59,7 +59,7 @@ async fn main() {
|
||||
|
||||
// Submit the transaction
|
||||
let _response = wallet_core
|
||||
.sequencer_client
|
||||
.leader_owned()
|
||||
.send_transaction(LeeTransaction::Public(tx))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
@ -23,7 +23,7 @@ use wallet::{AccountIdentity, WalletCore};
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
// Initialize wallet
|
||||
let wallet_core = WalletCore::from_env().unwrap();
|
||||
let mut wallet_core = WalletCore::from_env().await.unwrap();
|
||||
|
||||
// Parse arguments
|
||||
// First argument is the path to the program binary
|
||||
|
||||
@ -27,7 +27,7 @@ use wallet::WalletCore;
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
// Initialize wallet
|
||||
let wallet_core = WalletCore::from_env().unwrap();
|
||||
let wallet_core = WalletCore::from_env().await.unwrap();
|
||||
|
||||
// Parse arguments
|
||||
// First argument is the path to the program binary
|
||||
@ -55,7 +55,7 @@ async fn main() {
|
||||
|
||||
// Submit the transaction
|
||||
let _response = wallet_core
|
||||
.sequencer_client
|
||||
.leader_owned()
|
||||
.send_transaction(LeeTransaction::Public(tx))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
@ -26,7 +26,7 @@ use wallet::{AccountIdentity, WalletCore};
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
// Initialize wallet
|
||||
let wallet_core = WalletCore::from_env().unwrap();
|
||||
let mut wallet_core = WalletCore::from_env().await.unwrap();
|
||||
|
||||
// Parse arguments
|
||||
// First argument is the path to the simple_tail_call program binary
|
||||
|
||||
@ -29,7 +29,7 @@ use wallet::WalletCore;
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
// Initialize wallet
|
||||
let wallet_core = WalletCore::from_env().unwrap();
|
||||
let mut wallet_core = WalletCore::from_env().await.unwrap();
|
||||
|
||||
// Parse arguments
|
||||
// First argument is the path to the program binary
|
||||
@ -52,7 +52,8 @@ async fn main() {
|
||||
.storage()
|
||||
.key_chain()
|
||||
.pub_account_signing_key(account_id)
|
||||
.expect("Input account should be a self owned public account");
|
||||
.expect("Input account should be a self owned public account")
|
||||
.clone();
|
||||
|
||||
// Define the desired greeting in ASCII
|
||||
let greeting: Vec<u8> = vec![72, 111, 108, 97, 32, 109, 117, 110, 100, 111, 33];
|
||||
@ -63,7 +64,7 @@ async fn main() {
|
||||
.get_accounts_nonces(vec![account_id])
|
||||
.await
|
||||
.expect("Node should be reachable to query account data");
|
||||
let signing_keys = [signing_key];
|
||||
let signing_keys = [&signing_key];
|
||||
let message = Message::try_new(program.id(), vec![account_id], nonces, greeting).unwrap();
|
||||
// Pass the signing key to sign the message. This will be used by the node
|
||||
// to flag the pre_state as `is_authorized` when executing the program
|
||||
@ -72,7 +73,7 @@ async fn main() {
|
||||
|
||||
// Submit the transaction
|
||||
let _response = wallet_core
|
||||
.sequencer_client
|
||||
.leader_owned()
|
||||
.send_transaction(LeeTransaction::Public(tx))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
@ -35,7 +35,7 @@ const PDA_SEED: PdaSeed = PdaSeed::new([37; 32]);
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
// Initialize wallet
|
||||
let wallet_core = WalletCore::from_env().unwrap();
|
||||
let wallet_core = WalletCore::from_env().await.unwrap();
|
||||
|
||||
// Parse arguments
|
||||
// First argument is the path to the program binary
|
||||
@ -57,7 +57,7 @@ async fn main() {
|
||||
|
||||
// Submit the transaction
|
||||
let _response = wallet_core
|
||||
.sequencer_client
|
||||
.leader_owned()
|
||||
.send_transaction(LeeTransaction::Public(tx))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
@ -66,7 +66,7 @@ async fn main() {
|
||||
let program = Program::new(bytecode.into()).unwrap();
|
||||
|
||||
// Initialize wallet
|
||||
let wallet_core = WalletCore::from_env().unwrap();
|
||||
let mut wallet_core = WalletCore::from_env().await.unwrap();
|
||||
|
||||
match cli.command {
|
||||
Command::WritePublic {
|
||||
@ -88,7 +88,7 @@ async fn main() {
|
||||
|
||||
// Submit the transaction
|
||||
let _response = wallet_core
|
||||
.sequencer_client
|
||||
.leader_owned()
|
||||
.send_transaction(LeeTransaction::Public(tx))
|
||||
.await
|
||||
.unwrap();
|
||||
@ -127,7 +127,7 @@ async fn main() {
|
||||
|
||||
// Submit the transaction
|
||||
let _response = wallet_core
|
||||
.sequencer_client
|
||||
.leader_owned()
|
||||
.send_transaction(LeeTransaction::Public(tx))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
@ -440,7 +440,7 @@ async fn bedrock_deposit_claim_and_withdraw_round_trip_succeeds() -> anyhow::Res
|
||||
|
||||
// Now claim funds from vault back to recipient
|
||||
let nonces = ctx
|
||||
.wallet()
|
||||
.wallet_mut()
|
||||
.get_accounts_nonces(vec![recipient_id])
|
||||
.await
|
||||
.context("Failed to get nonce for vault claim")?;
|
||||
|
||||
@ -37,7 +37,7 @@ use wallet::{AccountIdentity, WalletCore};
|
||||
reason = "test helper — grouping args would obscure intent"
|
||||
)]
|
||||
async fn fund_private_pda(
|
||||
wallet: &WalletCore,
|
||||
wallet: &mut WalletCore,
|
||||
sender: AccountId,
|
||||
npk: NullifierPublicKey,
|
||||
vpk: ViewingPublicKey,
|
||||
@ -91,7 +91,7 @@ async fn fund_private_pda(
|
||||
let tx = PrivacyPreservingTransaction::new(message, witness_set);
|
||||
|
||||
wallet
|
||||
.sequencer_client
|
||||
.leader_owned()
|
||||
.send_transaction(LeeTransaction::PrivacyPreserving(tx))
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("send transaction failed: {e}"))?;
|
||||
@ -107,7 +107,7 @@ async fn fund_private_pda(
|
||||
reason = "test helper — grouping args would obscure intent"
|
||||
)]
|
||||
async fn spend_private_pda(
|
||||
wallet: &WalletCore,
|
||||
wallet: &mut WalletCore,
|
||||
pda_account_id: AccountId,
|
||||
recipient_npk: NullifierPublicKey,
|
||||
recipient_vpk: ViewingPublicKey,
|
||||
@ -180,7 +180,7 @@ async fn private_pda_family_members_receive_and_spend() -> Result<()> {
|
||||
|
||||
info!("Sending to alice_pda_0 (identifier=0)");
|
||||
fund_private_pda(
|
||||
ctx.wallet(),
|
||||
ctx.wallet_mut(),
|
||||
sender_0,
|
||||
alice_npk,
|
||||
alice_vpk.clone(),
|
||||
@ -194,7 +194,7 @@ async fn private_pda_family_members_receive_and_spend() -> Result<()> {
|
||||
|
||||
info!("Sending to alice_pda_1 (identifier=1)");
|
||||
fund_private_pda(
|
||||
ctx.wallet(),
|
||||
ctx.wallet_mut(),
|
||||
sender_1,
|
||||
alice_npk,
|
||||
alice_vpk.clone(),
|
||||
@ -262,7 +262,7 @@ async fn private_pda_family_members_receive_and_spend() -> Result<()> {
|
||||
|
||||
info!("Alice spending from alice_pda_0");
|
||||
spend_private_pda(
|
||||
ctx.wallet(),
|
||||
ctx.wallet_mut(),
|
||||
alice_pda_0_id,
|
||||
recipient_npk_0,
|
||||
recipient_vpk_0,
|
||||
@ -275,7 +275,7 @@ async fn private_pda_family_members_receive_and_spend() -> Result<()> {
|
||||
|
||||
info!("Alice spending from alice_pda_1");
|
||||
spend_private_pda(
|
||||
ctx.wallet(),
|
||||
ctx.wallet_mut(),
|
||||
alice_pda_1_id,
|
||||
recipient_npk_1,
|
||||
recipient_vpk_1,
|
||||
|
||||
@ -31,7 +31,10 @@ async fn deploy_and_execute_program() -> Result<()> {
|
||||
|
||||
let account_id = new_account(&mut ctx, false, None).await?;
|
||||
|
||||
let nonces = ctx.wallet().get_accounts_nonces(vec![account_id]).await?;
|
||||
let nonces = ctx
|
||||
.wallet_mut()
|
||||
.get_accounts_nonces(vec![account_id])
|
||||
.await?;
|
||||
let private_key = ctx
|
||||
.wallet()
|
||||
.get_account_public_signing_key(account_id)
|
||||
|
||||
@ -1794,7 +1794,7 @@ fn test_wallet_ffi_transfer_generic_private() -> Result<()> {
|
||||
|
||||
#[test]
|
||||
fn test_wallet_ffi_vault_balance_and_claim_public() -> Result<()> {
|
||||
let ctx = BlockingTestContext::new()?;
|
||||
let mut ctx = BlockingTestContext::new()?;
|
||||
let home = tempfile::tempdir()?;
|
||||
let FfiCreateWalletOutput {
|
||||
wallet: wallet_ffi_handle,
|
||||
@ -1808,7 +1808,7 @@ fn test_wallet_ffi_vault_balance_and_claim_public() -> Result<()> {
|
||||
|
||||
// Fund the owner's vault, simulating an L1 bridge deposit.
|
||||
ctx.block_on(|ctx| async move {
|
||||
Vault(ctx.wallet())
|
||||
Vault(ctx.wallet_mut())
|
||||
.send_transfer(sender, owner, amount)
|
||||
.await
|
||||
})
|
||||
@ -1894,7 +1894,7 @@ fn test_wallet_ffi_vault_balance_and_claim_private() -> Result<()> {
|
||||
// Fund the owner's vault. Real deposits always land via a public transfer (the bridge
|
||||
// program crediting the vault PDA), regardless of whether the owner is private.
|
||||
ctx.block_on(|ctx| async move {
|
||||
Vault(ctx.wallet())
|
||||
Vault(ctx.wallet_mut())
|
||||
.send_transfer(sender, owner, amount)
|
||||
.await
|
||||
})
|
||||
|
||||
@ -323,7 +323,7 @@ pub unsafe extern "C" fn wallet_ffi_get_balance(
|
||||
return WalletFfiError::NullPointer;
|
||||
}
|
||||
|
||||
let wallet = match wrapper.core.lock() {
|
||||
let mut wallet = match wrapper.core.lock() {
|
||||
Ok(w) => w,
|
||||
Err(e) => {
|
||||
print_error(format!("Failed to lock wallet: {e}"));
|
||||
@ -389,7 +389,7 @@ pub unsafe extern "C" fn wallet_ffi_get_account_public(
|
||||
return WalletFfiError::NullPointer;
|
||||
}
|
||||
|
||||
let wallet = match wrapper.core.lock() {
|
||||
let mut wallet = match wrapper.core.lock() {
|
||||
Ok(w) => w,
|
||||
Err(e) => {
|
||||
print_error(format!("Failed to lock wallet: {e}"));
|
||||
|
||||
@ -55,7 +55,7 @@ pub unsafe extern "C" fn wallet_ffi_bridge_withdraw(
|
||||
return WalletFfiError::NullPointer;
|
||||
}
|
||||
|
||||
let wallet = match wrapper.core.lock() {
|
||||
let mut wallet = match wrapper.core.lock() {
|
||||
Ok(w) => w,
|
||||
Err(e) => {
|
||||
print_error(format!("Failed to lock wallet: {e}"));
|
||||
@ -66,7 +66,7 @@ pub unsafe extern "C" fn wallet_ffi_bridge_withdraw(
|
||||
let from_id = AccountId::new(unsafe { (*from).data });
|
||||
let bedrock_account_pk = unsafe { (*bedrock_account_pk).data };
|
||||
|
||||
let bridge = Bridge(&wallet);
|
||||
let mut bridge = Bridge(&mut wallet);
|
||||
|
||||
match block_on(bridge.send_withdraw(from_id, amount, bedrock_account_pk)) {
|
||||
Ok(tx_hash) => {
|
||||
|
||||
@ -237,7 +237,7 @@ pub unsafe extern "C" fn wallet_ffi_send_generic_public_transaction(
|
||||
return WalletFfiError::NullPointer;
|
||||
}
|
||||
|
||||
let wallet = match wrapper.core.lock() {
|
||||
let mut wallet = match wrapper.core.lock() {
|
||||
Ok(w) => w,
|
||||
Err(e) => {
|
||||
print_error(format!("Failed to lock wallet: {e}"));
|
||||
@ -329,7 +329,7 @@ pub unsafe extern "C" fn wallet_ffi_send_generic_private_transaction(
|
||||
return WalletFfiError::NullPointer;
|
||||
}
|
||||
|
||||
let wallet = match wrapper.core.lock() {
|
||||
let mut wallet = match wrapper.core.lock() {
|
||||
Ok(w) => w,
|
||||
Err(e) => {
|
||||
print_error(format!("Failed to lock wallet: {e}"));
|
||||
|
||||
@ -60,7 +60,7 @@ pub unsafe extern "C" fn wallet_ffi_claim_pinata(
|
||||
return WalletFfiError::NullPointer;
|
||||
}
|
||||
|
||||
let wallet = match wrapper.core.lock() {
|
||||
let mut wallet = match wrapper.core.lock() {
|
||||
Ok(w) => w,
|
||||
Err(e) => {
|
||||
print_error(format!("Failed to lock wallet: {e}"));
|
||||
@ -72,7 +72,7 @@ pub unsafe extern "C" fn wallet_ffi_claim_pinata(
|
||||
let winner_id = AccountId::new(unsafe { (*winner_account_id).data });
|
||||
let solution = u128::from_le_bytes(unsafe { *solution });
|
||||
|
||||
let pinata = Pinata(&wallet);
|
||||
let mut pinata = Pinata(&mut wallet);
|
||||
|
||||
match block_on(pinata.claim(pinata_id, winner_id, solution)) {
|
||||
Ok(tx_hash) => {
|
||||
@ -155,7 +155,7 @@ pub unsafe extern "C" fn wallet_ffi_claim_pinata_private_owned_already_initializ
|
||||
return WalletFfiError::NullPointer;
|
||||
}
|
||||
|
||||
let wallet = match wrapper.core.lock() {
|
||||
let mut wallet = match wrapper.core.lock() {
|
||||
Ok(w) => w,
|
||||
Err(e) => {
|
||||
print_error(format!("Failed to lock wallet: {e}"));
|
||||
@ -174,7 +174,7 @@ pub unsafe extern "C" fn wallet_ffi_claim_pinata_private_owned_already_initializ
|
||||
};
|
||||
let proof: MembershipProof = (winner_proof_index, siblings);
|
||||
|
||||
let pinata = Pinata(&wallet);
|
||||
let mut pinata = Pinata(&mut wallet);
|
||||
|
||||
match block_on(
|
||||
pinata
|
||||
@ -250,7 +250,7 @@ pub unsafe extern "C" fn wallet_ffi_claim_pinata_private_owned_not_initialized(
|
||||
return WalletFfiError::NullPointer;
|
||||
}
|
||||
|
||||
let wallet = match wrapper.core.lock() {
|
||||
let mut wallet = match wrapper.core.lock() {
|
||||
Ok(w) => w,
|
||||
Err(e) => {
|
||||
print_error(format!("Failed to lock wallet: {e}"));
|
||||
@ -262,7 +262,7 @@ pub unsafe extern "C" fn wallet_ffi_claim_pinata_private_owned_not_initialized(
|
||||
let winner_id = AccountId::new(unsafe { (*winner_account_id).data });
|
||||
let solution = u128::from_le_bytes(unsafe { *solution });
|
||||
|
||||
let pinata = Pinata(&wallet);
|
||||
let mut pinata = Pinata(&mut wallet);
|
||||
|
||||
match block_on(pinata.claim_private_owned_account(pinata_id, winner_id, solution)) {
|
||||
Ok((tx_hash, _shared_key)) => {
|
||||
|
||||
@ -1,9 +1,5 @@
|
||||
use std::{ffi::CString, ptr, slice};
|
||||
|
||||
use common::transaction::LeeTransaction;
|
||||
use lee::ProgramDeploymentTransaction;
|
||||
use sequencer_service_rpc::RpcClient as _;
|
||||
|
||||
use crate::{
|
||||
block_on,
|
||||
error::{print_error, WalletFfiError},
|
||||
@ -50,7 +46,7 @@ pub unsafe extern "C" fn wallet_ffi_program_deployment(
|
||||
return WalletFfiError::NullPointer;
|
||||
}
|
||||
|
||||
let wallet = match wrapper.core.lock() {
|
||||
let mut wallet = match wrapper.core.lock() {
|
||||
Ok(w) => w,
|
||||
Err(e) => {
|
||||
print_error(format!("Failed to lock wallet: {e}"));
|
||||
@ -60,14 +56,7 @@ pub unsafe extern "C" fn wallet_ffi_program_deployment(
|
||||
|
||||
let elf = unsafe { slice::from_raw_parts(elf_data, elf_size) }.to_vec();
|
||||
|
||||
let message = lee::program_deployment_transaction::Message::new(elf);
|
||||
let transaction = ProgramDeploymentTransaction::new(message);
|
||||
|
||||
match block_on(
|
||||
wallet
|
||||
.sequencer_client
|
||||
.send_transaction(LeeTransaction::ProgramDeployment(transaction)),
|
||||
) {
|
||||
match block_on(wallet.send_program_deployment_transaction(elf)) {
|
||||
Ok(tx_hash) => {
|
||||
let tx_hash = CString::new(tx_hash.to_string())
|
||||
.map_or(ptr::null_mut(), std::ffi::CString::into_raw);
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
//! Block synchronization functions.
|
||||
|
||||
use sequencer_service_rpc::RpcClient as _;
|
||||
|
||||
use crate::{
|
||||
block_on,
|
||||
error::{print_error, WalletFfiError},
|
||||
@ -128,7 +126,7 @@ pub unsafe extern "C" fn wallet_ffi_get_current_block_height(
|
||||
return WalletFfiError::NullPointer;
|
||||
}
|
||||
|
||||
let wallet = match wrapper.core.lock() {
|
||||
let mut wallet = match wrapper.core.lock() {
|
||||
Ok(w) => w,
|
||||
Err(e) => {
|
||||
print_error(format!("Failed to lock wallet: {e}"));
|
||||
@ -136,7 +134,7 @@ pub unsafe extern "C" fn wallet_ffi_get_current_block_height(
|
||||
}
|
||||
};
|
||||
|
||||
match block_on(wallet.sequencer_client.get_last_block_id()) {
|
||||
match block_on(wallet.get_last_block_id()) {
|
||||
Ok(last_block_id) => {
|
||||
unsafe {
|
||||
*out_block_height = last_block_id;
|
||||
|
||||
@ -72,7 +72,7 @@ pub unsafe extern "C" fn wallet_ffi_transfer_public(
|
||||
return WalletFfiError::NullPointer;
|
||||
}
|
||||
|
||||
let wallet = match wrapper.core.lock() {
|
||||
let mut wallet = match wrapper.core.lock() {
|
||||
Ok(w) => w,
|
||||
Err(e) => {
|
||||
print_error(format!("Failed to lock wallet: {e}"));
|
||||
@ -84,7 +84,7 @@ pub unsafe extern "C" fn wallet_ffi_transfer_public(
|
||||
let to_id = AccountId::new(unsafe { (*to).data });
|
||||
let amount = u128::from_le_bytes(unsafe { *amount });
|
||||
|
||||
let transfer = NativeTokenTransfer(&wallet);
|
||||
let mut transfer = NativeTokenTransfer(&mut wallet);
|
||||
|
||||
match block_on(transfer.send_public_transfer(
|
||||
AccountIdentity::Public(from_id),
|
||||
@ -164,7 +164,7 @@ pub unsafe extern "C" fn wallet_ffi_transfer_shielded(
|
||||
return WalletFfiError::NullPointer;
|
||||
}
|
||||
|
||||
let wallet = match wrapper.core.lock() {
|
||||
let mut wallet = match wrapper.core.lock() {
|
||||
Ok(w) => w,
|
||||
Err(e) => {
|
||||
print_error(format!("Failed to lock wallet: {e}"));
|
||||
@ -188,7 +188,7 @@ pub unsafe extern "C" fn wallet_ffi_transfer_shielded(
|
||||
CliAccountMention::KeyPath,
|
||||
);
|
||||
|
||||
let transfer = NativeTokenTransfer(&wallet);
|
||||
let mut transfer = NativeTokenTransfer(&mut wallet);
|
||||
|
||||
match block_on(transfer.send_shielded_transfer_to_outer_account(
|
||||
from_mention.into_public_identity(from_id),
|
||||
@ -262,7 +262,7 @@ pub unsafe extern "C" fn wallet_ffi_transfer_deshielded(
|
||||
return WalletFfiError::NullPointer;
|
||||
}
|
||||
|
||||
let wallet = match wrapper.core.lock() {
|
||||
let mut wallet = match wrapper.core.lock() {
|
||||
Ok(w) => w,
|
||||
Err(e) => {
|
||||
print_error(format!("Failed to lock wallet: {e}"));
|
||||
@ -273,7 +273,7 @@ pub unsafe extern "C" fn wallet_ffi_transfer_deshielded(
|
||||
let from_id = AccountId::new(unsafe { (*from).data });
|
||||
let to_id = AccountId::new(unsafe { (*to).data });
|
||||
let amount = u128::from_le_bytes(unsafe { *amount });
|
||||
let transfer = NativeTokenTransfer(&wallet);
|
||||
let mut transfer = NativeTokenTransfer(&mut wallet);
|
||||
|
||||
match block_on(transfer.send_deshielded_transfer(from_id, to_id, amount)) {
|
||||
Ok((tx_hash, _shared_key)) => {
|
||||
@ -348,7 +348,7 @@ pub unsafe extern "C" fn wallet_ffi_transfer_private(
|
||||
return WalletFfiError::NullPointer;
|
||||
}
|
||||
|
||||
let wallet = match wrapper.core.lock() {
|
||||
let mut wallet = match wrapper.core.lock() {
|
||||
Ok(w) => w,
|
||||
Err(e) => {
|
||||
print_error(format!("Failed to lock wallet: {e}"));
|
||||
@ -367,7 +367,7 @@ pub unsafe extern "C" fn wallet_ffi_transfer_private(
|
||||
};
|
||||
let to_identifier = u128::from_le_bytes(unsafe { (*to_identifier).data });
|
||||
let amount = u128::from_le_bytes(unsafe { *amount });
|
||||
let transfer = NativeTokenTransfer(&wallet);
|
||||
let mut transfer = NativeTokenTransfer(&mut wallet);
|
||||
|
||||
match block_on(transfer.send_private_transfer_to_outer_account(
|
||||
from_id,
|
||||
@ -445,7 +445,7 @@ pub unsafe extern "C" fn wallet_ffi_transfer_shielded_owned(
|
||||
return WalletFfiError::NullPointer;
|
||||
}
|
||||
|
||||
let wallet = match wrapper.core.lock() {
|
||||
let mut wallet = match wrapper.core.lock() {
|
||||
Ok(w) => w,
|
||||
Err(e) => {
|
||||
print_error(format!("Failed to lock wallet: {e}"));
|
||||
@ -461,7 +461,7 @@ pub unsafe extern "C" fn wallet_ffi_transfer_shielded_owned(
|
||||
CliAccountMention::KeyPath,
|
||||
);
|
||||
|
||||
let transfer = NativeTokenTransfer(&wallet);
|
||||
let mut transfer = NativeTokenTransfer(&mut wallet);
|
||||
|
||||
match block_on(transfer.send_shielded_transfer(
|
||||
from_mention.into_public_identity(from_id),
|
||||
@ -536,7 +536,7 @@ pub unsafe extern "C" fn wallet_ffi_transfer_private_owned(
|
||||
return WalletFfiError::NullPointer;
|
||||
}
|
||||
|
||||
let wallet = match wrapper.core.lock() {
|
||||
let mut wallet = match wrapper.core.lock() {
|
||||
Ok(w) => w,
|
||||
Err(e) => {
|
||||
print_error(format!("Failed to lock wallet: {e}"));
|
||||
@ -547,7 +547,7 @@ pub unsafe extern "C" fn wallet_ffi_transfer_private_owned(
|
||||
let from_id = AccountId::new(unsafe { (*from).data });
|
||||
let to_id = AccountId::new(unsafe { (*to).data });
|
||||
let amount = u128::from_le_bytes(unsafe { *amount });
|
||||
let transfer = NativeTokenTransfer(&wallet);
|
||||
let mut transfer = NativeTokenTransfer(&mut wallet);
|
||||
|
||||
match block_on(transfer.send_private_transfer_to_owned_account(from_id, to_id, amount)) {
|
||||
Ok((tx_hash, _shared_keys)) => {
|
||||
@ -608,7 +608,7 @@ pub unsafe extern "C" fn wallet_ffi_register_public_account(
|
||||
return WalletFfiError::NullPointer;
|
||||
}
|
||||
|
||||
let wallet = match wrapper.core.lock() {
|
||||
let mut wallet = match wrapper.core.lock() {
|
||||
Ok(w) => w,
|
||||
Err(e) => {
|
||||
print_error(format!("Failed to lock wallet: {e}"));
|
||||
@ -618,7 +618,7 @@ pub unsafe extern "C" fn wallet_ffi_register_public_account(
|
||||
|
||||
let account_id = AccountId::new(unsafe { (*account_id).data });
|
||||
|
||||
let transfer = NativeTokenTransfer(&wallet);
|
||||
let mut transfer = NativeTokenTransfer(&mut wallet);
|
||||
|
||||
match block_on(transfer.register_account(AccountIdentity::Public(account_id))) {
|
||||
Ok(tx_hash) => {
|
||||
@ -679,7 +679,7 @@ pub unsafe extern "C" fn wallet_ffi_register_private_account(
|
||||
return WalletFfiError::NullPointer;
|
||||
}
|
||||
|
||||
let wallet = match wrapper.core.lock() {
|
||||
let mut wallet = match wrapper.core.lock() {
|
||||
Ok(w) => w,
|
||||
Err(e) => {
|
||||
print_error(format!("Failed to lock wallet: {e}"));
|
||||
@ -688,7 +688,7 @@ pub unsafe extern "C" fn wallet_ffi_register_private_account(
|
||||
};
|
||||
|
||||
let account_id = AccountId::new(unsafe { (*account_id).data });
|
||||
let transfer = NativeTokenTransfer(&wallet);
|
||||
let mut transfer = NativeTokenTransfer(&mut wallet);
|
||||
|
||||
match block_on(transfer.register_account_private(account_id)) {
|
||||
Ok((tx_hash, _secret)) => {
|
||||
|
||||
@ -48,7 +48,7 @@ pub unsafe extern "C" fn wallet_ffi_get_vault_balance(
|
||||
return WalletFfiError::NullPointer;
|
||||
}
|
||||
|
||||
let wallet = match wrapper.core.lock() {
|
||||
let mut wallet = match wrapper.core.lock() {
|
||||
Ok(w) => w,
|
||||
Err(e) => {
|
||||
print_error(format!("Failed to lock wallet: {e}"));
|
||||
@ -113,7 +113,7 @@ pub unsafe extern "C" fn wallet_ffi_vault_claim(
|
||||
return WalletFfiError::NullPointer;
|
||||
}
|
||||
|
||||
let wallet = match wrapper.core.lock() {
|
||||
let mut wallet = match wrapper.core.lock() {
|
||||
Ok(w) => w,
|
||||
Err(e) => {
|
||||
print_error(format!("Failed to lock wallet: {e}"));
|
||||
@ -124,7 +124,7 @@ pub unsafe extern "C" fn wallet_ffi_vault_claim(
|
||||
let owner_id = AccountId::new(unsafe { (*owner).data });
|
||||
let amount = u128::from_le_bytes(unsafe { *amount });
|
||||
|
||||
match block_on(Vault(&wallet).send_claim(owner_id, amount)) {
|
||||
match block_on(Vault(&mut wallet).send_claim(owner_id, amount)) {
|
||||
Ok(tx_hash) => {
|
||||
let tx_hash = CString::new(tx_hash.to_string())
|
||||
.map_or(ptr::null_mut(), std::ffi::CString::into_raw);
|
||||
@ -185,7 +185,7 @@ pub unsafe extern "C" fn wallet_ffi_vault_claim_private(
|
||||
return WalletFfiError::NullPointer;
|
||||
}
|
||||
|
||||
let wallet = match wrapper.core.lock() {
|
||||
let mut wallet = match wrapper.core.lock() {
|
||||
Ok(w) => w,
|
||||
Err(e) => {
|
||||
print_error(format!("Failed to lock wallet: {e}"));
|
||||
@ -196,7 +196,7 @@ pub unsafe extern "C" fn wallet_ffi_vault_claim_private(
|
||||
let owner_id = AccountId::new(unsafe { (*owner).data });
|
||||
let amount = u128::from_le_bytes(unsafe { *amount });
|
||||
|
||||
match block_on(Vault(&wallet).send_claim_private_owner(owner_id, amount)) {
|
||||
match block_on(Vault(&mut wallet).send_claim_private_owner(owner_id, amount)) {
|
||||
Ok((tx_hash, _shared_key)) => {
|
||||
let tx_hash = CString::new(tx_hash.to_string())
|
||||
.map_or(ptr::null_mut(), std::ffi::CString::into_raw);
|
||||
|
||||
@ -86,6 +86,7 @@ fn c_str_to_path(ptr: *const c_char, name: &str) -> Result<PathBuf, WalletFfiErr
|
||||
/// # Parameters
|
||||
/// - `config_path`: Path to the wallet configuration file (JSON)
|
||||
/// - `storage_path`: Path where wallet data will be stored
|
||||
/// - `metrics_path`: Path to the wallet metrics file (JSON)
|
||||
/// - `password`: Password for encrypting the wallet seed
|
||||
///
|
||||
/// # Returns
|
||||
@ -98,6 +99,7 @@ fn c_str_to_path(ptr: *const c_char, name: &str) -> Result<PathBuf, WalletFfiErr
|
||||
pub unsafe extern "C" fn wallet_ffi_create_new(
|
||||
config_path: *const c_char,
|
||||
storage_path: *const c_char,
|
||||
metrics_path: *const c_char,
|
||||
password: *const c_char,
|
||||
) -> FfiCreateWalletOutput {
|
||||
let Ok(config_path) = c_str_to_path(config_path, "config_path") else {
|
||||
@ -112,7 +114,17 @@ pub unsafe extern "C" fn wallet_ffi_create_new(
|
||||
return FfiCreateWalletOutput::default();
|
||||
};
|
||||
|
||||
match WalletCore::new_init_storage(config_path, storage_path, None, &password) {
|
||||
let Ok(metrics_path) = c_str_to_path(metrics_path, "metrics_path") else {
|
||||
return FfiCreateWalletOutput::default();
|
||||
};
|
||||
|
||||
match block_on(WalletCore::new_init_storage(
|
||||
config_path,
|
||||
storage_path,
|
||||
metrics_path,
|
||||
None,
|
||||
&password,
|
||||
)) {
|
||||
Ok((core, mnemonic)) => {
|
||||
let wrapper = Box::new(WalletWrapper {
|
||||
core: Mutex::new(core),
|
||||
@ -142,8 +154,9 @@ pub unsafe extern "C" fn wallet_ffi_create_new(
|
||||
/// This loads a wallet that was previously created with `wallet_ffi_create_new()`.
|
||||
///
|
||||
/// # Parameters
|
||||
/// - `handle` - Valid wallet handle
|
||||
/// - `config_path`: Path to the wallet configuration file (JSON)
|
||||
/// - `storage_path`: Path where wallet data is stored
|
||||
/// - `metrics_path`: Path to the wallet metrics file (JSON)
|
||||
///
|
||||
/// # Returns
|
||||
/// - Opaque wallet handle on success
|
||||
@ -151,10 +164,12 @@ pub unsafe extern "C" fn wallet_ffi_create_new(
|
||||
///
|
||||
/// # Safety
|
||||
/// All string parameters must be valid null-terminated UTF-8 strings.
|
||||
/// `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wallet_ffi_open(
|
||||
config_path: *const c_char,
|
||||
storage_path: *const c_char,
|
||||
metrics_path: *const c_char,
|
||||
) -> *mut WalletHandle {
|
||||
let Ok(config_path) = c_str_to_path(config_path, "config_path") else {
|
||||
return ptr::null_mut();
|
||||
@ -164,7 +179,16 @@ pub unsafe extern "C" fn wallet_ffi_open(
|
||||
return ptr::null_mut();
|
||||
};
|
||||
|
||||
match WalletCore::new_update_chain(config_path, storage_path, None) {
|
||||
let Ok(metrics_path) = c_str_to_path(metrics_path, "metrics_path") else {
|
||||
return ptr::null_mut();
|
||||
};
|
||||
|
||||
match block_on(WalletCore::new_update_chain(
|
||||
config_path,
|
||||
storage_path,
|
||||
metrics_path,
|
||||
None,
|
||||
)) {
|
||||
Ok(core) => {
|
||||
let wrapper = Box::new(WalletWrapper {
|
||||
core: Mutex::new(core),
|
||||
@ -334,7 +358,7 @@ pub unsafe extern "C" fn wallet_ffi_get_sequencer_addr(handle: *mut WalletHandle
|
||||
}
|
||||
};
|
||||
|
||||
let addr = wallet.config().sequencer_addr.clone().to_string();
|
||||
let addr = wallet.leader_url().to_string();
|
||||
|
||||
match std::ffi::CString::new(addr) {
|
||||
Ok(s) => s.into_raw(),
|
||||
|
||||
@ -1564,6 +1564,7 @@ enum WalletFfiError wallet_ffi_vault_claim_private(struct WalletHandle *handle,
|
||||
* # Parameters
|
||||
* - `config_path`: Path to the wallet configuration file (JSON)
|
||||
* - `storage_path`: Path where wallet data will be stored
|
||||
* - `metrics_path`: Path to the wallet metrics file (JSON)
|
||||
* - `password`: Password for encrypting the wallet seed
|
||||
*
|
||||
* # Returns
|
||||
@ -1575,6 +1576,7 @@ enum WalletFfiError wallet_ffi_vault_claim_private(struct WalletHandle *handle,
|
||||
*/
|
||||
struct FfiCreateWalletOutput wallet_ffi_create_new(const char *config_path,
|
||||
const char *storage_path,
|
||||
const char *metrics_path,
|
||||
const char *password);
|
||||
|
||||
/**
|
||||
@ -1583,8 +1585,9 @@ struct FfiCreateWalletOutput wallet_ffi_create_new(const char *config_path,
|
||||
* This loads a wallet that was previously created with `wallet_ffi_create_new()`.
|
||||
*
|
||||
* # Parameters
|
||||
* - `handle` - Valid wallet handle
|
||||
* - `config_path`: Path to the wallet configuration file (JSON)
|
||||
* - `storage_path`: Path where wallet data is stored
|
||||
* - `metrics_path`: Path to the wallet metrics file (JSON)
|
||||
*
|
||||
* # Returns
|
||||
* - Opaque wallet handle on success
|
||||
@ -1592,8 +1595,11 @@ struct FfiCreateWalletOutput wallet_ffi_create_new(const char *config_path,
|
||||
*
|
||||
* # Safety
|
||||
* All string parameters must be valid null-terminated UTF-8 strings.
|
||||
* `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`.
|
||||
*/
|
||||
struct WalletHandle *wallet_ffi_open(const char *config_path, const char *storage_path);
|
||||
struct WalletHandle *wallet_ffi_open(const char *config_path,
|
||||
const char *storage_path,
|
||||
const char *metrics_path);
|
||||
|
||||
/**
|
||||
* Destroy a wallet handle and free its resources.
|
||||
|
||||
@ -211,6 +211,10 @@ impl WalletCore {
|
||||
self.multi_sequencer_client.leader.clone()
|
||||
}
|
||||
|
||||
pub fn leader_url(&self) -> Url {
|
||||
self.multi_sequencer_client.leader_url.clone()
|
||||
}
|
||||
|
||||
/// Get storage.
|
||||
#[must_use]
|
||||
pub const fn storage(&self) -> &Storage {
|
||||
|
||||
@ -158,10 +158,9 @@ pub async fn callibration(client: SequencerClient) -> Metrics {
|
||||
// Precision loss if fine there
|
||||
let sample_size = latencies.len();
|
||||
let latency_avg = (latencies.iter().fold(0, |acc, x| acc + x) as f32) / (sample_size as f32);
|
||||
let latency_var = (latencies.iter().fold(0f32, |acc, x| {
|
||||
let latency_var = latencies.iter().fold(0f32, |acc, x| {
|
||||
acc + ((*x as f32) - latency_avg) * ((*x as f32) - latency_avg)
|
||||
}) / (sample_size as f32))
|
||||
.sqrt();
|
||||
}) / (sample_size as f32);
|
||||
|
||||
Metrics {
|
||||
latency_avg,
|
||||
@ -216,32 +215,16 @@ pub fn choose_leader(
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Conservative assumption: least amount of errors is the best
|
||||
let min_err_addr = client_vec.iter().fold(client_vec[0], |acc, x| {
|
||||
let old_err_count = metrics.get(acc).unwrap().errors;
|
||||
let new_err_count = metrics.get(*x).unwrap().errors;
|
||||
if new_err_count < old_err_count {
|
||||
*x
|
||||
} else {
|
||||
acc
|
||||
}
|
||||
// Get the lowest quartile in error distribution
|
||||
client_vec.sort_by(|a, b| {
|
||||
metrics
|
||||
.get(*a)
|
||||
.unwrap()
|
||||
.errors
|
||||
.cmp(&metrics.get(*b).unwrap().errors)
|
||||
});
|
||||
|
||||
let min_err_count = metrics.get(min_err_addr).unwrap().errors;
|
||||
|
||||
// Sort out all latest clients
|
||||
client_vec = client_vec
|
||||
.iter()
|
||||
.filter_map(|x| {
|
||||
let err_count = metrics.get(*x).unwrap().errors;
|
||||
|
||||
if err_count == min_err_count {
|
||||
Some(*x)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
client_vec = client_vec[..(client_vec.len() / 4)].to_vec();
|
||||
|
||||
// Choose clients with least latency and variance
|
||||
let min_lat_var_addr = client_vec.iter().fold(client_vec[0], |acc, x| {
|
||||
@ -250,10 +233,11 @@ pub fn choose_leader(
|
||||
let new = metrics.get(*x).unwrap();
|
||||
let (new_lat, new_var) = (new.latency_avg, new.latency_var);
|
||||
|
||||
// Client is better if it is strongly linearly better
|
||||
if ((new_lat - new_var) > (old_lat - old_var))
|
||||
&& ((new_lat + new_var) > (old_lat + old_var))
|
||||
{
|
||||
let new_std = new_var.sqrt();
|
||||
let old_std = old_var.sqrt();
|
||||
|
||||
// Client is better if its averabe is better and variance does not make it worse
|
||||
if (new_lat < old_lat) && ((new_lat + new_std) < (old_lat + old_std)) {
|
||||
*x
|
||||
} else {
|
||||
acc
|
||||
@ -283,32 +267,41 @@ struct CumulativeUpdates {
|
||||
pub failure_count: u64,
|
||||
pub latest_block_id: Option<u64>,
|
||||
pub cumulative_latency: f32,
|
||||
pub cumulative_latency_squares: f32,
|
||||
pub additional_sample_size: usize,
|
||||
}
|
||||
|
||||
fn cumulative_updates(metric_updates: &[MetricsUpdate]) -> CumulativeUpdates {
|
||||
let (failure_count, latest_block_id, cumulative_latency) =
|
||||
metric_updates.iter().fold((0u64, None, 0f32), |acc, x| {
|
||||
let MetricsUpdate {
|
||||
latency,
|
||||
new_latest_block_id,
|
||||
is_failed,
|
||||
} = x;
|
||||
(
|
||||
if *is_failed { acc.0 + 1 } else { acc.0 },
|
||||
match (acc.1, new_latest_block_id) {
|
||||
(None, None) => None,
|
||||
(None, Some(val)) | (Some(val), None) => Some(val),
|
||||
(Some(val_old), Some(val_new)) => Some(std::cmp::max(val_old, val_new)),
|
||||
},
|
||||
if !*is_failed { acc.2 + latency } else { acc.2 },
|
||||
)
|
||||
});
|
||||
let (failure_count, latest_block_id, cumulative_latency, cumulative_latency_squares) =
|
||||
metric_updates
|
||||
.iter()
|
||||
.fold((0u64, None, 0f32, 0_f32), |acc, x| {
|
||||
let MetricsUpdate {
|
||||
latency,
|
||||
new_latest_block_id,
|
||||
is_failed,
|
||||
} = x;
|
||||
(
|
||||
if *is_failed { acc.0 + 1 } else { acc.0 },
|
||||
match (acc.1, new_latest_block_id) {
|
||||
(None, None) => None,
|
||||
(None, Some(val)) | (Some(val), None) => Some(val),
|
||||
(Some(val_old), Some(val_new)) => Some(std::cmp::max(val_old, val_new)),
|
||||
},
|
||||
if !*is_failed { acc.2 + latency } else { acc.2 },
|
||||
if !*is_failed {
|
||||
acc.3 + latency * latency
|
||||
} else {
|
||||
acc.3
|
||||
},
|
||||
)
|
||||
});
|
||||
|
||||
CumulativeUpdates {
|
||||
failure_count,
|
||||
latest_block_id: latest_block_id.copied(),
|
||||
cumulative_latency,
|
||||
cumulative_latency_squares,
|
||||
additional_sample_size: metric_updates.len() - (failure_count as usize),
|
||||
}
|
||||
}
|
||||
@ -319,19 +312,24 @@ fn cumulative_avg(
|
||||
orig_size_f: f32,
|
||||
mod_size_f: f32,
|
||||
) -> f32 {
|
||||
(latency_avg_old * orig_size_f + cumulative_latency) / mod_size_f
|
||||
(latency_avg_old * orig_size_f + cumulative_latency) / (orig_size_f + mod_size_f)
|
||||
}
|
||||
|
||||
fn cumulative_var(
|
||||
latency_avg_old: f32,
|
||||
latency_avg_new: f32,
|
||||
latency_var: f32,
|
||||
cumulative_latency: f32,
|
||||
cumulative_latency_squares: f32,
|
||||
orig_size_f: f32,
|
||||
mod_size_f: f32,
|
||||
) -> f32 {
|
||||
(latency_avg_old - latency_avg_new)
|
||||
* ((3f32 * latency_avg_old + latency_avg_new) * orig_size_f / mod_size_f)
|
||||
+ (latency_var * latency_var) * orig_size_f / mod_size_f
|
||||
(latency_var * orig_size_f
|
||||
+ (latency_avg_new - latency_avg_old) * (latency_avg_new - latency_avg_old) * orig_size_f
|
||||
+ cumulative_latency_squares
|
||||
+ mod_size_f * (latency_avg_new * latency_avg_new)
|
||||
- 2_f32 * cumulative_latency * latency_avg_new)
|
||||
/ (orig_size_f + mod_size_f)
|
||||
}
|
||||
|
||||
pub fn update_metrics(
|
||||
@ -341,12 +339,13 @@ pub fn update_metrics(
|
||||
) -> Result<(), anyhow::Error> {
|
||||
let leader_metric = metrics
|
||||
.get_mut(leader_url)
|
||||
.ok_or(anyhow::anyhow!("Leader URL is in present in metrics"))?;
|
||||
.ok_or(anyhow::anyhow!("Leader URL is not present in metrics"))?;
|
||||
|
||||
let CumulativeUpdates {
|
||||
failure_count,
|
||||
latest_block_id,
|
||||
cumulative_latency,
|
||||
cumulative_latency_squares,
|
||||
additional_sample_size,
|
||||
} = cumulative_updates(metric_updates);
|
||||
|
||||
@ -356,22 +355,25 @@ pub fn update_metrics(
|
||||
}
|
||||
|
||||
let orig_size_f = leader_metric.sample_size as f32;
|
||||
let mod_size_f = (leader_metric.sample_size + additional_sample_size) as f32;
|
||||
let mod_size_f = additional_sample_size as f32;
|
||||
|
||||
let latency_avg_old = leader_metric.latency_avg;
|
||||
let latency_avg_new =
|
||||
cumulative_avg(latency_avg_old, cumulative_latency, orig_size_f, mod_size_f);
|
||||
|
||||
let latency_disp_new = cumulative_var(
|
||||
let latency_var_new = cumulative_var(
|
||||
latency_avg_old,
|
||||
latency_avg_new,
|
||||
leader_metric.latency_var,
|
||||
cumulative_latency,
|
||||
cumulative_latency_squares,
|
||||
orig_size_f,
|
||||
mod_size_f,
|
||||
);
|
||||
|
||||
leader_metric.latency_avg = latency_avg_new;
|
||||
leader_metric.latency_var = latency_disp_new.sqrt();
|
||||
leader_metric.latency_var = latency_var_new;
|
||||
leader_metric.sample_size += additional_sample_size;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -389,7 +391,14 @@ pub fn save_metrics_at_path_with_updates(
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::multi_client::{MetricsUpdate, cumulative_avg, cumulative_updates};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use url::Url;
|
||||
|
||||
use crate::multi_client::{
|
||||
CumulativeUpdates, Metrics, MetricsUpdate, cumulative_avg, cumulative_updates,
|
||||
cumulative_var, update_metrics,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn cumulative_updates_test() {
|
||||
@ -411,25 +420,36 @@ mod tests {
|
||||
},
|
||||
];
|
||||
|
||||
let cumulative_updates = cumulative_updates(&metrics_updates_vec);
|
||||
let CumulativeUpdates {
|
||||
failure_count,
|
||||
latest_block_id,
|
||||
cumulative_latency,
|
||||
cumulative_latency_squares,
|
||||
additional_sample_size,
|
||||
} = cumulative_updates(&metrics_updates_vec);
|
||||
|
||||
let epsilon = 0.01_f32;
|
||||
|
||||
assert_eq!(cumulative_updates.additional_sample_size, 2);
|
||||
assert_eq!(cumulative_updates.failure_count, 1);
|
||||
assert_eq!(cumulative_updates.latest_block_id, Some(16));
|
||||
assert!((cumulative_updates.cumulative_latency - 215_f32).abs() < epsilon);
|
||||
let sum_squared_manual = 100_f32 * 100_f32 + 115_f32 * 115_f32;
|
||||
|
||||
assert_eq!(additional_sample_size, 2);
|
||||
assert_eq!(failure_count, 1);
|
||||
assert_eq!(latest_block_id, Some(16));
|
||||
assert!((cumulative_latency - 215_f32).abs() < epsilon);
|
||||
assert!((cumulative_latency_squares - sum_squared_manual).abs() < epsilon);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cumulative_avg_test() {
|
||||
let mut sample = vec![100_f32; 20];
|
||||
let mut sample = vec![100_f32; 40];
|
||||
|
||||
let old_sample_size_f = sample.len() as f32;
|
||||
let old_avg = sample.iter().sum::<f32>() / old_sample_size_f;
|
||||
|
||||
let new_samples = vec![101_f32, 110_f32, 112_f32, 97_f32, 78_f32];
|
||||
let mod_sample_size_f = new_samples.len() as f32 + old_sample_size_f;
|
||||
let new_samples = vec![
|
||||
101_f32, 110_f32, 112_f32, 97_f32, 78_f32, 25_f32, 75_f32, 189_f32, 120_f32, 50_f32,
|
||||
];
|
||||
let mod_sample_size_f = new_samples.len() as f32;
|
||||
let cumulative = new_samples.iter().sum();
|
||||
|
||||
sample.extend_from_slice(&new_samples);
|
||||
@ -442,4 +462,117 @@ mod tests {
|
||||
|
||||
assert!((new_avg_1 - new_avg_2).abs() < epsilon);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cumulative_var_test() {
|
||||
let mut sample = vec![100_f32; 40];
|
||||
|
||||
let old_sample_size_f = sample.len() as f32;
|
||||
let old_avg = sample.iter().sum::<f32>() / old_sample_size_f;
|
||||
|
||||
let old_var = sample
|
||||
.iter()
|
||||
.fold(0_f32, |acc, x| acc + (x - old_avg) * (x - old_avg))
|
||||
/ old_sample_size_f;
|
||||
|
||||
let new_samples = vec![
|
||||
101_f32, 110_f32, 112_f32, 97_f32, 78_f32, 25_f32, 75_f32, 189_f32, 120_f32, 50_f32,
|
||||
];
|
||||
let mod_sample_size_f = new_samples.len() as f32;
|
||||
let cumulative = new_samples.iter().sum();
|
||||
let cumulative_squares = new_samples.iter().fold(0_f32, |acc, x| acc + (*x) * (*x));
|
||||
|
||||
let new_avg = cumulative_avg(old_avg, cumulative, old_sample_size_f, mod_sample_size_f);
|
||||
|
||||
sample.extend_from_slice(&new_samples);
|
||||
let new_var_1 = sample
|
||||
.iter()
|
||||
.fold(0_f32, |acc, x| acc + (x - new_avg) * (x - new_avg))
|
||||
/ (sample.len() as f32);
|
||||
|
||||
let new_var_2 = cumulative_var(
|
||||
old_avg,
|
||||
new_avg,
|
||||
old_var,
|
||||
cumulative,
|
||||
cumulative_squares,
|
||||
old_sample_size_f,
|
||||
mod_sample_size_f,
|
||||
);
|
||||
|
||||
let epsilon = 0.01_f32;
|
||||
|
||||
assert!((new_var_1 - new_var_2).abs() < epsilon);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn metric_updates_correctness() {
|
||||
let metrics_updates_vec = vec![
|
||||
MetricsUpdate {
|
||||
latency: 100_f32,
|
||||
new_latest_block_id: Some(105),
|
||||
is_failed: false,
|
||||
},
|
||||
MetricsUpdate {
|
||||
latency: 115_f32,
|
||||
new_latest_block_id: Some(106),
|
||||
is_failed: false,
|
||||
},
|
||||
MetricsUpdate {
|
||||
latency: 50_f32,
|
||||
new_latest_block_id: None,
|
||||
is_failed: true,
|
||||
},
|
||||
];
|
||||
|
||||
let addr_leader = Url::parse("https://127.0.0.1:3040").unwrap();
|
||||
|
||||
let leader_metrics = Metrics {
|
||||
latency_avg: 100_f32,
|
||||
latency_var: 25_f32,
|
||||
sample_size: 10,
|
||||
latest_block_id: 100,
|
||||
errors: 5,
|
||||
};
|
||||
|
||||
let cumulative_latency = 100_f32 + 115_f32;
|
||||
let cumulative_latency_squares = 100_f32 * 100_f32 + 115_f32 * 115_f32;
|
||||
|
||||
let avg_manual = cumulative_avg(
|
||||
leader_metrics.latency_avg,
|
||||
cumulative_latency,
|
||||
10_f32,
|
||||
2_f32,
|
||||
);
|
||||
let var_manual = cumulative_var(
|
||||
leader_metrics.latency_avg,
|
||||
avg_manual,
|
||||
leader_metrics.latency_var,
|
||||
cumulative_latency,
|
||||
cumulative_latency_squares,
|
||||
10_f32,
|
||||
2_f32,
|
||||
);
|
||||
|
||||
let mut metric_map = HashMap::new();
|
||||
metric_map.insert(addr_leader.clone(), leader_metrics);
|
||||
|
||||
update_metrics(&mut metric_map, &addr_leader, &metrics_updates_vec).unwrap();
|
||||
|
||||
let Metrics {
|
||||
latency_avg,
|
||||
latency_var,
|
||||
sample_size,
|
||||
latest_block_id,
|
||||
errors,
|
||||
} = metric_map.get(&addr_leader).unwrap();
|
||||
|
||||
let epsilon = 0.01_f32;
|
||||
|
||||
assert_eq!(*errors, 6);
|
||||
assert_eq!(*latest_block_id, 106);
|
||||
assert_eq!(*sample_size, 12);
|
||||
assert!((*latency_avg - avg_manual).abs() < epsilon);
|
||||
assert!((*latency_var - var_manual).abs() < epsilon);
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ use lee::{AccountId, PrivateKey, PublicKey};
|
||||
use lee_core::Identifier;
|
||||
use sequencer_core::config::{BedrockConfig, GenesisAction, SequencerConfig};
|
||||
use url::Url;
|
||||
use wallet::config::WalletConfig;
|
||||
use wallet::config::{SequencerConnectionData, WalletConfig};
|
||||
|
||||
pub const INITIAL_PUBLIC_BALANCES_FOR_WALLET: [u128; 2] = [10_000, 20_000];
|
||||
pub const INITIAL_PRIVATE_BALANCES_FOR_WALLET: [u128; 2] = [10_000, 20_000];
|
||||
@ -157,13 +157,15 @@ pub fn genesis_from_accounts(
|
||||
|
||||
pub fn wallet_config(sequencer_addr: SocketAddr) -> Result<WalletConfig> {
|
||||
Ok(WalletConfig {
|
||||
sequencer_addr: addr_to_url(UrlProtocol::Http, sequencer_addr)
|
||||
.context("Failed to convert sequencer addr to URL")?,
|
||||
sequencers_conn_data: vec![SequencerConnectionData {
|
||||
sequencer_addr: addr_to_url(UrlProtocol::Http, sequencer_addr)
|
||||
.context("Failed to convert sequencer addr to URL")?,
|
||||
basic_auth: None,
|
||||
}],
|
||||
seq_poll_timeout: Duration::from_secs(30),
|
||||
seq_tx_poll_max_blocks: 15,
|
||||
seq_poll_max_retries: 10,
|
||||
seq_block_poll_max_amount: 100,
|
||||
basic_auth: None,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -365,6 +365,7 @@ impl TestContextBuilder {
|
||||
&initial_private_accounts,
|
||||
wallet_config_overrides,
|
||||
)
|
||||
.await
|
||||
.context("Failed to setup wallet")?;
|
||||
|
||||
setup_public_accounts_with_initial_supply(&mut wallet, &initial_public_accounts)
|
||||
@ -420,15 +421,19 @@ impl BlockingTestContext {
|
||||
self.ctx.as_ref().expect("TestContext is set")
|
||||
}
|
||||
|
||||
pub fn ctx_mut(&mut self) -> &mut TestContext {
|
||||
self.ctx.as_mut().expect("TestContext is set")
|
||||
}
|
||||
|
||||
pub const fn runtime(&self) -> &tokio::runtime::Runtime {
|
||||
&self.runtime
|
||||
}
|
||||
|
||||
pub fn block_on<'ctx, F>(&'ctx self, f: impl FnOnce(&'ctx TestContext) -> F) -> F::Output
|
||||
pub fn block_on<'ctx, F>(&'ctx mut self, f: impl FnOnce(&'ctx TestContext) -> F) -> F::Output
|
||||
where
|
||||
F: std::future::Future + 'ctx,
|
||||
{
|
||||
let future = f(self.ctx());
|
||||
let future = f(self.ctx_mut());
|
||||
self.runtime.block_on(future)
|
||||
}
|
||||
|
||||
|
||||
@ -133,7 +133,7 @@ pub async fn setup_sequencer(
|
||||
Ok((sequencer_handle, temp_sequencer_dir))
|
||||
}
|
||||
|
||||
pub fn setup_wallet(
|
||||
pub async fn setup_wallet(
|
||||
sequencer_addr: SocketAddr,
|
||||
initial_public_accounts: &[(PrivateKey, u128)],
|
||||
initial_private_accounts: &[InitialPrivateAccountForWallet],
|
||||
@ -151,14 +151,17 @@ pub fn setup_wallet(
|
||||
.context("Failed to write wallet config in temp dir")?;
|
||||
|
||||
let storage_path = temp_wallet_dir.path().join("storage.json");
|
||||
let metrics_path = temp_wallet_dir.path().join("metrics.json");
|
||||
|
||||
let wallet_password = "test_pass".to_owned();
|
||||
let (mut wallet, _mnemonic) = WalletCore::new_init_storage(
|
||||
config_path,
|
||||
storage_path,
|
||||
metrics_path,
|
||||
Some(config_overrides),
|
||||
&wallet_password,
|
||||
)
|
||||
.await
|
||||
.context("Failed to init wallet")?;
|
||||
|
||||
for (private_key, _balance) in initial_public_accounts {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user