From 8db6110150fb17a59f11b4111ba4267eaaa8fc0d Mon Sep 17 00:00:00 2001 From: aeryz Date: Thu, 11 Sep 2025 14:12:14 +0300 Subject: [PATCH 01/33] chore: add fungible asset deployer Signed-off-by: aeryz --- cosmwasm/deployer/src/main.rs | 104 ++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/cosmwasm/deployer/src/main.rs b/cosmwasm/deployer/src/main.rs index 6615d4dc0a..97ff26454f 100644 --- a/cosmwasm/deployer/src/main.rs +++ b/cosmwasm/deployer/src/main.rs @@ -92,6 +92,31 @@ enum App { #[command(flatten)] gas_config: GasFillerArgs, }, + DeployFungibleToken { + #[arg(long)] + rpc_url: String, + #[arg(long, env)] + private_key: H256, + #[arg(long)] + contract: PathBuf, + #[arg( + long, + // the autoref value parser selector chooses From before FromStr, but Value's From impl always returns Value::String(..), whereas FromStr actually parses the json contained within the string + value_parser(serde_json::Value::from_str), + )] + init_msg: Value, + #[arg(long)] + output: Option, + #[arg(long)] + salt: String, + /// Marks this chain as permissioned. + /// + /// Permisioned cosmwasm chains require special handling of instantiate permissions in order to deploy the stack. + #[arg(long)] + permissioned: bool, + #[command(flatten)] + gas_config: GasFillerArgs, + }, Instantiate2Address { #[arg(long)] deployer: Bech32, @@ -833,6 +858,85 @@ async fn do_main() -> Result<()> { write_output(output, contract_addresses)?; } + App::DeployFungibleToken { + rpc_url, + private_key, + contract, + init_msg, + output: _, + permissioned: _, + salt, + gas_config, + } => { + let ctx = Deployer::new(rpc_url, private_key, &gas_config).await?; + + let bytecode_base_address = ctx + .instantiate2_address(sha2(BYTECODE_BASE_BYTECODE), &BYTECODE_BASE) + .await?; + + let bytecode_base_contract = ctx.contract_info(&bytecode_base_address).await?; + + let bytecode_base_code_id = match bytecode_base_contract { + Some(_) => ctx + .instantiate_code_id_of_contract(bytecode_base_address) + .await? + .unwrap(), + // contract does not exist on chain + None => { + info!("bytecode-base has not yet been stored"); + + let (tx_hash, store_code_response) = ctx + .tx( + MsgStoreCode { + sender: ctx.wallet().address().map_data(Into::into), + wasm_byte_code: BYTECODE_BASE_BYTECODE.into(), + instantiate_permission: Some(AccessConfig::Everybody), + }, + "", + gas_config.simulate, + ) + .await + .context("store code")?; + + info!(%tx_hash, code_id = store_code_response.code_id, "stored bytecode-base"); + + let (tx_hash, instantiate_response) = ctx + .tx( + MsgInstantiateContract2 { + sender: ctx.wallet().address().map_data(Into::into), + admin: ctx.wallet().address().map_data(Into::into), + code_id: store_code_response.code_id, + label: BYTECODE_BASE.to_string(), + msg: b"{}".into(), + salt: BYTECODE_BASE.as_bytes().into(), + funds: vec![], + fix_msg: false, + }, + "", + gas_config.simulate, + ) + .await + .context("instantiate2")?; + + info!(%tx_hash, address = %instantiate_response.address, "instantiated bytecode-base"); + + store_code_response.code_id + } + }; + + info!("bytecode-base code_id is {bytecode_base_code_id}"); + + let address = ctx + .deploy_and_initiate( + std::fs::read(contract)?, + bytecode_base_code_id, + init_msg, + &Salt::Utf8(salt), + ) + .await?; + + info!("deployed at {address}"); + } App::Instantiate2Address { deployer, salt, From 6ebc887feb98955f5802b68950b24054b55ead41 Mon Sep 17 00:00:00 2001 From: kaancaglan Date: Thu, 18 Sep 2025 18:02:46 +0300 Subject: [PATCH 02/33] chore: lst contract e2es Signed-off-by: kaancaglan --- tools/union-test/tests/e2e.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tools/union-test/tests/e2e.rs b/tools/union-test/tests/e2e.rs index ea1a0a3f48..9b6878cb81 100644 --- a/tools/union-test/tests/e2e.rs +++ b/tools/union-test/tests/e2e.rs @@ -41,10 +41,12 @@ use union_test::{ use unionlabs::{ encoding::{Encode, Json}, ethereum::keccak256, - primitives::{Bech32, FixedBytes, H160, U256}, + primitives::{encoding::Base64, Bech32, Bytes, FixedBytes, H160, U256}, +}; +use voyager_sdk::{ + primitives::{ChainId, Timestamp}, + serde_json::json, }; -use voyager_sdk::primitives::{ChainId, Timestamp}; - static CTX: OnceCell>> = OnceCell::const_new(); static CHANNELS_OPENED: OnceCell<()> = OnceCell::const_new(); // static ERC20: OnceCell = OnceCell::const_new(); @@ -187,7 +189,7 @@ async fn init_ctx<'a>() -> Arc>> { }; let src = cosmos::Module::new(cosmos_cfg).await.unwrap(); let dst = evm::Module::new(evm_cfg).await.unwrap(); - let needed_channel_count = 19; // TODO: Hardcoded now, it will be specified from config later. + let needed_channel_count = 1; // TODO: Hardcoded now, it will be specified from config later. // TODO(aeryz): move config file into the testing framework's own config file let ctx = TestContext::new( From 2bc7ac5d2de7798028486df8f2850628f695f920 Mon Sep 17 00:00:00 2001 From: kaancaglan Date: Thu, 18 Sep 2025 18:04:02 +0300 Subject: [PATCH 03/33] chore: creating bond msg Signed-off-by: kaancaglan --- tools/union-test/tests/e2e_lst.rs | 619 ++++++++++++++++++++++++++++++ 1 file changed, 619 insertions(+) create mode 100644 tools/union-test/tests/e2e_lst.rs diff --git a/tools/union-test/tests/e2e_lst.rs b/tools/union-test/tests/e2e_lst.rs new file mode 100644 index 0000000000..af5198b13d --- /dev/null +++ b/tools/union-test/tests/e2e_lst.rs @@ -0,0 +1,619 @@ +// tests/e2e_lst.rs + +use std::{ + num::NonZero, + str::FromStr, + sync::Arc, + time::{Duration, SystemTime, UNIX_EPOCH}, +}; + +use alloy::{ + hex::decode as hex_decode, + sol_types::{SolCall, SolValue}, +}; +use concurrent_keyring::{KeyringConfig, KeyringConfigEntry}; +use cosmos::{FeemarketConfig, GasFillerConfig}; +use cosmwasm_std::{instantiate2_address, to_json_binary, Coin as CwCoin, CosmosMsg, WasmMsg}; +use cw20::Cw20ExecuteMsg; +use hex_literal::hex; +use ibc_union_spec::ChannelId; +use protos::cosmos::base::v1beta1::Coin; +use rand::RngCore; +use serde::Serialize; +use tokio::sync::OnceCell; +use ucs03_zkgm::{ + self, + com::{ + Batch, Call, Instruction, SolverMetadata, TokenOrderV1, TokenOrderV2, INSTR_VERSION_0, + INSTR_VERSION_1, INSTR_VERSION_2, OP_BATCH, OP_CALL, OP_FORWARD, OP_TOKEN_ORDER, + TOKEN_ORDER_KIND_ESCROW, TOKEN_ORDER_KIND_INITIALIZE, TOKEN_ORDER_KIND_SOLVE, + TOKEN_ORDER_KIND_UNESCROW, + }, +}; +use union_test::{ + cosmos::{self}, + evm::{ + self, + zkgm::{ + IBCPacket, Instruction as InstructionEvm, MsgPacketRecv, UCS03Zkgm, ZkgmPacket, IBC, + }, + zkgmerc20::ZkgmERC20, + }, + TestContext, +}; +use unionlabs::{ + encoding::{Encode, Json}, + ethereum::keccak256, + primitives::{encoding::Base64, Bech32, Bytes, FixedBytes, H160, U256}, +}; +use voyager_sdk::{ + primitives::{ChainId, Timestamp}, + serde_json::json, +}; +static CTX: OnceCell>> = OnceCell::const_new(); +static CHANNELS_OPENED: OnceCell<()> = OnceCell::const_new(); +// static ERC20: OnceCell = OnceCell::const_new(); + +static UNION_ZKGM_ADDRESS: &str = + "union1rfz3ytg6l60wxk5rxsk27jvn2907cyav04sz8kde3xhmmf9nplxqr8y05c"; +// static UNION_MINTER_ADDRESS: &str = +// "union1tt6nn3qv0q0z4gq4s2h65a2acv3lcwxjwf8ey3jgnwmtqkfnyq9q4q5y8x"; +static EVM_ZKGM_BYTES: [u8; 20] = hex!("05fd55c1abe31d3ed09a76216ca8f0372f4b2ec5"); +static EVM_IBC_BYTES: [u8; 20] = hex!("ed2af2aD7FE0D92011b26A2e5D1B4dC7D12A47C5"); +#[derive(Serialize)] +struct BondInner<'a> { + mint_to: &'a str, + min_mint_amount: &'a str, +} +#[derive(Serialize)] +struct BondMsg<'a> { + bond: BondInner<'a>, +} + +fn make_zkgm_call_payload( + lst_hub: &str, + mint_to: &str, + min_amount: &str, + funds_denom: &str, + funds_amount: u32, +) -> String { + let bond = BondMsg { + bond: BondInner { + mint_to, + min_mint_amount: min_amount, + }, + }; + + let wasm_exec: CosmosMsg = CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: lst_hub.to_string(), + msg: to_json_binary(&bond).expect("bond json"), + funds: vec![CwCoin { + denom: funds_denom.to_string(), + amount: funds_amount.into(), + }], + }); + + voyager_sdk::serde_json::to_string(&vec![wasm_exec]).expect("vec cosmosmsg json") +} + +async fn init_ctx<'a>() -> Arc>> { + CTX.get_or_init(|| async { + let cosmos_cfg = cosmos::Config { + chain_id: ChainId::new("union-devnet-1"), + ibc_host_contract_address: Bech32::from_str( + "union1nk3nes4ef6vcjan5tz6stf9g8p08q2kgqysx6q5exxh89zakp0msq5z79t", + ) + .unwrap(), + privileged_acc_keyring: KeyringConfig { + name: "privileged_acc".into(), + keys: vec![KeyringConfigEntry::Raw { + name: "privileged_acc".into(), + key: hex!("aa820fa947beb242032a41b6dc9a8b9c37d8f5fbcda0966b1ec80335b10a7d6f") + .to_vec(), + }], + }, + keyring: KeyringConfig { + name: "alice".into(), + keys: vec![ + KeyringConfigEntry::Raw { + name: "bob".into(), + key: hex_literal::hex!( + "f562d20f0a4ffd8814d262f7023f33971cbcd14a96d60027585777f174b9cdeb" + ) + .to_vec(), + }, + KeyringConfigEntry::Raw { + name: "dave".into(), + key: hex_literal::hex!( + "edc165ff1ebc27044ddc284c9cf5da656dcbff324f6ecbb9d3203cf5f4738d6d" + ) + .to_vec(), + }, + KeyringConfigEntry::Raw { + name: "charlie".into(), + key: hex_literal::hex!( + "a1f713e0f36404586085a599a45ca8233e23709e23cd54bc8d5452ef8f7bc1e6" + ) + .to_vec(), + }, + ], + }, + rpc_url: "http://0.0.0.0:26657".into(), + gas_config: GasFillerConfig::Feemarket(FeemarketConfig { + max_gas: 10000000, + gas_multiplier: Some(1.4), + denom: None, + }), + fee_recipient: None, + }; + let evm_cfg = evm::Config { + chain_id: ChainId::new("32382"), + ibc_handler_address: hex!("ed2af2aD7FE0D92011b26A2e5D1B4dC7D12A47C5").into(), + multicall_address: hex!("84c4c2ee43ccfd523af9f78740256e0f60d38068").into(), + rpc_url: "http://0.0.0.0:8545".into(), + ws_url: "ws://0.0.0.0:8546".into(), + privileged_acc_keyring: KeyringConfig { + name: "zkgm-deployer".into(), + keys: vec![KeyringConfigEntry::Raw { + name: "zkgm-deployer-key".into(), + key: hex!("4e9444a6efd6d42725a250b650a781da2737ea308c839eaccb0f7f3dbd2fea77") + .to_vec(), + }], + }, + keyring: KeyringConfig { + name: "evm-keyring".into(), + keys: vec![ + KeyringConfigEntry::Raw { + name: "dev-key0.prv".into(), + key: hex!( + "4e9444a6efd6d42725a250b650a781da2737ea308c839eaccb0f7f3dbd2fea77" + ) + .to_vec(), + }, + // KeyringConfigEntry::Raw { + // name: "dev-key1.prv".into(), + // key: hex!( + // "d9c5dc47ed678fc3e63249953866d79e5cf48418e79d8eec1a985be7393ef3b9" + // ) + // .to_vec(), + // }, + // KeyringConfigEntry::Raw { + // name: "dev-key2.prv".into(), + // key: hex!( + // "eadf66c84a1c2768a14e883512724d6023a54d500bf91d910a7dace376a97d6b" + // ) + // .to_vec(), + // }, + // KeyringConfigEntry::Raw { + // name: "dev-key3.prv".into(), + // key: hex!( + // "d56f932b298ba86341037f3871141a707330316f6f9493641a2cd59ba4a53710" + // ) + // .to_vec(), + // }, + // KeyringConfigEntry::Raw { + // name: "dev-key4.prv".into(), + // key: hex!( + // "084494a1ff88a1319e493d32aa6e127ab0eaaaf74b8714edfd670a9ddc4a060d" + // ) + // .to_vec(), + // }, + // KeyringConfigEntry::Raw { + // name: "dev-key5.prv".into(), + // key: hex!( + // "f977996449841b13ce9bbb99873006e04590ddbe28d9cd449dd33505851e74ba" + // ) + // .to_vec(), + // }, + // KeyringConfigEntry::Raw { + // name: "dev-key6.prv".into(), + // key: hex!( + // "523776c0e15a5826c85f08e0dd20d70190b0001e87f6ff9f25854d10f24db63c" + // ) + // .to_vec(), + // }, + // KeyringConfigEntry::Raw { + // name: "dev-key7.prv".into(), + // key: hex!( + // "b7d500ecae3d26deaa9547557822c95208163e230cc04345bd223da99f5bd058" + // ) + // .to_vec(), + // }, + ], + }, + max_gas_price: None, + fixed_gas_price: None, + gas_multiplier: 2.0, + }; + let src = cosmos::Module::new(cosmos_cfg).await.unwrap(); + let dst = evm::Module::new(evm_cfg).await.unwrap(); + let needed_channel_count = 1; // TODO: Hardcoded now, it will be specified from config later. + + // TODO(aeryz): move config file into the testing framework's own config file + let ctx = TestContext::new( + src, + dst, + needed_channel_count, + "/home/kaancaglan/dev/union/voyager/config.jsonc", + ) + .await + .unwrap_or_else(|e| panic!("failed to build TestContext: {:#?}", e)); + + Arc::new(ctx) + }) + .await + .clone() +} + +async fn ensure_channels_opened(channel_count: usize) { + CHANNELS_OPENED + .get_or_init(|| async move { + let ctx = init_ctx().await; + + let (src_client, dst_client) = ctx + .create_clients( + Duration::from_secs(60), + "ibc-cosmwasm", + "trusted/evm/mpt", + "ibc-solidity", + "cometbls", + ) + .await + .unwrap(); + + assert!(src_client.client_id > 0); + assert!(dst_client.client_id > 0); + + let conn = ctx + .open_connection::( + &ctx.src, + src_client.client_id, + &ctx.dst, + dst_client.client_id, + Duration::from_secs(180), + ) + .await + .unwrap(); + assert!(conn.connection_id > 0); + assert!(conn.counterparty_connection_id > 0); + + let current_available_count = ctx.get_available_channel_count().await; + + let opened = ctx + .open_channels( + true, + UNION_ZKGM_ADDRESS.as_bytes().into(), + EVM_ZKGM_BYTES.to_vec().into(), + conn.counterparty_connection_id, + "ucs03-zkgm-0".into(), + channel_count, + Duration::from_secs(360 * channel_count as u64), + ) + .await + .unwrap(); + assert_eq!(opened, channel_count); + + let available_count_after_open = ctx.get_available_channel_count().await; + assert_eq!( + current_available_count + channel_count, + available_count_after_open + ); + let pair = ctx.get_channel().await.expect("channel available"); + let available_count_after_get = ctx.get_available_channel_count().await; + assert_eq!(available_count_after_open - 1, available_count_after_get); + ctx.release_channel(pair).await; + let available_count_after_release = ctx.get_available_channel_count().await; + assert_eq!(available_count_after_open, available_count_after_release); + }) + .await; +} + +async fn test_escher_lst() { + let ctx = init_ctx().await; + + let (evm_address, evm_provider) = ctx.dst.get_provider().await; + let (cosmos_address, cosmos_provider) = ctx.src.get_signer().await; + let cosmos_address_bytes = cosmos_address.to_string().into_bytes(); + + // ensure_channels_opened(ctx.channel_count).await; + // let available_channel = ctx.get_available_channel_count().await; + // assert!(available_channel > 0); + // let pair = ctx.get_channel().await.expect("channel available"); + + let dst_channel_id = 1; + let src_channel_id = 1; + + let vault_on_union = "union1skg5244hpkad603zz77kdekzw6ffgpfrde3ldk8rpdz06n62k4hqct0w4j"; + + let u_on_eth = hex_literal::hex!("0c8C6f58156D10d18193A8fFdD853e1b9F8D8836"); + + // let metadata = SolverMetadata { + // solverAddress: u_on_eth.to_vec().into(), + // metadata: Default::default(), + // } + // .abi_encode_params(); + + // let instruction_cosmos = Instruction { + // version: INSTR_VERSION_2, + // opcode: OP_TOKEN_ORDER, + // operand: TokenOrderV2 { + // sender: cosmos_address_bytes.clone().into(), + // receiver: evm_address.to_vec().into(), + // base_token: "muno".as_bytes().into(), + // base_amount: "100000".parse().unwrap(), + // kind: TOKEN_ORDER_KIND_SOLVE, + // metadata: metadata.into(), + // quote_token: u_on_eth.to_vec().into(), + // quote_amount: "100000".parse().unwrap(), + // } + // .abi_encode_params() + // .into(), + // }; + + // let (_, zkgm_deployer_provider) = ctx.dst.get_provider_privileged().await; + // println!("registering u counterpart"); + // ctx.dst + // .u_register_fungible_counterpart( + // H160::from(u_on_eth), + // zkgm_deployer_provider.clone(), + // alloy::primitives::U256::ZERO, + // dst_channel_id, + // b"muno".to_vec().into(), + // evm::u::U::FungibleCounterparty { + // beneficiary: vault_on_union.as_bytes().to_vec().into(), + // }, + // ) + // .await + // .unwrap(); + // println!("u counterpart is registered"); + + let mut salt_bytes = [0u8; 32]; + rand::rng().fill_bytes(&mut salt_bytes); + + // let cw_msg = ucs03_zkgm::msg::ExecuteMsg::Send { + // channel_id: src_channel_id.try_into().unwrap(), + // timeout_height: 0u64.into(), + // timeout_timestamp: voyager_sdk::primitives::Timestamp::from_secs(u32::MAX.into()), + // salt: salt_bytes.into(), + // instruction: instruction_cosmos.abi_encode_params().into(), + // }; + // let bin_msg: Vec = Encode::::encode(&cw_msg); + + // let funds = vec![Coin { + // denom: "muno".into(), + // amount: "100000".into(), + // }]; + + // let contract: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); + + // let ack_packet_data = ctx + // .send_and_recv_and_ack_with_retry::( + // &ctx.src, + // contract, + // (bin_msg, funds), + // &ctx.dst, + // 3, + // Duration::from_secs(20), + // Duration::from_secs(720), + // cosmos_provider, + // ) + // .await; + + // assert!( + // ack_packet_data.is_ok(), + // "Failed to send and ack packet: {:?}", + // ack_packet_data.err() + // ); + + let new_u_balance = ctx + .dst + .zkgmerc20_balance_of( + H160::from(u_on_eth), + evm_address.into(), + evm_provider.clone(), + ) + .await + .unwrap(); + + let new_vault_balance = ctx + .src + .native_balance(Bech32::from_str(vault_on_union).unwrap(), "muno") + .await + .unwrap(); + + // both balances are updated + assert!(new_u_balance > U256::ZERO); + assert!(new_vault_balance > 0); + + println!("new_u_balance: {}", new_u_balance); + + let lst_hub = "union1fdg764zzxwvwyqkx3fuj0236l9ddh5xmutgvj2mv9cduffy82z9sp62ygc"; + // let lst = "union1jansh23v7teaznyljq6ss4vx6eym8yrz0dsjchap4u7j3etx94vqhmcwn5"; + + let zkgm_proxy = "union1ykagxh4cmvvyldvh98yxr9vlaqn3j77xepatml4paren37rw4zusthnwpv"; + + let addr: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); + let canon = cosmwasm_std::CanonicalAddr::from(addr.data().as_ref()); + + let zkgm_proxy_canon = instantiate2_address( + &hex_literal::hex!("ec827349ed4c1fec5a9c3462ff7c979d4c40e7aa43b16ed34469d04ff835f2a1"), + &canon, + proxy_account_salt_for_tests( + alloy::primitives::U256::ZERO, + dst_channel_id, + evm_address.as_slice(), + ) + .get() + .as_slice(), + ) + .unwrap(); + + let hrp = Bech32::>::from_str(UNION_ZKGM_ADDRESS) + .unwrap() + .hrp() + .to_string(); + + // 3. Build a Bech32 address with same HRP + let zkgm_proxy_calculated = Bech32::>::new( + hrp, + FixedBytes::<32>::try_from(zkgm_proxy_canon.as_slice()).unwrap(), + ); + println!("ZKGM Proxy: {}", zkgm_proxy_calculated); + + // let zkgm_proxy = zkgm_proxy_calculated.to_string().as_str(); + + // let bond_message: Bytes = json!({ + // "bond": { + // "mint_to_address": "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", + // "min_mint_amount": "3" + // } + // }) + // .to_string() + // .as_bytes() + // .into(); + + // let zkgm_message = json!({ + // "contract": lst_hub, + // "msg": bond_message.to_string(), + // "funds": [{ "denom": "muno", "amount": "3" }], + // "call_action": "call_proxy" + // }) + // .to_string(); + + let zkgm_msg_json = make_zkgm_call_payload( + lst_hub, + "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", + "3", + "muno", + 3, + ); + + let proxy_balance = ctx + .src + .native_balance(zkgm_proxy_calculated.clone(), "muno") + .await + .unwrap(); + + println!("Proxy balance before: {}", proxy_balance); + + let addr_str = zkgm_proxy_calculated.to_string(); + let receiver = addr_str.into_bytes().into(); + + let instruction_from_evm_to_union = InstructionEvm { + version: INSTR_VERSION_0, + opcode: OP_BATCH, + operand: Batch { + instructions: vec![ + Instruction { + version: INSTR_VERSION_2, + opcode: OP_TOKEN_ORDER, + operand: TokenOrderV2 { + sender: evm_address.to_vec().into(), + receiver: receiver, + base_token: u_on_eth.to_vec().into(), + base_amount: "150".parse().unwrap(), + kind: TOKEN_ORDER_KIND_SOLVE, + metadata: SolverMetadata { + solverAddress: vault_on_union.as_bytes().into(), + metadata: Default::default(), + } + .abi_encode_params() + .into(), + quote_token: "muno".as_bytes().into(), + quote_amount: "150".parse().unwrap(), + } + .abi_encode_params() + .into(), + }, + Instruction { + version: INSTR_VERSION_0, + opcode: OP_CALL, + operand: Call { + sender: evm_address.to_vec().into(), + eureka: false, + contract_address: lst_hub.as_bytes().to_vec().into(), + contract_calldata: zkgm_msg_json.as_bytes().to_vec().into(), + } + .abi_encode_params() + .into(), + }, + ], + } + .abi_encode_params() + .into(), + }; + + let approve_tx_hash = ctx + .dst + .zkgmerc20_approve( + u_on_eth.into(), + EVM_ZKGM_BYTES.into(), + U256::from(100000000000u64), + evm_provider.clone(), + ) + .await; + + assert!( + approve_tx_hash.is_ok(), + "Failed to send approve transaction: {:?}, from_account: {:?}", + approve_tx_hash.err(), + evm_address + ); + + let ucs03_zkgm = UCS03Zkgm::new(EVM_ZKGM_BYTES.into(), evm_provider.clone()); + + let call = ucs03_zkgm + .send( + dst_channel_id, + 0u64, + 4294967295000000000u64, + salt_bytes.into(), + instruction_from_evm_to_union.clone(), + ) + .clear_decoder(); + + let acked_packet = ctx + .send_and_recv_and_ack_with_retry::( + &ctx.dst, + EVM_ZKGM_BYTES.into(), + call, + &ctx.src, + 3, + Duration::from_secs(20), + Duration::from_secs(720), + &evm_provider, + ) + .await; + + let acked_packet = acked_packet.unwrap(); + assert!( + acked_packet.tag == 1, + "Packet is acked not successfully, but it should be. Tag: {:?}", + acked_packet.tag + ); + + let proxy_balance = ctx + .src + .native_balance(zkgm_proxy_calculated, "muno") + .await + .unwrap(); + + println!("Proxy balance before: {}", proxy_balance); +} + +#[tokio::test] +async fn test_escher_lst_success() { + self::test_escher_lst().await; +} + +fn proxy_account_salt_for_tests( + path: alloy::primitives::U256, + channel_id: u32, + sender: &[u8], +) -> unionlabs::primitives::H256 { + use alloy_sol_types::SolValue; + use unionlabs::ethereum::keccak256; + + let encoded = (path, channel_id, sender.to_vec()).abi_encode_params(); + keccak256(encoded) +} From ff2ce87058a35090bb09abad8e122a15cb29858a Mon Sep 17 00:00:00 2001 From: kaancaglan Date: Thu, 18 Sep 2025 18:07:50 +0300 Subject: [PATCH 04/33] chore: fixed cargo issue Signed-off-by: kaancaglan --- tools/union-test/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/union-test/Cargo.toml b/tools/union-test/Cargo.toml index d2ba84fb4a..3968726e8e 100644 --- a/tools/union-test/Cargo.toml +++ b/tools/union-test/Cargo.toml @@ -11,6 +11,7 @@ repository = { workspace = true } [dependencies] alloy = { workspace = true, features = ["contract", "network", "providers", "signers", "signer-local", "rpc", "rpc-types", "transports", "transport-http", "transport-ws", "reqwest", "provider-ws"] } +alloy-sol-types = { workspace = true } axum = { workspace = true, features = ["macros", "tokio", "json"] } bip32 = { workspace = true } cometbft-rpc = { workspace = true } From 815c4e71917ffd89460dae2b1cecf6042b633475 Mon Sep 17 00:00:00 2001 From: kaancaglan Date: Thu, 18 Sep 2025 18:08:01 +0300 Subject: [PATCH 05/33] chore: fixed forge issue Signed-off-by: kaancaglan --- networks/services/forge.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/networks/services/forge.nix b/networks/services/forge.nix index 1b945050e7..5be39077f0 100644 --- a/networks/services/forge.nix +++ b/networks/services/forge.nix @@ -15,6 +15,8 @@ let cp --no-preserve=mode -r ${evm-contracts}/* . cp --no-preserve=mode -r ${evm-sources}/* . WETH_ADDRESS="0x0000000000000000000000000000000000000000" \ + DEPLOYER="0x0000000000000000000000000000000000000000" \ + SENDER="0xBe68fC2d8249eb60bfCf0e71D5A0d2F2e292c4eD" \ RATE_LIMIT_ENABLED="false" \ PRIVATE_KEY=0x${builtins.readFile ./../genesis/devnet-eth/dev-key0.prv} \ FOUNDRY_PROFILE="script" \ From 44bbbf46525278ed8e73087062fec2dab6dca56c Mon Sep 17 00:00:00 2001 From: aeryz Date: Fri, 19 Sep 2025 13:08:49 +0300 Subject: [PATCH 06/33] chore: bond works Signed-off-by: aeryz --- cosmwasm/cosmwasm.nix | 5 +---- tools/union-test/src/lib.rs | 4 ++-- tools/union-test/tests/e2e_lst.rs | 33 +++++++++++++++++-------------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/cosmwasm/cosmwasm.nix b/cosmwasm/cosmwasm.nix index 71b78e33e4..2a012869bd 100644 --- a/cosmwasm/cosmwasm.nix +++ b/cosmwasm/cosmwasm.nix @@ -108,11 +108,8 @@ _: { }; # lightclients = pkgs.lib.lists.remove "cometbls" (builtins.attrNames all-lightclients); lightclients = [ + "trusted-mpt" # "sui" - # "trusted-mpt" - # "parlia" - "sui" - # "trusted-mpt" ]; } { diff --git a/tools/union-test/src/lib.rs b/tools/union-test/src/lib.rs index 4ffd44a010..33e5c7fae3 100644 --- a/tools/union-test/src/lib.rs +++ b/tools/union-test/src/lib.rs @@ -485,8 +485,8 @@ where channel_count: usize, voyager_config_file_path: &str, ) -> anyhow::Result { - voyager::init_fetch(voyager_config_file_path, src.chain_id().clone())?; - voyager::init_fetch(voyager_config_file_path, dst.chain_id().clone())?; + // voyager::init_fetch(voyager_config_file_path, src.chain_id().clone())?; + // voyager::init_fetch(voyager_config_file_path, dst.chain_id().clone())?; let channel_pool = ChannelPool::new(); println!( "Creating test context for {} and {}. Init_fetch called for both chains.", diff --git a/tools/union-test/tests/e2e_lst.rs b/tools/union-test/tests/e2e_lst.rs index af5198b13d..1abf1e39cb 100644 --- a/tools/union-test/tests/e2e_lst.rs +++ b/tools/union-test/tests/e2e_lst.rs @@ -60,9 +60,13 @@ static UNION_ZKGM_ADDRESS: &str = // "union1tt6nn3qv0q0z4gq4s2h65a2acv3lcwxjwf8ey3jgnwmtqkfnyq9q4q5y8x"; static EVM_ZKGM_BYTES: [u8; 20] = hex!("05fd55c1abe31d3ed09a76216ca8f0372f4b2ec5"); static EVM_IBC_BYTES: [u8; 20] = hex!("ed2af2aD7FE0D92011b26A2e5D1B4dC7D12A47C5"); + +// u: union1pntx7gm7shsp6slef74ae7wvcc35t3wdmanh7wrg4xkq95m24qds5atmcp +// lst: union1fdg764zzxwvwyqkx3fuj0236l9ddh5xmutgvj2mv9cduffy82z9sp62ygc + #[derive(Serialize)] struct BondInner<'a> { - mint_to: &'a str, + mint_to_address: &'a str, min_mint_amount: &'a str, } #[derive(Serialize)] @@ -79,14 +83,14 @@ fn make_zkgm_call_payload( ) -> String { let bond = BondMsg { bond: BondInner { - mint_to, + mint_to_address: mint_to, min_mint_amount: min_amount, }, }; let wasm_exec: CosmosMsg = CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: lst_hub.to_string(), - msg: to_json_binary(&bond).expect("bond json"), + msg: to_json_binary(&bond).unwrap(), funds: vec![CwCoin { denom: funds_denom.to_string(), amount: funds_amount.into(), @@ -234,7 +238,7 @@ async fn init_ctx<'a>() -> Arc>> { src, dst, needed_channel_count, - "/home/kaancaglan/dev/union/voyager/config.jsonc", + "/home/aeryz/dev/union/union/voyager/config.jsonc", ) .await .unwrap_or_else(|e| panic!("failed to build TestContext: {:#?}", e)); @@ -308,6 +312,7 @@ async fn ensure_channels_opened(channel_count: usize) { .await; } +#[tokio::test] async fn test_escher_lst() { let ctx = init_ctx().await; @@ -430,12 +435,11 @@ async fn test_escher_lst() { let lst_hub = "union1fdg764zzxwvwyqkx3fuj0236l9ddh5xmutgvj2mv9cduffy82z9sp62ygc"; // let lst = "union1jansh23v7teaznyljq6ss4vx6eym8yrz0dsjchap4u7j3etx94vqhmcwn5"; - let zkgm_proxy = "union1ykagxh4cmvvyldvh98yxr9vlaqn3j77xepatml4paren37rw4zusthnwpv"; - let addr: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); let canon = cosmwasm_std::CanonicalAddr::from(addr.data().as_ref()); let zkgm_proxy_canon = instantiate2_address( + // Checksum of the base contract &hex_literal::hex!("ec827349ed4c1fec5a9c3462ff7c979d4c40e7aa43b16ed34469d04ff835f2a1"), &canon, proxy_account_salt_for_tests( @@ -483,9 +487,9 @@ async fn test_escher_lst() { let zkgm_msg_json = make_zkgm_call_payload( lst_hub, "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", - "3", + "10", "muno", - 3, + 10, ); let proxy_balance = ctx @@ -509,7 +513,7 @@ async fn test_escher_lst() { opcode: OP_TOKEN_ORDER, operand: TokenOrderV2 { sender: evm_address.to_vec().into(), - receiver: receiver, + receiver, base_token: u_on_eth.to_vec().into(), base_amount: "150".parse().unwrap(), kind: TOKEN_ORDER_KIND_SOLVE, @@ -531,7 +535,11 @@ async fn test_escher_lst() { operand: Call { sender: evm_address.to_vec().into(), eureka: false, - contract_address: lst_hub.as_bytes().to_vec().into(), + contract_address: zkgm_proxy_calculated + .to_string() + .as_bytes() + .to_vec() + .into(), contract_calldata: zkgm_msg_json.as_bytes().to_vec().into(), } .abi_encode_params() @@ -601,11 +609,6 @@ async fn test_escher_lst() { println!("Proxy balance before: {}", proxy_balance); } -#[tokio::test] -async fn test_escher_lst_success() { - self::test_escher_lst().await; -} - fn proxy_account_salt_for_tests( path: alloy::primitives::U256, channel_id: u32, From aa34e5abd75414f3a297772d2c4aaffe3eaa97a6 Mon Sep 17 00:00:00 2001 From: kaancaglan Date: Fri, 19 Sep 2025 14:12:23 +0300 Subject: [PATCH 07/33] chore: fixed init_fetch issue Signed-off-by: kaancaglan --- tools/union-test/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/union-test/src/lib.rs b/tools/union-test/src/lib.rs index 33e5c7fae3..4ffd44a010 100644 --- a/tools/union-test/src/lib.rs +++ b/tools/union-test/src/lib.rs @@ -485,8 +485,8 @@ where channel_count: usize, voyager_config_file_path: &str, ) -> anyhow::Result { - // voyager::init_fetch(voyager_config_file_path, src.chain_id().clone())?; - // voyager::init_fetch(voyager_config_file_path, dst.chain_id().clone())?; + voyager::init_fetch(voyager_config_file_path, src.chain_id().clone())?; + voyager::init_fetch(voyager_config_file_path, dst.chain_id().clone())?; let channel_pool = ChannelPool::new(); println!( "Creating test context for {} and {}. Init_fetch called for both chains.", From f78ac75189b04cdaeaac63fd93bf9335c5e6d14a Mon Sep 17 00:00:00 2001 From: kaancaglan Date: Fri, 19 Sep 2025 14:12:46 +0300 Subject: [PATCH 08/33] chore: added one unhappy path Signed-off-by: kaancaglan --- tools/union-test/tests/e2e_lst.rs | 443 +++++++++++++++++++++++++----- 1 file changed, 370 insertions(+), 73 deletions(-) diff --git a/tools/union-test/tests/e2e_lst.rs b/tools/union-test/tests/e2e_lst.rs index 1abf1e39cb..83dd5fc196 100644 --- a/tools/union-test/tests/e2e_lst.rs +++ b/tools/union-test/tests/e2e_lst.rs @@ -238,7 +238,7 @@ async fn init_ctx<'a>() -> Arc>> { src, dst, needed_channel_count, - "/home/aeryz/dev/union/union/voyager/config.jsonc", + "/home/kaancaglan/dev/union/union/voyager/config.jsonc", ) .await .unwrap_or_else(|e| panic!("failed to build TestContext: {:#?}", e)); @@ -332,83 +332,380 @@ async fn test_escher_lst() { let u_on_eth = hex_literal::hex!("0c8C6f58156D10d18193A8fFdD853e1b9F8D8836"); - // let metadata = SolverMetadata { - // solverAddress: u_on_eth.to_vec().into(), - // metadata: Default::default(), - // } - // .abi_encode_params(); - - // let instruction_cosmos = Instruction { - // version: INSTR_VERSION_2, - // opcode: OP_TOKEN_ORDER, - // operand: TokenOrderV2 { - // sender: cosmos_address_bytes.clone().into(), - // receiver: evm_address.to_vec().into(), - // base_token: "muno".as_bytes().into(), - // base_amount: "100000".parse().unwrap(), - // kind: TOKEN_ORDER_KIND_SOLVE, - // metadata: metadata.into(), - // quote_token: u_on_eth.to_vec().into(), - // quote_amount: "100000".parse().unwrap(), + let metadata = SolverMetadata { + solverAddress: u_on_eth.to_vec().into(), + metadata: Default::default(), + } + .abi_encode_params(); + + let instruction_cosmos = Instruction { + version: INSTR_VERSION_2, + opcode: OP_TOKEN_ORDER, + operand: TokenOrderV2 { + sender: cosmos_address_bytes.clone().into(), + receiver: evm_address.to_vec().into(), + base_token: "muno".as_bytes().into(), + base_amount: "100000".parse().unwrap(), + kind: TOKEN_ORDER_KIND_SOLVE, + metadata: metadata.into(), + quote_token: u_on_eth.to_vec().into(), + quote_amount: "100000".parse().unwrap(), + } + .abi_encode_params() + .into(), + }; + + let (_, zkgm_deployer_provider) = ctx.dst.get_provider_privileged().await; + println!("registering u counterpart"); + ctx.dst + .u_register_fungible_counterpart( + H160::from(u_on_eth), + zkgm_deployer_provider.clone(), + alloy::primitives::U256::ZERO, + dst_channel_id, + b"muno".to_vec().into(), + evm::u::U::FungibleCounterparty { + beneficiary: vault_on_union.as_bytes().to_vec().into(), + }, + ) + .await + .unwrap(); + println!("u counterpart is registered"); + + let mut salt_bytes = [0u8; 32]; + rand::rng().fill_bytes(&mut salt_bytes); + + let cw_msg = ucs03_zkgm::msg::ExecuteMsg::Send { + channel_id: src_channel_id.try_into().unwrap(), + timeout_height: 0u64.into(), + timeout_timestamp: voyager_sdk::primitives::Timestamp::from_secs(u32::MAX.into()), + salt: salt_bytes.into(), + instruction: instruction_cosmos.abi_encode_params().into(), + }; + let bin_msg: Vec = Encode::::encode(&cw_msg); + + let funds = vec![Coin { + denom: "muno".into(), + amount: "100000".into(), + }]; + + let contract: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); + + let ack_packet_data = ctx + .send_and_recv_and_ack_with_retry::( + &ctx.src, + contract, + (bin_msg, funds), + &ctx.dst, + 3, + Duration::from_secs(20), + Duration::from_secs(720), + cosmos_provider, + ) + .await; + + assert!( + ack_packet_data.is_ok(), + "Failed to send and ack packet: {:?}", + ack_packet_data.err() + ); + + let new_u_balance = ctx + .dst + .zkgmerc20_balance_of( + H160::from(u_on_eth), + evm_address.into(), + evm_provider.clone(), + ) + .await + .unwrap(); + + let new_vault_balance = ctx + .src + .native_balance(Bech32::from_str(vault_on_union).unwrap(), "muno") + .await + .unwrap(); + + // both balances are updated + assert!(new_u_balance > U256::ZERO); + assert!(new_vault_balance > 0); + + println!("new_u_balance: {}", new_u_balance); + + let lst_hub = "union1fdg764zzxwvwyqkx3fuj0236l9ddh5xmutgvj2mv9cduffy82z9sp62ygc"; + // let lst = "union1jansh23v7teaznyljq6ss4vx6eym8yrz0dsjchap4u7j3etx94vqhmcwn5"; + + let addr: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); + let canon = cosmwasm_std::CanonicalAddr::from(addr.data().as_ref()); + + let zkgm_proxy_canon = instantiate2_address( + // Checksum of the base contract + &hex_literal::hex!("ec827349ed4c1fec5a9c3462ff7c979d4c40e7aa43b16ed34469d04ff835f2a1"), + &canon, + proxy_account_salt_for_tests( + alloy::primitives::U256::ZERO, + dst_channel_id, + evm_address.as_slice(), + ) + .get() + .as_slice(), + ) + .unwrap(); + + let hrp = Bech32::>::from_str(UNION_ZKGM_ADDRESS) + .unwrap() + .hrp() + .to_string(); + + // 3. Build a Bech32 address with same HRP + let zkgm_proxy_calculated = Bech32::>::new( + hrp, + FixedBytes::<32>::try_from(zkgm_proxy_canon.as_slice()).unwrap(), + ); + println!("ZKGM Proxy: {}", zkgm_proxy_calculated); + + // let zkgm_proxy = zkgm_proxy_calculated.to_string().as_str(); + + // let bond_message: Bytes = json!({ + // "bond": { + // "mint_to_address": "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", + // "min_mint_amount": "3" // } - // .abi_encode_params() - // .into(), - // }; - - // let (_, zkgm_deployer_provider) = ctx.dst.get_provider_privileged().await; - // println!("registering u counterpart"); - // ctx.dst - // .u_register_fungible_counterpart( - // H160::from(u_on_eth), - // zkgm_deployer_provider.clone(), - // alloy::primitives::U256::ZERO, - // dst_channel_id, - // b"muno".to_vec().into(), - // evm::u::U::FungibleCounterparty { - // beneficiary: vault_on_union.as_bytes().to_vec().into(), - // }, - // ) - // .await - // .unwrap(); - // println!("u counterpart is registered"); + // }) + // .to_string() + // .as_bytes() + // .into(); + + // let zkgm_message = json!({ + // "contract": lst_hub, + // "msg": bond_message.to_string(), + // "funds": [{ "denom": "muno", "amount": "3" }], + // "call_action": "call_proxy" + // }) + // .to_string(); + + let zkgm_msg_json = make_zkgm_call_payload( + lst_hub, + "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", + "1000000", + "muno", + 1000000, + ); + + let proxy_balance = ctx + .src + .native_balance(zkgm_proxy_calculated.clone(), "muno") + .await + .unwrap(); + + println!("Proxy balance before: {}", proxy_balance); + + let addr_str = zkgm_proxy_calculated.to_string(); + let receiver = addr_str.into_bytes().into(); + + let instruction_from_evm_to_union = InstructionEvm { + version: INSTR_VERSION_0, + opcode: OP_BATCH, + operand: Batch { + instructions: vec![ + Instruction { + version: INSTR_VERSION_2, + opcode: OP_TOKEN_ORDER, + operand: TokenOrderV2 { + sender: evm_address.to_vec().into(), + receiver, + base_token: u_on_eth.to_vec().into(), + base_amount: "150".parse().unwrap(), //giving 150 but expecting 1000000 so it will fail. + kind: TOKEN_ORDER_KIND_SOLVE, + metadata: SolverMetadata { + solverAddress: vault_on_union.as_bytes().into(), + metadata: Default::default(), + } + .abi_encode_params() + .into(), + quote_token: "muno".as_bytes().into(), + quote_amount: "150".parse().unwrap(), //giving 150 but expecting 1000000 so it will fail. + } + .abi_encode_params() + .into(), + }, + Instruction { + version: INSTR_VERSION_0, + opcode: OP_CALL, + operand: Call { + sender: evm_address.to_vec().into(), + eureka: false, + contract_address: zkgm_proxy_calculated + .to_string() + .as_bytes() + .to_vec() + .into(), + contract_calldata: zkgm_msg_json.as_bytes().to_vec().into(), + } + .abi_encode_params() + .into(), + }, + ], + } + .abi_encode_params() + .into(), + }; + + let approve_tx_hash = ctx + .dst + .zkgmerc20_approve( + u_on_eth.into(), + EVM_ZKGM_BYTES.into(), + U256::from(100000000000u64), + evm_provider.clone(), + ) + .await; + + assert!( + approve_tx_hash.is_ok(), + "Failed to send approve transaction: {:?}, from_account: {:?}", + approve_tx_hash.err(), + evm_address + ); + + let ucs03_zkgm = UCS03Zkgm::new(EVM_ZKGM_BYTES.into(), evm_provider.clone()); + + let call = ucs03_zkgm + .send( + dst_channel_id, + 0u64, + 4294967295000000000u64, + salt_bytes.into(), + instruction_from_evm_to_union.clone(), + ) + .clear_decoder(); + + let acked_packet = ctx + .send_and_recv_and_ack_with_retry::( + &ctx.dst, + EVM_ZKGM_BYTES.into(), + call, + &ctx.src, + 3, + Duration::from_secs(20), + Duration::from_secs(720), + &evm_provider, + ) + .await; + + let acked_packet = acked_packet.unwrap(); + assert!( + acked_packet.tag == 0, + "Packet is acked successfully, but it should not be. Tag: {:?}", + acked_packet.tag + ); + + let proxy_balance = ctx + .src + .native_balance(zkgm_proxy_calculated, "muno") + .await + .unwrap(); + + println!("Proxy balance before: {}", proxy_balance); +} + +#[tokio::test] +async fn test_escher_lst_unhappy_less_money_than_required() { + let ctx = init_ctx().await; + + let (evm_address, evm_provider) = ctx.dst.get_provider().await; + let (cosmos_address, cosmos_provider) = ctx.src.get_signer().await; + let cosmos_address_bytes = cosmos_address.to_string().into_bytes(); + + // ensure_channels_opened(ctx.channel_count).await; + // let available_channel = ctx.get_available_channel_count().await; + // assert!(available_channel > 0); + // let pair = ctx.get_channel().await.expect("channel available"); + + let dst_channel_id = 1; + let src_channel_id = 1; + + let vault_on_union = "union1skg5244hpkad603zz77kdekzw6ffgpfrde3ldk8rpdz06n62k4hqct0w4j"; + + let u_on_eth = hex_literal::hex!("0c8C6f58156D10d18193A8fFdD853e1b9F8D8836"); + + let metadata = SolverMetadata { + solverAddress: u_on_eth.to_vec().into(), + metadata: Default::default(), + } + .abi_encode_params(); + + let instruction_cosmos = Instruction { + version: INSTR_VERSION_2, + opcode: OP_TOKEN_ORDER, + operand: TokenOrderV2 { + sender: cosmos_address_bytes.clone().into(), + receiver: evm_address.to_vec().into(), + base_token: "muno".as_bytes().into(), + base_amount: "100000".parse().unwrap(), + kind: TOKEN_ORDER_KIND_SOLVE, + metadata: metadata.into(), + quote_token: u_on_eth.to_vec().into(), + quote_amount: "100000".parse().unwrap(), + } + .abi_encode_params() + .into(), + }; + + let (_, zkgm_deployer_provider) = ctx.dst.get_provider_privileged().await; + println!("registering u counterpart"); + ctx.dst + .u_register_fungible_counterpart( + H160::from(u_on_eth), + zkgm_deployer_provider.clone(), + alloy::primitives::U256::ZERO, + dst_channel_id, + b"muno".to_vec().into(), + evm::u::U::FungibleCounterparty { + beneficiary: vault_on_union.as_bytes().to_vec().into(), + }, + ) + .await + .unwrap(); + println!("u counterpart is registered"); let mut salt_bytes = [0u8; 32]; rand::rng().fill_bytes(&mut salt_bytes); - // let cw_msg = ucs03_zkgm::msg::ExecuteMsg::Send { - // channel_id: src_channel_id.try_into().unwrap(), - // timeout_height: 0u64.into(), - // timeout_timestamp: voyager_sdk::primitives::Timestamp::from_secs(u32::MAX.into()), - // salt: salt_bytes.into(), - // instruction: instruction_cosmos.abi_encode_params().into(), - // }; - // let bin_msg: Vec = Encode::::encode(&cw_msg); - - // let funds = vec![Coin { - // denom: "muno".into(), - // amount: "100000".into(), - // }]; - - // let contract: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); - - // let ack_packet_data = ctx - // .send_and_recv_and_ack_with_retry::( - // &ctx.src, - // contract, - // (bin_msg, funds), - // &ctx.dst, - // 3, - // Duration::from_secs(20), - // Duration::from_secs(720), - // cosmos_provider, - // ) - // .await; - - // assert!( - // ack_packet_data.is_ok(), - // "Failed to send and ack packet: {:?}", - // ack_packet_data.err() - // ); + let cw_msg = ucs03_zkgm::msg::ExecuteMsg::Send { + channel_id: src_channel_id.try_into().unwrap(), + timeout_height: 0u64.into(), + timeout_timestamp: voyager_sdk::primitives::Timestamp::from_secs(u32::MAX.into()), + salt: salt_bytes.into(), + instruction: instruction_cosmos.abi_encode_params().into(), + }; + let bin_msg: Vec = Encode::::encode(&cw_msg); + + let funds = vec![Coin { + denom: "muno".into(), + amount: "100000".into(), + }]; + + let contract: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); + + let ack_packet_data = ctx + .send_and_recv_and_ack_with_retry::( + &ctx.src, + contract, + (bin_msg, funds), + &ctx.dst, + 3, + Duration::from_secs(20), + Duration::from_secs(720), + cosmos_provider, + ) + .await; + + assert!( + ack_packet_data.is_ok(), + "Failed to send and ack packet: {:?}", + ack_packet_data.err() + ); let new_u_balance = ctx .dst From 6d7345ce229a55fd8238f2381bd8f47be4c0be48 Mon Sep 17 00:00:00 2001 From: kaancaglan Date: Fri, 19 Sep 2025 16:10:07 +0300 Subject: [PATCH 09/33] chore: added one more unhappy path Signed-off-by: kaancaglan --- tools/union-test/tests/e2e_lst.rs | 298 ++++++++++++++++++++++++++++++ 1 file changed, 298 insertions(+) diff --git a/tools/union-test/tests/e2e_lst.rs b/tools/union-test/tests/e2e_lst.rs index 83dd5fc196..cef8d41c77 100644 --- a/tools/union-test/tests/e2e_lst.rs +++ b/tools/union-test/tests/e2e_lst.rs @@ -906,6 +906,304 @@ async fn test_escher_lst_unhappy_less_money_than_required() { println!("Proxy balance before: {}", proxy_balance); } + +#[tokio::test] +async fn test_escher_lst_unhappy_wrong_denom() { + let ctx = init_ctx().await; + + let (evm_address, evm_provider) = ctx.dst.get_provider().await; + let (cosmos_address, cosmos_provider) = ctx.src.get_signer().await; + let cosmos_address_bytes = cosmos_address.to_string().into_bytes(); + + // ensure_channels_opened(ctx.channel_count).await; + // let available_channel = ctx.get_available_channel_count().await; + // assert!(available_channel > 0); + // let pair = ctx.get_channel().await.expect("channel available"); + + let dst_channel_id = 1; + let src_channel_id = 1; + + let vault_on_union = "union1skg5244hpkad603zz77kdekzw6ffgpfrde3ldk8rpdz06n62k4hqct0w4j"; + + let u_on_eth = hex_literal::hex!("0c8C6f58156D10d18193A8fFdD853e1b9F8D8836"); + + let metadata = SolverMetadata { + solverAddress: u_on_eth.to_vec().into(), + metadata: Default::default(), + } + .abi_encode_params(); + + let instruction_cosmos = Instruction { + version: INSTR_VERSION_2, + opcode: OP_TOKEN_ORDER, + operand: TokenOrderV2 { + sender: cosmos_address_bytes.clone().into(), + receiver: evm_address.to_vec().into(), + base_token: "muno".as_bytes().into(), + base_amount: "100000".parse().unwrap(), + kind: TOKEN_ORDER_KIND_SOLVE, + metadata: metadata.into(), + quote_token: u_on_eth.to_vec().into(), + quote_amount: "100000".parse().unwrap(), + } + .abi_encode_params() + .into(), + }; + + let (_, zkgm_deployer_provider) = ctx.dst.get_provider_privileged().await; + println!("registering u counterpart"); + ctx.dst + .u_register_fungible_counterpart( + H160::from(u_on_eth), + zkgm_deployer_provider.clone(), + alloy::primitives::U256::ZERO, + dst_channel_id, + b"muno".to_vec().into(), + evm::u::U::FungibleCounterparty { + beneficiary: vault_on_union.as_bytes().to_vec().into(), + }, + ) + .await + .unwrap(); + println!("u counterpart is registered"); + + let mut salt_bytes = [0u8; 32]; + rand::rng().fill_bytes(&mut salt_bytes); + + let cw_msg = ucs03_zkgm::msg::ExecuteMsg::Send { + channel_id: src_channel_id.try_into().unwrap(), + timeout_height: 0u64.into(), + timeout_timestamp: voyager_sdk::primitives::Timestamp::from_secs(u32::MAX.into()), + salt: salt_bytes.into(), + instruction: instruction_cosmos.abi_encode_params().into(), + }; + let bin_msg: Vec = Encode::::encode(&cw_msg); + + let funds = vec![Coin { + denom: "muno".into(), + amount: "100000".into(), + }]; + + let contract: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); + + let ack_packet_data = ctx + .send_and_recv_and_ack_with_retry::( + &ctx.src, + contract, + (bin_msg, funds), + &ctx.dst, + 3, + Duration::from_secs(20), + Duration::from_secs(720), + cosmos_provider, + ) + .await; + + assert!( + ack_packet_data.is_ok(), + "Failed to send and ack packet: {:?}", + ack_packet_data.err() + ); + + let new_u_balance = ctx + .dst + .zkgmerc20_balance_of( + H160::from(u_on_eth), + evm_address.into(), + evm_provider.clone(), + ) + .await + .unwrap(); + + let new_vault_balance = ctx + .src + .native_balance(Bech32::from_str(vault_on_union).unwrap(), "muno") + .await + .unwrap(); + + // both balances are updated + assert!(new_u_balance > U256::ZERO); + assert!(new_vault_balance > 0); + + println!("new_u_balance: {}", new_u_balance); + + let lst_hub = "union1fdg764zzxwvwyqkx3fuj0236l9ddh5xmutgvj2mv9cduffy82z9sp62ygc"; + // let lst = "union1jansh23v7teaznyljq6ss4vx6eym8yrz0dsjchap4u7j3etx94vqhmcwn5"; + + let addr: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); + let canon = cosmwasm_std::CanonicalAddr::from(addr.data().as_ref()); + + let zkgm_proxy_canon = instantiate2_address( + // Checksum of the base contract + &hex_literal::hex!("ec827349ed4c1fec5a9c3462ff7c979d4c40e7aa43b16ed34469d04ff835f2a1"), + &canon, + proxy_account_salt_for_tests( + alloy::primitives::U256::ZERO, + dst_channel_id, + evm_address.as_slice(), + ) + .get() + .as_slice(), + ) + .unwrap(); + + let hrp = Bech32::>::from_str(UNION_ZKGM_ADDRESS) + .unwrap() + .hrp() + .to_string(); + + // 3. Build a Bech32 address with same HRP + let zkgm_proxy_calculated = Bech32::>::new( + hrp, + FixedBytes::<32>::try_from(zkgm_proxy_canon.as_slice()).unwrap(), + ); + println!("ZKGM Proxy: {}", zkgm_proxy_calculated); + + // let zkgm_proxy = zkgm_proxy_calculated.to_string().as_str(); + + // let bond_message: Bytes = json!({ + // "bond": { + // "mint_to_address": "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", + // "min_mint_amount": "3" + // } + // }) + // .to_string() + // .as_bytes() + // .into(); + + // let zkgm_message = json!({ + // "contract": lst_hub, + // "msg": bond_message.to_string(), + // "funds": [{ "denom": "muno", "amount": "3" }], + // "call_action": "call_proxy" + // }) + // .to_string(); + + let zkgm_msg_json = make_zkgm_call_payload( + lst_hub, + "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", + "10", + "muan", // wrong denom to make it fail + 10, + ); + + let proxy_balance = ctx + .src + .native_balance(zkgm_proxy_calculated.clone(), "muno") + .await + .unwrap(); + + println!("Proxy balance before: {}", proxy_balance); + + let addr_str = zkgm_proxy_calculated.to_string(); + let receiver = addr_str.into_bytes().into(); + + let instruction_from_evm_to_union = InstructionEvm { + version: INSTR_VERSION_0, + opcode: OP_BATCH, + operand: Batch { + instructions: vec![ + Instruction { + version: INSTR_VERSION_2, + opcode: OP_TOKEN_ORDER, + operand: TokenOrderV2 { + sender: evm_address.to_vec().into(), + receiver, + base_token: u_on_eth.to_vec().into(), + base_amount: "150".parse().unwrap(), + kind: TOKEN_ORDER_KIND_SOLVE, + metadata: SolverMetadata { + solverAddress: vault_on_union.as_bytes().into(), + metadata: Default::default(), + } + .abi_encode_params() + .into(), + quote_token: "muno".as_bytes().into(), + quote_amount: "150".parse().unwrap(), + } + .abi_encode_params() + .into(), + }, + Instruction { + version: INSTR_VERSION_0, + opcode: OP_CALL, + operand: Call { + sender: evm_address.to_vec().into(), + eureka: false, + contract_address: zkgm_proxy_calculated + .to_string() + .as_bytes() + .to_vec() + .into(), + contract_calldata: zkgm_msg_json.as_bytes().to_vec().into(), + } + .abi_encode_params() + .into(), + }, + ], + } + .abi_encode_params() + .into(), + }; + + let approve_tx_hash = ctx + .dst + .zkgmerc20_approve( + u_on_eth.into(), + EVM_ZKGM_BYTES.into(), + U256::from(100000000000u64), + evm_provider.clone(), + ) + .await; + + assert!( + approve_tx_hash.is_ok(), + "Failed to send approve transaction: {:?}, from_account: {:?}", + approve_tx_hash.err(), + evm_address + ); + + let ucs03_zkgm = UCS03Zkgm::new(EVM_ZKGM_BYTES.into(), evm_provider.clone()); + + let call = ucs03_zkgm + .send( + dst_channel_id, + 0u64, + 4294967295000000000u64, + salt_bytes.into(), + instruction_from_evm_to_union.clone(), + ) + .clear_decoder(); + + let acked_packet = ctx + .send_and_recv_and_ack_with_retry::( + &ctx.dst, + EVM_ZKGM_BYTES.into(), + call, + &ctx.src, + 3, + Duration::from_secs(20), + Duration::from_secs(720), + &evm_provider, + ) + .await; + + let acked_packet = acked_packet.unwrap(); + assert!( + acked_packet.tag == 1, + "Packet is acked not successfully, but it should be. Tag: {:?}", + acked_packet.tag + ); + + let proxy_balance = ctx + .src + .native_balance(zkgm_proxy_calculated, "muno") + .await + .unwrap(); + + println!("Proxy balance before: {}", proxy_balance); +} + fn proxy_account_salt_for_tests( path: alloy::primitives::U256, channel_id: u32, From 45b12d092a9af4c7bfa1cccf31d15aac318ed07f Mon Sep 17 00:00:00 2001 From: kaancaglan Date: Fri, 19 Sep 2025 17:58:49 +0300 Subject: [PATCH 10/33] chore: added one more unhappy path Signed-off-by: kaancaglan --- tools/union-test/tests/e2e_lst.rs | 298 +++++++++++++++++++++++++++++- 1 file changed, 297 insertions(+), 1 deletion(-) diff --git a/tools/union-test/tests/e2e_lst.rs b/tools/union-test/tests/e2e_lst.rs index cef8d41c77..a89b746536 100644 --- a/tools/union-test/tests/e2e_lst.rs +++ b/tools/union-test/tests/e2e_lst.rs @@ -906,7 +906,6 @@ async fn test_escher_lst_unhappy_less_money_than_required() { println!("Proxy balance before: {}", proxy_balance); } - #[tokio::test] async fn test_escher_lst_unhappy_wrong_denom() { let ctx = init_ctx().await; @@ -1204,6 +1203,303 @@ async fn test_escher_lst_unhappy_wrong_denom() { println!("Proxy balance before: {}", proxy_balance); } +#[tokio::test] +async fn test_escher_lst_unhappy_under_minimum_ls_amount() { + let ctx = init_ctx().await; + + let (evm_address, evm_provider) = ctx.dst.get_provider().await; + let (cosmos_address, cosmos_provider) = ctx.src.get_signer().await; + let cosmos_address_bytes = cosmos_address.to_string().into_bytes(); + + // ensure_channels_opened(ctx.channel_count).await; + // let available_channel = ctx.get_available_channel_count().await; + // assert!(available_channel > 0); + // let pair = ctx.get_channel().await.expect("channel available"); + + let dst_channel_id = 1; + let src_channel_id = 1; + + let vault_on_union = "union1skg5244hpkad603zz77kdekzw6ffgpfrde3ldk8rpdz06n62k4hqct0w4j"; + + let u_on_eth = hex_literal::hex!("0c8C6f58156D10d18193A8fFdD853e1b9F8D8836"); + + let metadata = SolverMetadata { + solverAddress: u_on_eth.to_vec().into(), + metadata: Default::default(), + } + .abi_encode_params(); + + let instruction_cosmos = Instruction { + version: INSTR_VERSION_2, + opcode: OP_TOKEN_ORDER, + operand: TokenOrderV2 { + sender: cosmos_address_bytes.clone().into(), + receiver: evm_address.to_vec().into(), + base_token: "muno".as_bytes().into(), + base_amount: "100000".parse().unwrap(), + kind: TOKEN_ORDER_KIND_SOLVE, + metadata: metadata.into(), + quote_token: u_on_eth.to_vec().into(), + quote_amount: "100000".parse().unwrap(), + } + .abi_encode_params() + .into(), + }; + + let (_, zkgm_deployer_provider) = ctx.dst.get_provider_privileged().await; + println!("registering u counterpart"); + ctx.dst + .u_register_fungible_counterpart( + H160::from(u_on_eth), + zkgm_deployer_provider.clone(), + alloy::primitives::U256::ZERO, + dst_channel_id, + b"muno".to_vec().into(), + evm::u::U::FungibleCounterparty { + beneficiary: vault_on_union.as_bytes().to_vec().into(), + }, + ) + .await + .unwrap(); + println!("u counterpart is registered"); + + let mut salt_bytes = [0u8; 32]; + rand::rng().fill_bytes(&mut salt_bytes); + + let cw_msg = ucs03_zkgm::msg::ExecuteMsg::Send { + channel_id: src_channel_id.try_into().unwrap(), + timeout_height: 0u64.into(), + timeout_timestamp: voyager_sdk::primitives::Timestamp::from_secs(u32::MAX.into()), + salt: salt_bytes.into(), + instruction: instruction_cosmos.abi_encode_params().into(), + }; + let bin_msg: Vec = Encode::::encode(&cw_msg); + + let funds = vec![Coin { + denom: "muno".into(), + amount: "100000".into(), + }]; + + let contract: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); + + let ack_packet_data = ctx + .send_and_recv_and_ack_with_retry::( + &ctx.src, + contract, + (bin_msg, funds), + &ctx.dst, + 3, + Duration::from_secs(20), + Duration::from_secs(720), + cosmos_provider, + ) + .await; + + assert!( + ack_packet_data.is_ok(), + "Failed to send and ack packet: {:?}", + ack_packet_data.err() + ); + + let new_u_balance = ctx + .dst + .zkgmerc20_balance_of( + H160::from(u_on_eth), + evm_address.into(), + evm_provider.clone(), + ) + .await + .unwrap(); + + let new_vault_balance = ctx + .src + .native_balance(Bech32::from_str(vault_on_union).unwrap(), "muno") + .await + .unwrap(); + + // both balances are updated + assert!(new_u_balance > U256::ZERO); + assert!(new_vault_balance > 0); + + println!("new_u_balance: {}", new_u_balance); + + let lst_hub = "union1fdg764zzxwvwyqkx3fuj0236l9ddh5xmutgvj2mv9cduffy82z9sp62ygc"; + // let lst = "union1jansh23v7teaznyljq6ss4vx6eym8yrz0dsjchap4u7j3etx94vqhmcwn5"; + + let addr: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); + let canon = cosmwasm_std::CanonicalAddr::from(addr.data().as_ref()); + + let zkgm_proxy_canon = instantiate2_address( + // Checksum of the base contract + &hex_literal::hex!("ec827349ed4c1fec5a9c3462ff7c979d4c40e7aa43b16ed34469d04ff835f2a1"), + &canon, + proxy_account_salt_for_tests( + alloy::primitives::U256::ZERO, + dst_channel_id, + evm_address.as_slice(), + ) + .get() + .as_slice(), + ) + .unwrap(); + + let hrp = Bech32::>::from_str(UNION_ZKGM_ADDRESS) + .unwrap() + .hrp() + .to_string(); + + // 3. Build a Bech32 address with same HRP + let zkgm_proxy_calculated = Bech32::>::new( + hrp, + FixedBytes::<32>::try_from(zkgm_proxy_canon.as_slice()).unwrap(), + ); + println!("ZKGM Proxy: {}", zkgm_proxy_calculated); + + // let zkgm_proxy = zkgm_proxy_calculated.to_string().as_str(); + + // let bond_message: Bytes = json!({ + // "bond": { + // "mint_to_address": "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", + // "min_mint_amount": "3" + // } + // }) + // .to_string() + // .as_bytes() + // .into(); + + // let zkgm_message = json!({ + // "contract": lst_hub, + // "msg": bond_message.to_string(), + // "funds": [{ "denom": "muno", "amount": "3" }], + // "call_action": "call_proxy" + // }) + // .to_string(); + + let zkgm_msg_json = make_zkgm_call_payload( + lst_hub, + "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", + "0", + "muno", + 0, // under minimum amount to make it fail + ); + + let proxy_balance = ctx + .src + .native_balance(zkgm_proxy_calculated.clone(), "muno") + .await + .unwrap(); + + println!("Proxy balance before: {}", proxy_balance); + + let addr_str = zkgm_proxy_calculated.to_string(); + let receiver = addr_str.into_bytes().into(); + + let instruction_from_evm_to_union = InstructionEvm { + version: INSTR_VERSION_0, + opcode: OP_BATCH, + operand: Batch { + instructions: vec![ + Instruction { + version: INSTR_VERSION_2, + opcode: OP_TOKEN_ORDER, + operand: TokenOrderV2 { + sender: evm_address.to_vec().into(), + receiver, + base_token: u_on_eth.to_vec().into(), + base_amount: "150".parse().unwrap(), + kind: TOKEN_ORDER_KIND_SOLVE, + metadata: SolverMetadata { + solverAddress: vault_on_union.as_bytes().into(), + metadata: Default::default(), + } + .abi_encode_params() + .into(), + quote_token: "muno".as_bytes().into(), + quote_amount: "150".parse().unwrap(), + } + .abi_encode_params() + .into(), + }, + Instruction { + version: INSTR_VERSION_0, + opcode: OP_CALL, + operand: Call { + sender: evm_address.to_vec().into(), + eureka: false, + contract_address: zkgm_proxy_calculated + .to_string() + .as_bytes() + .to_vec() + .into(), + contract_calldata: zkgm_msg_json.as_bytes().to_vec().into(), + } + .abi_encode_params() + .into(), + }, + ], + } + .abi_encode_params() + .into(), + }; + + let approve_tx_hash = ctx + .dst + .zkgmerc20_approve( + u_on_eth.into(), + EVM_ZKGM_BYTES.into(), + U256::from(100000000000u64), + evm_provider.clone(), + ) + .await; + + assert!( + approve_tx_hash.is_ok(), + "Failed to send approve transaction: {:?}, from_account: {:?}", + approve_tx_hash.err(), + evm_address + ); + + let ucs03_zkgm = UCS03Zkgm::new(EVM_ZKGM_BYTES.into(), evm_provider.clone()); + + let call = ucs03_zkgm + .send( + dst_channel_id, + 0u64, + 4294967295000000000u64, + salt_bytes.into(), + instruction_from_evm_to_union.clone(), + ) + .clear_decoder(); + + let acked_packet = ctx + .send_and_recv_and_ack_with_retry::( + &ctx.dst, + EVM_ZKGM_BYTES.into(), + call, + &ctx.src, + 3, + Duration::from_secs(20), + Duration::from_secs(720), + &evm_provider, + ) + .await; + + let acked_packet = acked_packet.unwrap(); + assert!( + acked_packet.tag == 1, + "Packet is acked not successfully, but it should be. Tag: {:?}", + acked_packet.tag + ); + + let proxy_balance = ctx + .src + .native_balance(zkgm_proxy_calculated, "muno") + .await + .unwrap(); + + println!("Proxy balance before: {}", proxy_balance); +} + fn proxy_account_salt_for_tests( path: alloy::primitives::U256, channel_id: u32, From 03a204884400c7b85dbf407c4b26e74a1281ec3a Mon Sep 17 00:00:00 2001 From: kaancaglan Date: Fri, 19 Sep 2025 18:45:49 +0300 Subject: [PATCH 11/33] chore: fixed stuff Signed-off-by: kaancaglan --- tools/union-test/tests/e2e_lst.rs | 338 ++++++++++++++++++++++++++++-- 1 file changed, 322 insertions(+), 16 deletions(-) diff --git a/tools/union-test/tests/e2e_lst.rs b/tools/union-test/tests/e2e_lst.rs index a89b746536..56c5d6836d 100644 --- a/tools/union-test/tests/e2e_lst.rs +++ b/tools/union-test/tests/e2e_lst.rs @@ -313,7 +313,7 @@ async fn ensure_channels_opened(channel_count: usize) { } #[tokio::test] -async fn test_escher_lst() { +async fn test_escher_lst_success() { let ctx = init_ctx().await; let (evm_address, evm_provider) = ctx.dst.get_provider().await; @@ -487,9 +487,9 @@ async fn test_escher_lst() { let zkgm_msg_json = make_zkgm_call_payload( lst_hub, "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", - "1000000", + "150", "muno", - 1000000, + 150, ); let proxy_balance = ctx @@ -515,7 +515,7 @@ async fn test_escher_lst() { sender: evm_address.to_vec().into(), receiver, base_token: u_on_eth.to_vec().into(), - base_amount: "150".parse().unwrap(), //giving 150 but expecting 1000000 so it will fail. + base_amount: "150".parse().unwrap(), kind: TOKEN_ORDER_KIND_SOLVE, metadata: SolverMetadata { solverAddress: vault_on_union.as_bytes().into(), @@ -524,7 +524,7 @@ async fn test_escher_lst() { .abi_encode_params() .into(), quote_token: "muno".as_bytes().into(), - quote_amount: "150".parse().unwrap(), //giving 150 but expecting 1000000 so it will fail. + quote_amount: "150".parse().unwrap(), } .abi_encode_params() .into(), @@ -595,8 +595,8 @@ async fn test_escher_lst() { let acked_packet = acked_packet.unwrap(); assert!( - acked_packet.tag == 0, - "Packet is acked successfully, but it should not be. Tag: {:?}", + acked_packet.tag == 1, + "Packet is not acked successfully, but it should be. Tag: {:?}", acked_packet.tag ); @@ -784,9 +784,9 @@ async fn test_escher_lst_unhappy_less_money_than_required() { let zkgm_msg_json = make_zkgm_call_payload( lst_hub, "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", - "10", + "1000000", "muno", - 10, + 1000000, ); let proxy_balance = ctx @@ -813,6 +813,7 @@ async fn test_escher_lst_unhappy_less_money_than_required() { receiver, base_token: u_on_eth.to_vec().into(), base_amount: "150".parse().unwrap(), + ///giving 150 but expecting 1000000 so it will fail. kind: TOKEN_ORDER_KIND_SOLVE, metadata: SolverMetadata { solverAddress: vault_on_union.as_bytes().into(), @@ -821,7 +822,7 @@ async fn test_escher_lst_unhappy_less_money_than_required() { .abi_encode_params() .into(), quote_token: "muno".as_bytes().into(), - quote_amount: "150".parse().unwrap(), + quote_amount: "150".parse().unwrap(), //giving 150 but expecting 1000000 so it will fail. } .abi_encode_params() .into(), @@ -892,8 +893,8 @@ async fn test_escher_lst_unhappy_less_money_than_required() { let acked_packet = acked_packet.unwrap(); assert!( - acked_packet.tag == 1, - "Packet is acked not successfully, but it should be. Tag: {:?}", + acked_packet.tag == 0, + "Packet is acked successfully, but it should not be. Tag: {:?}", acked_packet.tag ); @@ -1189,8 +1190,8 @@ async fn test_escher_lst_unhappy_wrong_denom() { let acked_packet = acked_packet.unwrap(); assert!( - acked_packet.tag == 1, - "Packet is acked not successfully, but it should be. Tag: {:?}", + acked_packet.tag == 0, + "Packet is acked successfully, but it should not be. Tag: {:?}", acked_packet.tag ); @@ -1486,8 +1487,313 @@ async fn test_escher_lst_unhappy_under_minimum_ls_amount() { let acked_packet = acked_packet.unwrap(); assert!( - acked_packet.tag == 1, - "Packet is acked not successfully, but it should be. Tag: {:?}", + acked_packet.tag == 0, + "Packet is acked successfully, but it should not be. Tag: {:?}", + acked_packet.tag + ); + + let proxy_balance = ctx + .src + .native_balance(zkgm_proxy_calculated, "muno") + .await + .unwrap(); + + println!("Proxy balance before: {}", proxy_balance); +} + +#[tokio::test] +async fn test_escher_lst_unhappy_no_funds() { + let ctx = init_ctx().await; + + let (evm_address, evm_provider) = ctx.dst.get_provider().await; + let (cosmos_address, cosmos_provider) = ctx.src.get_signer().await; + let cosmos_address_bytes = cosmos_address.to_string().into_bytes(); + + // ensure_channels_opened(ctx.channel_count).await; + // let available_channel = ctx.get_available_channel_count().await; + // assert!(available_channel > 0); + // let pair = ctx.get_channel().await.expect("channel available"); + + let dst_channel_id = 1; + let src_channel_id = 1; + + let vault_on_union = "union1skg5244hpkad603zz77kdekzw6ffgpfrde3ldk8rpdz06n62k4hqct0w4j"; + + let u_on_eth = hex_literal::hex!("0c8C6f58156D10d18193A8fFdD853e1b9F8D8836"); + + let metadata = SolverMetadata { + solverAddress: u_on_eth.to_vec().into(), + metadata: Default::default(), + } + .abi_encode_params(); + + let instruction_cosmos = Instruction { + version: INSTR_VERSION_2, + opcode: OP_TOKEN_ORDER, + operand: TokenOrderV2 { + sender: cosmos_address_bytes.clone().into(), + receiver: evm_address.to_vec().into(), + base_token: "muno".as_bytes().into(), + base_amount: "100000".parse().unwrap(), + kind: TOKEN_ORDER_KIND_SOLVE, + metadata: metadata.into(), + quote_token: u_on_eth.to_vec().into(), + quote_amount: "100000".parse().unwrap(), + } + .abi_encode_params() + .into(), + }; + + let (_, zkgm_deployer_provider) = ctx.dst.get_provider_privileged().await; + println!("registering u counterpart"); + ctx.dst + .u_register_fungible_counterpart( + H160::from(u_on_eth), + zkgm_deployer_provider.clone(), + alloy::primitives::U256::ZERO, + dst_channel_id, + b"muno".to_vec().into(), + evm::u::U::FungibleCounterparty { + beneficiary: vault_on_union.as_bytes().to_vec().into(), + }, + ) + .await + .unwrap(); + println!("u counterpart is registered"); + + let mut salt_bytes = [0u8; 32]; + rand::rng().fill_bytes(&mut salt_bytes); + + let cw_msg = ucs03_zkgm::msg::ExecuteMsg::Send { + channel_id: src_channel_id.try_into().unwrap(), + timeout_height: 0u64.into(), + timeout_timestamp: voyager_sdk::primitives::Timestamp::from_secs(u32::MAX.into()), + salt: salt_bytes.into(), + instruction: instruction_cosmos.abi_encode_params().into(), + }; + let bin_msg: Vec = Encode::::encode(&cw_msg); + + let funds = vec![Coin { + denom: "muno".into(), + amount: "100000".into(), + }]; + + let contract: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); + + let ack_packet_data = ctx + .send_and_recv_and_ack_with_retry::( + &ctx.src, + contract, + (bin_msg, funds), + &ctx.dst, + 3, + Duration::from_secs(20), + Duration::from_secs(720), + cosmos_provider, + ) + .await; + + assert!( + ack_packet_data.is_ok(), + "Failed to send and ack packet: {:?}", + ack_packet_data.err() + ); + + let new_u_balance = ctx + .dst + .zkgmerc20_balance_of( + H160::from(u_on_eth), + evm_address.into(), + evm_provider.clone(), + ) + .await + .unwrap(); + + let new_vault_balance = ctx + .src + .native_balance(Bech32::from_str(vault_on_union).unwrap(), "muno") + .await + .unwrap(); + + // both balances are updated + assert!(new_u_balance > U256::ZERO); + assert!(new_vault_balance > 0); + + println!("new_u_balance: {}", new_u_balance); + + let lst_hub = "union1fdg764zzxwvwyqkx3fuj0236l9ddh5xmutgvj2mv9cduffy82z9sp62ygc"; + // let lst = "union1jansh23v7teaznyljq6ss4vx6eym8yrz0dsjchap4u7j3etx94vqhmcwn5"; + + let addr: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); + let canon = cosmwasm_std::CanonicalAddr::from(addr.data().as_ref()); + + let zkgm_proxy_canon = instantiate2_address( + // Checksum of the base contract + &hex_literal::hex!("ec827349ed4c1fec5a9c3462ff7c979d4c40e7aa43b16ed34469d04ff835f2a1"), + &canon, + proxy_account_salt_for_tests( + alloy::primitives::U256::ZERO, + dst_channel_id, + evm_address.as_slice(), + ) + .get() + .as_slice(), + ) + .unwrap(); + + let hrp = Bech32::>::from_str(UNION_ZKGM_ADDRESS) + .unwrap() + .hrp() + .to_string(); + + // 3. Build a Bech32 address with same HRP + let zkgm_proxy_calculated = Bech32::>::new( + hrp, + FixedBytes::<32>::try_from(zkgm_proxy_canon.as_slice()).unwrap(), + ); + println!("ZKGM Proxy: {}", zkgm_proxy_calculated); + + // let zkgm_proxy = zkgm_proxy_calculated.to_string().as_str(); + + // let bond_message: Bytes = json!({ + // "bond": { + // "mint_to_address": "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", + // "min_mint_amount": "3" + // } + // }) + // .to_string() + // .as_bytes() + // .into(); + + // let zkgm_message = json!({ + // "contract": lst_hub, + // "msg": bond_message.to_string(), + // "funds": [{ "denom": "muno", "amount": "3" }], + // "call_action": "call_proxy" + // }) + // .to_string(); + + let bond = BondMsg { + bond: BondInner { + mint_to_address: "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", + min_mint_amount: "0", + }, + }; + + let wasm_exec: CosmosMsg = CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: lst_hub.to_string(), + msg: to_json_binary(&bond).unwrap(), + funds: vec![], // no funds array so it will fail. + }); + + let zkgm_msg_json = + voyager_sdk::serde_json::to_string(&vec![wasm_exec]).expect("vec cosmosmsg json"); + + let proxy_balance = ctx + .src + .native_balance(zkgm_proxy_calculated.clone(), "muno") + .await + .unwrap(); + + println!("Proxy balance before: {}", proxy_balance); + + let addr_str = zkgm_proxy_calculated.to_string(); + let receiver = addr_str.into_bytes().into(); + + let instruction_from_evm_to_union = InstructionEvm { + version: INSTR_VERSION_0, + opcode: OP_BATCH, + operand: Batch { + instructions: vec![ + Instruction { + version: INSTR_VERSION_2, + opcode: OP_TOKEN_ORDER, + operand: TokenOrderV2 { + sender: evm_address.to_vec().into(), + receiver, + base_token: u_on_eth.to_vec().into(), + base_amount: "150".parse().unwrap(), //giving 150 but expecting 1000000 so it will fail. + kind: TOKEN_ORDER_KIND_SOLVE, + metadata: SolverMetadata { + solverAddress: vault_on_union.as_bytes().into(), + metadata: Default::default(), + } + .abi_encode_params() + .into(), + quote_token: "muno".as_bytes().into(), + quote_amount: "150".parse().unwrap(), //giving 150 but expecting 1000000 so it will fail. + } + .abi_encode_params() + .into(), + }, + Instruction { + version: INSTR_VERSION_0, + opcode: OP_CALL, + operand: Call { + sender: evm_address.to_vec().into(), + eureka: false, + contract_address: zkgm_proxy_calculated + .to_string() + .as_bytes() + .to_vec() + .into(), + contract_calldata: zkgm_msg_json.as_bytes().to_vec().into(), + } + .abi_encode_params() + .into(), + }, + ], + } + .abi_encode_params() + .into(), + }; + + let approve_tx_hash = ctx + .dst + .zkgmerc20_approve( + u_on_eth.into(), + EVM_ZKGM_BYTES.into(), + U256::from(100000000000u64), + evm_provider.clone(), + ) + .await; + + assert!( + approve_tx_hash.is_ok(), + "Failed to send approve transaction: {:?}, from_account: {:?}", + approve_tx_hash.err(), + evm_address + ); + + let ucs03_zkgm = UCS03Zkgm::new(EVM_ZKGM_BYTES.into(), evm_provider.clone()); + + let call = ucs03_zkgm + .send( + dst_channel_id, + 0u64, + 4294967295000000000u64, + salt_bytes.into(), + instruction_from_evm_to_union.clone(), + ) + .clear_decoder(); + + let acked_packet = ctx + .send_and_recv_and_ack_with_retry::( + &ctx.dst, + EVM_ZKGM_BYTES.into(), + call, + &ctx.src, + 3, + Duration::from_secs(20), + Duration::from_secs(720), + &evm_provider, + ) + .await; + + let acked_packet = acked_packet.unwrap(); + assert!( + acked_packet.tag == 0, + "Packet is acked successfully, but it should not be. Tag: {:?}", acked_packet.tag ); From 50805e41caab8f229f3f37a76d9a2200132bedea Mon Sep 17 00:00:00 2001 From: aeryz Date: Sun, 21 Sep 2025 20:37:04 +0300 Subject: [PATCH 12/33] chore: bunch of stuff Signed-off-by: aeryz --- Cargo.lock | 2 + cosmwasm/lst/src/contract.rs | 2 + tools/union-test/Cargo.toml | 2 +- tools/union-test/src/cosmos_helpers.rs | 30 + tools/union-test/src/evm.rs | 13 +- tools/union-test/src/lib.rs | 22 +- tools/union-test/tests/e2e.rs | 2 - tools/union-test/tests/e2e_lst.rs | 1819 ------------------------ tools/union-test/tests/lib.rs | 1 + tools/union-test/tests/lst/bond.rs | 1547 ++++++++++++++++++++ tools/union-test/tests/lst/config.json | 114 ++ tools/union-test/tests/lst/mod.rs | 266 ++++ 12 files changed, 1978 insertions(+), 1842 deletions(-) create mode 100644 tools/union-test/src/cosmos_helpers.rs delete mode 100644 tools/union-test/tests/e2e_lst.rs create mode 100644 tools/union-test/tests/lib.rs create mode 100644 tools/union-test/tests/lst/bond.rs create mode 100644 tools/union-test/tests/lst/config.json create mode 100644 tools/union-test/tests/lst/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 3353ffe9e1..e6eef67e1b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15241,6 +15241,7 @@ name = "union-test" version = "0.0.0" dependencies = [ "alloy", + "alloy-sol-types", "axum 0.8.3", "bip32 0.5.3", "cometbft-rpc", @@ -15254,6 +15255,7 @@ dependencies = [ "ibc-union-msg", "ibc-union-spec", "jsonrpsee 0.25.1", + "lst", "once_cell", "protos", "rand 0.8.5", diff --git a/cosmwasm/lst/src/contract.rs b/cosmwasm/lst/src/contract.rs index 66498f1efe..468163f6a0 100644 --- a/cosmwasm/lst/src/contract.rs +++ b/cosmwasm/lst/src/contract.rs @@ -58,6 +58,8 @@ // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND // TITLE. +#[cfg(not(feature = "library"))] +use cosmwasm_std::entry_point; use cosmwasm_std::{ ensure, to_json_binary, Binary, Deps, DepsMut, Env, Event, MessageInfo, Response, StdResult, }; diff --git a/tools/union-test/Cargo.toml b/tools/union-test/Cargo.toml index 3968726e8e..a98b16e369 100644 --- a/tools/union-test/Cargo.toml +++ b/tools/union-test/Cargo.toml @@ -37,7 +37,7 @@ trusted-mpt-light-client-types = { workspace = true, features = ["serde", "binco ucs03-zkgm = { workspace = true, features = ["library"] } unionlabs = { workspace = true } voyager-sdk = { workspace = true } - +lst = { workspace = true, features = [ "library" ] } [dev-dependencies] once_cell = "1.17" diff --git a/tools/union-test/src/cosmos_helpers.rs b/tools/union-test/src/cosmos_helpers.rs new file mode 100644 index 0000000000..bfbd85aef9 --- /dev/null +++ b/tools/union-test/src/cosmos_helpers.rs @@ -0,0 +1,30 @@ +use std::str::FromStr; + +use cosmwasm_std::{instantiate2_address, Addr}; +use hex_literal::hex; +use unionlabs::primitives::Bech32; +use voyager_sdk::anyhow; + +pub const COSMOS_BASE_CONTRACT_HASH: [u8; 32] = + hex!("ec827349ed4c1fec5a9c3462ff7c979d4c40e7aa43b16ed34469d04ff835f2a1"); + +pub const SALT_IBC_CORE: &[u8] = b"ibc-is-based"; +pub const SALT_ZKGM: &[u8] = b"protocols/ucs03"; +pub const SALT_ESCROW_VAULT: &[u8] = + &hex!("50bbead29d10abe51a7c32bbc02a9b00ff4a7db57c050b7a0ff61d6173c33965"); +pub const SALT_LST_HUB: &[u8] = b"apps/lst"; +pub const SALT_EU: &[u8] = b"tokens/eu"; + +pub fn calculate_cosmos_contract_address(creator: &str, salt: &[u8]) -> anyhow::Result { + let bech_addr: Bech32 = Bech32::from_str(creator).unwrap(); + + let addr = instantiate2_address( + &COSMOS_BASE_CONTRACT_HASH, + &bech_addr.data().as_ref().into(), + salt, + )?; + + let bech_addr = Bech32::new(bech_addr.hrp(), addr.as_slice()); + + Ok(Addr::unchecked(bech_addr.to_string())) +} diff --git a/tools/union-test/src/evm.rs b/tools/union-test/src/evm.rs index f3db96298c..f84e05a5d0 100644 --- a/tools/union-test/src/evm.rs +++ b/tools/union-test/src/evm.rs @@ -33,7 +33,7 @@ use voyager_sdk::{ use crate::helpers; #[derive(Debug)] -pub struct Module<'a> { +pub struct Module { pub chain_id: ChainId, pub ibc_handler_address: H160, @@ -50,8 +50,6 @@ pub struct Module<'a> { pub fixed_gas_price: Option, pub gas_multiplier: f64, - - pub _marker: PhantomData<&'a ()>, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -76,7 +74,7 @@ pub struct Config { pub gas_multiplier: f64, } -impl<'a> Module<'a> { +impl Module { pub async fn new(config: Config) -> anyhow::Result { let provider = DynProvider::new( ProviderBuilder::new() @@ -139,7 +137,6 @@ impl<'a> Module<'a> { max_gas_price: config.max_gas_price, fixed_gas_price: config.fixed_gas_price, gas_multiplier: config.gas_multiplier, - _marker: PhantomData, }) } @@ -727,9 +724,7 @@ impl<'a> Module<'a> { pub async fn send_ibc_transaction( &self, - _contract: H160, - msg: RawCallBuilder<&DynProvider, AnyNetwork>, - _provider: &DynProvider, + msg: RawCallBuilder, AnyNetwork>, ) -> RpcResult<(FixedBytes<32>, u64)> { let res = self .keyring @@ -790,7 +785,7 @@ impl<'a> Module<'a> { pub async fn submit_transaction( &self, _wallet: &LocalSigner, - mut call: RawCallBuilder<&DynProvider, AnyNetwork>, + mut call: RawCallBuilder, AnyNetwork>, ) -> Result { if let Some(max_gas_price) = self.max_gas_price { let gas_price = self diff --git a/tools/union-test/src/lib.rs b/tools/union-test/src/lib.rs index 4ffd44a010..bda8aa6903 100644 --- a/tools/union-test/src/lib.rs +++ b/tools/union-test/src/lib.rs @@ -3,12 +3,14 @@ use std::{future::Future, sync::Arc, time::Duration}; use alloy::{contract::RawCallBuilder, network::AnyNetwork, providers::DynProvider}; // use axum::async_trait; use cosmos_client::wallet::LocalSigner; +use cosmwasm_std::Addr; use ibc_union_spec::{ path::{BatchPacketsPath, StorePath}, ChannelId, MustBeZero, Packet, }; use jsonrpsee::http_client::HttpClient; use protos::cosmos::base::v1beta1::Coin; +use regex::Regex; use unionlabs::{ ibc::core::client::height::Height, primitives::{Bech32, Bytes, FixedBytes, H160, H256}, @@ -21,10 +23,10 @@ use voyager_sdk::{ }; pub mod channel_provider; pub mod cosmos; +pub mod cosmos_helpers; pub mod evm; pub mod helpers; pub mod voyager; -use regex::Regex; use crate::{ channel_provider::{ChannelConfirm, ChannelPair, ChannelPool}, @@ -140,8 +142,8 @@ pub trait IbcEventHash { type Hash; } -impl<'a> ChainEndpoint for evm::Module<'a> { - type Msg = RawCallBuilder<&'a DynProvider, AnyNetwork>; +impl ChainEndpoint for evm::Module { + type Msg = RawCallBuilder, AnyNetwork>; type Contract = H160; type PredictWrappedTokenResponse = H160; type PredictWrappedTokenFromMetadataImageV2Response = H160; @@ -278,13 +280,11 @@ impl<'a> ChainEndpoint for evm::Module<'a> { async fn send_ibc_transaction( &self, - contract: Self::Contract, + _: Self::Contract, msg: Self::Msg, - signer: &Self::ProviderType, + _: &Self::ProviderType, ) -> anyhow::Result<(H256, u64)> { - self.send_ibc_transaction(contract, msg, signer) - .await - .map_err(Into::into) + self.send_ibc_transaction(msg).await.map_err(Into::into) } async fn wait_for_packet_recv( @@ -326,7 +326,7 @@ impl IbcEventHash for ibc_solidity::Ibc::PacketRecv { impl ChainEndpoint for cosmos::Module { type Msg = (Vec, Vec); - type Contract = Bech32; + type Contract = Addr; type PredictWrappedTokenResponse = String; type PredictWrappedTokenFromMetadataImageV2Response = String; type ProviderType = LocalSigner; @@ -485,8 +485,8 @@ where channel_count: usize, voyager_config_file_path: &str, ) -> anyhow::Result { - voyager::init_fetch(voyager_config_file_path, src.chain_id().clone())?; - voyager::init_fetch(voyager_config_file_path, dst.chain_id().clone())?; + // voyager::init_fetch(voyager_config_file_path, src.chain_id().clone())?; + // voyager::init_fetch(voyager_config_file_path, dst.chain_id().clone())?; let channel_pool = ChannelPool::new(); println!( "Creating test context for {} and {}. Init_fetch called for both chains.", diff --git a/tools/union-test/tests/e2e.rs b/tools/union-test/tests/e2e.rs index 9b6878cb81..64d9c82084 100644 --- a/tools/union-test/tests/e2e.rs +++ b/tools/union-test/tests/e2e.rs @@ -1,5 +1,3 @@ -// tests/e2e.rs - use std::{ num::NonZero, str::FromStr, diff --git a/tools/union-test/tests/e2e_lst.rs b/tools/union-test/tests/e2e_lst.rs deleted file mode 100644 index 56c5d6836d..0000000000 --- a/tools/union-test/tests/e2e_lst.rs +++ /dev/null @@ -1,1819 +0,0 @@ -// tests/e2e_lst.rs - -use std::{ - num::NonZero, - str::FromStr, - sync::Arc, - time::{Duration, SystemTime, UNIX_EPOCH}, -}; - -use alloy::{ - hex::decode as hex_decode, - sol_types::{SolCall, SolValue}, -}; -use concurrent_keyring::{KeyringConfig, KeyringConfigEntry}; -use cosmos::{FeemarketConfig, GasFillerConfig}; -use cosmwasm_std::{instantiate2_address, to_json_binary, Coin as CwCoin, CosmosMsg, WasmMsg}; -use cw20::Cw20ExecuteMsg; -use hex_literal::hex; -use ibc_union_spec::ChannelId; -use protos::cosmos::base::v1beta1::Coin; -use rand::RngCore; -use serde::Serialize; -use tokio::sync::OnceCell; -use ucs03_zkgm::{ - self, - com::{ - Batch, Call, Instruction, SolverMetadata, TokenOrderV1, TokenOrderV2, INSTR_VERSION_0, - INSTR_VERSION_1, INSTR_VERSION_2, OP_BATCH, OP_CALL, OP_FORWARD, OP_TOKEN_ORDER, - TOKEN_ORDER_KIND_ESCROW, TOKEN_ORDER_KIND_INITIALIZE, TOKEN_ORDER_KIND_SOLVE, - TOKEN_ORDER_KIND_UNESCROW, - }, -}; -use union_test::{ - cosmos::{self}, - evm::{ - self, - zkgm::{ - IBCPacket, Instruction as InstructionEvm, MsgPacketRecv, UCS03Zkgm, ZkgmPacket, IBC, - }, - zkgmerc20::ZkgmERC20, - }, - TestContext, -}; -use unionlabs::{ - encoding::{Encode, Json}, - ethereum::keccak256, - primitives::{encoding::Base64, Bech32, Bytes, FixedBytes, H160, U256}, -}; -use voyager_sdk::{ - primitives::{ChainId, Timestamp}, - serde_json::json, -}; -static CTX: OnceCell>> = OnceCell::const_new(); -static CHANNELS_OPENED: OnceCell<()> = OnceCell::const_new(); -// static ERC20: OnceCell = OnceCell::const_new(); - -static UNION_ZKGM_ADDRESS: &str = - "union1rfz3ytg6l60wxk5rxsk27jvn2907cyav04sz8kde3xhmmf9nplxqr8y05c"; -// static UNION_MINTER_ADDRESS: &str = -// "union1tt6nn3qv0q0z4gq4s2h65a2acv3lcwxjwf8ey3jgnwmtqkfnyq9q4q5y8x"; -static EVM_ZKGM_BYTES: [u8; 20] = hex!("05fd55c1abe31d3ed09a76216ca8f0372f4b2ec5"); -static EVM_IBC_BYTES: [u8; 20] = hex!("ed2af2aD7FE0D92011b26A2e5D1B4dC7D12A47C5"); - -// u: union1pntx7gm7shsp6slef74ae7wvcc35t3wdmanh7wrg4xkq95m24qds5atmcp -// lst: union1fdg764zzxwvwyqkx3fuj0236l9ddh5xmutgvj2mv9cduffy82z9sp62ygc - -#[derive(Serialize)] -struct BondInner<'a> { - mint_to_address: &'a str, - min_mint_amount: &'a str, -} -#[derive(Serialize)] -struct BondMsg<'a> { - bond: BondInner<'a>, -} - -fn make_zkgm_call_payload( - lst_hub: &str, - mint_to: &str, - min_amount: &str, - funds_denom: &str, - funds_amount: u32, -) -> String { - let bond = BondMsg { - bond: BondInner { - mint_to_address: mint_to, - min_mint_amount: min_amount, - }, - }; - - let wasm_exec: CosmosMsg = CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: lst_hub.to_string(), - msg: to_json_binary(&bond).unwrap(), - funds: vec![CwCoin { - denom: funds_denom.to_string(), - amount: funds_amount.into(), - }], - }); - - voyager_sdk::serde_json::to_string(&vec![wasm_exec]).expect("vec cosmosmsg json") -} - -async fn init_ctx<'a>() -> Arc>> { - CTX.get_or_init(|| async { - let cosmos_cfg = cosmos::Config { - chain_id: ChainId::new("union-devnet-1"), - ibc_host_contract_address: Bech32::from_str( - "union1nk3nes4ef6vcjan5tz6stf9g8p08q2kgqysx6q5exxh89zakp0msq5z79t", - ) - .unwrap(), - privileged_acc_keyring: KeyringConfig { - name: "privileged_acc".into(), - keys: vec![KeyringConfigEntry::Raw { - name: "privileged_acc".into(), - key: hex!("aa820fa947beb242032a41b6dc9a8b9c37d8f5fbcda0966b1ec80335b10a7d6f") - .to_vec(), - }], - }, - keyring: KeyringConfig { - name: "alice".into(), - keys: vec![ - KeyringConfigEntry::Raw { - name: "bob".into(), - key: hex_literal::hex!( - "f562d20f0a4ffd8814d262f7023f33971cbcd14a96d60027585777f174b9cdeb" - ) - .to_vec(), - }, - KeyringConfigEntry::Raw { - name: "dave".into(), - key: hex_literal::hex!( - "edc165ff1ebc27044ddc284c9cf5da656dcbff324f6ecbb9d3203cf5f4738d6d" - ) - .to_vec(), - }, - KeyringConfigEntry::Raw { - name: "charlie".into(), - key: hex_literal::hex!( - "a1f713e0f36404586085a599a45ca8233e23709e23cd54bc8d5452ef8f7bc1e6" - ) - .to_vec(), - }, - ], - }, - rpc_url: "http://0.0.0.0:26657".into(), - gas_config: GasFillerConfig::Feemarket(FeemarketConfig { - max_gas: 10000000, - gas_multiplier: Some(1.4), - denom: None, - }), - fee_recipient: None, - }; - let evm_cfg = evm::Config { - chain_id: ChainId::new("32382"), - ibc_handler_address: hex!("ed2af2aD7FE0D92011b26A2e5D1B4dC7D12A47C5").into(), - multicall_address: hex!("84c4c2ee43ccfd523af9f78740256e0f60d38068").into(), - rpc_url: "http://0.0.0.0:8545".into(), - ws_url: "ws://0.0.0.0:8546".into(), - privileged_acc_keyring: KeyringConfig { - name: "zkgm-deployer".into(), - keys: vec![KeyringConfigEntry::Raw { - name: "zkgm-deployer-key".into(), - key: hex!("4e9444a6efd6d42725a250b650a781da2737ea308c839eaccb0f7f3dbd2fea77") - .to_vec(), - }], - }, - keyring: KeyringConfig { - name: "evm-keyring".into(), - keys: vec![ - KeyringConfigEntry::Raw { - name: "dev-key0.prv".into(), - key: hex!( - "4e9444a6efd6d42725a250b650a781da2737ea308c839eaccb0f7f3dbd2fea77" - ) - .to_vec(), - }, - // KeyringConfigEntry::Raw { - // name: "dev-key1.prv".into(), - // key: hex!( - // "d9c5dc47ed678fc3e63249953866d79e5cf48418e79d8eec1a985be7393ef3b9" - // ) - // .to_vec(), - // }, - // KeyringConfigEntry::Raw { - // name: "dev-key2.prv".into(), - // key: hex!( - // "eadf66c84a1c2768a14e883512724d6023a54d500bf91d910a7dace376a97d6b" - // ) - // .to_vec(), - // }, - // KeyringConfigEntry::Raw { - // name: "dev-key3.prv".into(), - // key: hex!( - // "d56f932b298ba86341037f3871141a707330316f6f9493641a2cd59ba4a53710" - // ) - // .to_vec(), - // }, - // KeyringConfigEntry::Raw { - // name: "dev-key4.prv".into(), - // key: hex!( - // "084494a1ff88a1319e493d32aa6e127ab0eaaaf74b8714edfd670a9ddc4a060d" - // ) - // .to_vec(), - // }, - // KeyringConfigEntry::Raw { - // name: "dev-key5.prv".into(), - // key: hex!( - // "f977996449841b13ce9bbb99873006e04590ddbe28d9cd449dd33505851e74ba" - // ) - // .to_vec(), - // }, - // KeyringConfigEntry::Raw { - // name: "dev-key6.prv".into(), - // key: hex!( - // "523776c0e15a5826c85f08e0dd20d70190b0001e87f6ff9f25854d10f24db63c" - // ) - // .to_vec(), - // }, - // KeyringConfigEntry::Raw { - // name: "dev-key7.prv".into(), - // key: hex!( - // "b7d500ecae3d26deaa9547557822c95208163e230cc04345bd223da99f5bd058" - // ) - // .to_vec(), - // }, - ], - }, - max_gas_price: None, - fixed_gas_price: None, - gas_multiplier: 2.0, - }; - let src = cosmos::Module::new(cosmos_cfg).await.unwrap(); - let dst = evm::Module::new(evm_cfg).await.unwrap(); - let needed_channel_count = 1; // TODO: Hardcoded now, it will be specified from config later. - - // TODO(aeryz): move config file into the testing framework's own config file - let ctx = TestContext::new( - src, - dst, - needed_channel_count, - "/home/kaancaglan/dev/union/union/voyager/config.jsonc", - ) - .await - .unwrap_or_else(|e| panic!("failed to build TestContext: {:#?}", e)); - - Arc::new(ctx) - }) - .await - .clone() -} - -async fn ensure_channels_opened(channel_count: usize) { - CHANNELS_OPENED - .get_or_init(|| async move { - let ctx = init_ctx().await; - - let (src_client, dst_client) = ctx - .create_clients( - Duration::from_secs(60), - "ibc-cosmwasm", - "trusted/evm/mpt", - "ibc-solidity", - "cometbls", - ) - .await - .unwrap(); - - assert!(src_client.client_id > 0); - assert!(dst_client.client_id > 0); - - let conn = ctx - .open_connection::( - &ctx.src, - src_client.client_id, - &ctx.dst, - dst_client.client_id, - Duration::from_secs(180), - ) - .await - .unwrap(); - assert!(conn.connection_id > 0); - assert!(conn.counterparty_connection_id > 0); - - let current_available_count = ctx.get_available_channel_count().await; - - let opened = ctx - .open_channels( - true, - UNION_ZKGM_ADDRESS.as_bytes().into(), - EVM_ZKGM_BYTES.to_vec().into(), - conn.counterparty_connection_id, - "ucs03-zkgm-0".into(), - channel_count, - Duration::from_secs(360 * channel_count as u64), - ) - .await - .unwrap(); - assert_eq!(opened, channel_count); - - let available_count_after_open = ctx.get_available_channel_count().await; - assert_eq!( - current_available_count + channel_count, - available_count_after_open - ); - let pair = ctx.get_channel().await.expect("channel available"); - let available_count_after_get = ctx.get_available_channel_count().await; - assert_eq!(available_count_after_open - 1, available_count_after_get); - ctx.release_channel(pair).await; - let available_count_after_release = ctx.get_available_channel_count().await; - assert_eq!(available_count_after_open, available_count_after_release); - }) - .await; -} - -#[tokio::test] -async fn test_escher_lst_success() { - let ctx = init_ctx().await; - - let (evm_address, evm_provider) = ctx.dst.get_provider().await; - let (cosmos_address, cosmos_provider) = ctx.src.get_signer().await; - let cosmos_address_bytes = cosmos_address.to_string().into_bytes(); - - // ensure_channels_opened(ctx.channel_count).await; - // let available_channel = ctx.get_available_channel_count().await; - // assert!(available_channel > 0); - // let pair = ctx.get_channel().await.expect("channel available"); - - let dst_channel_id = 1; - let src_channel_id = 1; - - let vault_on_union = "union1skg5244hpkad603zz77kdekzw6ffgpfrde3ldk8rpdz06n62k4hqct0w4j"; - - let u_on_eth = hex_literal::hex!("0c8C6f58156D10d18193A8fFdD853e1b9F8D8836"); - - let metadata = SolverMetadata { - solverAddress: u_on_eth.to_vec().into(), - metadata: Default::default(), - } - .abi_encode_params(); - - let instruction_cosmos = Instruction { - version: INSTR_VERSION_2, - opcode: OP_TOKEN_ORDER, - operand: TokenOrderV2 { - sender: cosmos_address_bytes.clone().into(), - receiver: evm_address.to_vec().into(), - base_token: "muno".as_bytes().into(), - base_amount: "100000".parse().unwrap(), - kind: TOKEN_ORDER_KIND_SOLVE, - metadata: metadata.into(), - quote_token: u_on_eth.to_vec().into(), - quote_amount: "100000".parse().unwrap(), - } - .abi_encode_params() - .into(), - }; - - let (_, zkgm_deployer_provider) = ctx.dst.get_provider_privileged().await; - println!("registering u counterpart"); - ctx.dst - .u_register_fungible_counterpart( - H160::from(u_on_eth), - zkgm_deployer_provider.clone(), - alloy::primitives::U256::ZERO, - dst_channel_id, - b"muno".to_vec().into(), - evm::u::U::FungibleCounterparty { - beneficiary: vault_on_union.as_bytes().to_vec().into(), - }, - ) - .await - .unwrap(); - println!("u counterpart is registered"); - - let mut salt_bytes = [0u8; 32]; - rand::rng().fill_bytes(&mut salt_bytes); - - let cw_msg = ucs03_zkgm::msg::ExecuteMsg::Send { - channel_id: src_channel_id.try_into().unwrap(), - timeout_height: 0u64.into(), - timeout_timestamp: voyager_sdk::primitives::Timestamp::from_secs(u32::MAX.into()), - salt: salt_bytes.into(), - instruction: instruction_cosmos.abi_encode_params().into(), - }; - let bin_msg: Vec = Encode::::encode(&cw_msg); - - let funds = vec![Coin { - denom: "muno".into(), - amount: "100000".into(), - }]; - - let contract: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); - - let ack_packet_data = ctx - .send_and_recv_and_ack_with_retry::( - &ctx.src, - contract, - (bin_msg, funds), - &ctx.dst, - 3, - Duration::from_secs(20), - Duration::from_secs(720), - cosmos_provider, - ) - .await; - - assert!( - ack_packet_data.is_ok(), - "Failed to send and ack packet: {:?}", - ack_packet_data.err() - ); - - let new_u_balance = ctx - .dst - .zkgmerc20_balance_of( - H160::from(u_on_eth), - evm_address.into(), - evm_provider.clone(), - ) - .await - .unwrap(); - - let new_vault_balance = ctx - .src - .native_balance(Bech32::from_str(vault_on_union).unwrap(), "muno") - .await - .unwrap(); - - // both balances are updated - assert!(new_u_balance > U256::ZERO); - assert!(new_vault_balance > 0); - - println!("new_u_balance: {}", new_u_balance); - - let lst_hub = "union1fdg764zzxwvwyqkx3fuj0236l9ddh5xmutgvj2mv9cduffy82z9sp62ygc"; - // let lst = "union1jansh23v7teaznyljq6ss4vx6eym8yrz0dsjchap4u7j3etx94vqhmcwn5"; - - let addr: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); - let canon = cosmwasm_std::CanonicalAddr::from(addr.data().as_ref()); - - let zkgm_proxy_canon = instantiate2_address( - // Checksum of the base contract - &hex_literal::hex!("ec827349ed4c1fec5a9c3462ff7c979d4c40e7aa43b16ed34469d04ff835f2a1"), - &canon, - proxy_account_salt_for_tests( - alloy::primitives::U256::ZERO, - dst_channel_id, - evm_address.as_slice(), - ) - .get() - .as_slice(), - ) - .unwrap(); - - let hrp = Bech32::>::from_str(UNION_ZKGM_ADDRESS) - .unwrap() - .hrp() - .to_string(); - - // 3. Build a Bech32 address with same HRP - let zkgm_proxy_calculated = Bech32::>::new( - hrp, - FixedBytes::<32>::try_from(zkgm_proxy_canon.as_slice()).unwrap(), - ); - println!("ZKGM Proxy: {}", zkgm_proxy_calculated); - - // let zkgm_proxy = zkgm_proxy_calculated.to_string().as_str(); - - // let bond_message: Bytes = json!({ - // "bond": { - // "mint_to_address": "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", - // "min_mint_amount": "3" - // } - // }) - // .to_string() - // .as_bytes() - // .into(); - - // let zkgm_message = json!({ - // "contract": lst_hub, - // "msg": bond_message.to_string(), - // "funds": [{ "denom": "muno", "amount": "3" }], - // "call_action": "call_proxy" - // }) - // .to_string(); - - let zkgm_msg_json = make_zkgm_call_payload( - lst_hub, - "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", - "150", - "muno", - 150, - ); - - let proxy_balance = ctx - .src - .native_balance(zkgm_proxy_calculated.clone(), "muno") - .await - .unwrap(); - - println!("Proxy balance before: {}", proxy_balance); - - let addr_str = zkgm_proxy_calculated.to_string(); - let receiver = addr_str.into_bytes().into(); - - let instruction_from_evm_to_union = InstructionEvm { - version: INSTR_VERSION_0, - opcode: OP_BATCH, - operand: Batch { - instructions: vec![ - Instruction { - version: INSTR_VERSION_2, - opcode: OP_TOKEN_ORDER, - operand: TokenOrderV2 { - sender: evm_address.to_vec().into(), - receiver, - base_token: u_on_eth.to_vec().into(), - base_amount: "150".parse().unwrap(), - kind: TOKEN_ORDER_KIND_SOLVE, - metadata: SolverMetadata { - solverAddress: vault_on_union.as_bytes().into(), - metadata: Default::default(), - } - .abi_encode_params() - .into(), - quote_token: "muno".as_bytes().into(), - quote_amount: "150".parse().unwrap(), - } - .abi_encode_params() - .into(), - }, - Instruction { - version: INSTR_VERSION_0, - opcode: OP_CALL, - operand: Call { - sender: evm_address.to_vec().into(), - eureka: false, - contract_address: zkgm_proxy_calculated - .to_string() - .as_bytes() - .to_vec() - .into(), - contract_calldata: zkgm_msg_json.as_bytes().to_vec().into(), - } - .abi_encode_params() - .into(), - }, - ], - } - .abi_encode_params() - .into(), - }; - - let approve_tx_hash = ctx - .dst - .zkgmerc20_approve( - u_on_eth.into(), - EVM_ZKGM_BYTES.into(), - U256::from(100000000000u64), - evm_provider.clone(), - ) - .await; - - assert!( - approve_tx_hash.is_ok(), - "Failed to send approve transaction: {:?}, from_account: {:?}", - approve_tx_hash.err(), - evm_address - ); - - let ucs03_zkgm = UCS03Zkgm::new(EVM_ZKGM_BYTES.into(), evm_provider.clone()); - - let call = ucs03_zkgm - .send( - dst_channel_id, - 0u64, - 4294967295000000000u64, - salt_bytes.into(), - instruction_from_evm_to_union.clone(), - ) - .clear_decoder(); - - let acked_packet = ctx - .send_and_recv_and_ack_with_retry::( - &ctx.dst, - EVM_ZKGM_BYTES.into(), - call, - &ctx.src, - 3, - Duration::from_secs(20), - Duration::from_secs(720), - &evm_provider, - ) - .await; - - let acked_packet = acked_packet.unwrap(); - assert!( - acked_packet.tag == 1, - "Packet is not acked successfully, but it should be. Tag: {:?}", - acked_packet.tag - ); - - let proxy_balance = ctx - .src - .native_balance(zkgm_proxy_calculated, "muno") - .await - .unwrap(); - - println!("Proxy balance before: {}", proxy_balance); -} - -#[tokio::test] -async fn test_escher_lst_unhappy_less_money_than_required() { - let ctx = init_ctx().await; - - let (evm_address, evm_provider) = ctx.dst.get_provider().await; - let (cosmos_address, cosmos_provider) = ctx.src.get_signer().await; - let cosmos_address_bytes = cosmos_address.to_string().into_bytes(); - - // ensure_channels_opened(ctx.channel_count).await; - // let available_channel = ctx.get_available_channel_count().await; - // assert!(available_channel > 0); - // let pair = ctx.get_channel().await.expect("channel available"); - - let dst_channel_id = 1; - let src_channel_id = 1; - - let vault_on_union = "union1skg5244hpkad603zz77kdekzw6ffgpfrde3ldk8rpdz06n62k4hqct0w4j"; - - let u_on_eth = hex_literal::hex!("0c8C6f58156D10d18193A8fFdD853e1b9F8D8836"); - - let metadata = SolverMetadata { - solverAddress: u_on_eth.to_vec().into(), - metadata: Default::default(), - } - .abi_encode_params(); - - let instruction_cosmos = Instruction { - version: INSTR_VERSION_2, - opcode: OP_TOKEN_ORDER, - operand: TokenOrderV2 { - sender: cosmos_address_bytes.clone().into(), - receiver: evm_address.to_vec().into(), - base_token: "muno".as_bytes().into(), - base_amount: "100000".parse().unwrap(), - kind: TOKEN_ORDER_KIND_SOLVE, - metadata: metadata.into(), - quote_token: u_on_eth.to_vec().into(), - quote_amount: "100000".parse().unwrap(), - } - .abi_encode_params() - .into(), - }; - - let (_, zkgm_deployer_provider) = ctx.dst.get_provider_privileged().await; - println!("registering u counterpart"); - ctx.dst - .u_register_fungible_counterpart( - H160::from(u_on_eth), - zkgm_deployer_provider.clone(), - alloy::primitives::U256::ZERO, - dst_channel_id, - b"muno".to_vec().into(), - evm::u::U::FungibleCounterparty { - beneficiary: vault_on_union.as_bytes().to_vec().into(), - }, - ) - .await - .unwrap(); - println!("u counterpart is registered"); - - let mut salt_bytes = [0u8; 32]; - rand::rng().fill_bytes(&mut salt_bytes); - - let cw_msg = ucs03_zkgm::msg::ExecuteMsg::Send { - channel_id: src_channel_id.try_into().unwrap(), - timeout_height: 0u64.into(), - timeout_timestamp: voyager_sdk::primitives::Timestamp::from_secs(u32::MAX.into()), - salt: salt_bytes.into(), - instruction: instruction_cosmos.abi_encode_params().into(), - }; - let bin_msg: Vec = Encode::::encode(&cw_msg); - - let funds = vec![Coin { - denom: "muno".into(), - amount: "100000".into(), - }]; - - let contract: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); - - let ack_packet_data = ctx - .send_and_recv_and_ack_with_retry::( - &ctx.src, - contract, - (bin_msg, funds), - &ctx.dst, - 3, - Duration::from_secs(20), - Duration::from_secs(720), - cosmos_provider, - ) - .await; - - assert!( - ack_packet_data.is_ok(), - "Failed to send and ack packet: {:?}", - ack_packet_data.err() - ); - - let new_u_balance = ctx - .dst - .zkgmerc20_balance_of( - H160::from(u_on_eth), - evm_address.into(), - evm_provider.clone(), - ) - .await - .unwrap(); - - let new_vault_balance = ctx - .src - .native_balance(Bech32::from_str(vault_on_union).unwrap(), "muno") - .await - .unwrap(); - - // both balances are updated - assert!(new_u_balance > U256::ZERO); - assert!(new_vault_balance > 0); - - println!("new_u_balance: {}", new_u_balance); - - let lst_hub = "union1fdg764zzxwvwyqkx3fuj0236l9ddh5xmutgvj2mv9cduffy82z9sp62ygc"; - // let lst = "union1jansh23v7teaznyljq6ss4vx6eym8yrz0dsjchap4u7j3etx94vqhmcwn5"; - - let addr: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); - let canon = cosmwasm_std::CanonicalAddr::from(addr.data().as_ref()); - - let zkgm_proxy_canon = instantiate2_address( - // Checksum of the base contract - &hex_literal::hex!("ec827349ed4c1fec5a9c3462ff7c979d4c40e7aa43b16ed34469d04ff835f2a1"), - &canon, - proxy_account_salt_for_tests( - alloy::primitives::U256::ZERO, - dst_channel_id, - evm_address.as_slice(), - ) - .get() - .as_slice(), - ) - .unwrap(); - - let hrp = Bech32::>::from_str(UNION_ZKGM_ADDRESS) - .unwrap() - .hrp() - .to_string(); - - // 3. Build a Bech32 address with same HRP - let zkgm_proxy_calculated = Bech32::>::new( - hrp, - FixedBytes::<32>::try_from(zkgm_proxy_canon.as_slice()).unwrap(), - ); - println!("ZKGM Proxy: {}", zkgm_proxy_calculated); - - // let zkgm_proxy = zkgm_proxy_calculated.to_string().as_str(); - - // let bond_message: Bytes = json!({ - // "bond": { - // "mint_to_address": "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", - // "min_mint_amount": "3" - // } - // }) - // .to_string() - // .as_bytes() - // .into(); - - // let zkgm_message = json!({ - // "contract": lst_hub, - // "msg": bond_message.to_string(), - // "funds": [{ "denom": "muno", "amount": "3" }], - // "call_action": "call_proxy" - // }) - // .to_string(); - - let zkgm_msg_json = make_zkgm_call_payload( - lst_hub, - "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", - "1000000", - "muno", - 1000000, - ); - - let proxy_balance = ctx - .src - .native_balance(zkgm_proxy_calculated.clone(), "muno") - .await - .unwrap(); - - println!("Proxy balance before: {}", proxy_balance); - - let addr_str = zkgm_proxy_calculated.to_string(); - let receiver = addr_str.into_bytes().into(); - - let instruction_from_evm_to_union = InstructionEvm { - version: INSTR_VERSION_0, - opcode: OP_BATCH, - operand: Batch { - instructions: vec![ - Instruction { - version: INSTR_VERSION_2, - opcode: OP_TOKEN_ORDER, - operand: TokenOrderV2 { - sender: evm_address.to_vec().into(), - receiver, - base_token: u_on_eth.to_vec().into(), - base_amount: "150".parse().unwrap(), - ///giving 150 but expecting 1000000 so it will fail. - kind: TOKEN_ORDER_KIND_SOLVE, - metadata: SolverMetadata { - solverAddress: vault_on_union.as_bytes().into(), - metadata: Default::default(), - } - .abi_encode_params() - .into(), - quote_token: "muno".as_bytes().into(), - quote_amount: "150".parse().unwrap(), //giving 150 but expecting 1000000 so it will fail. - } - .abi_encode_params() - .into(), - }, - Instruction { - version: INSTR_VERSION_0, - opcode: OP_CALL, - operand: Call { - sender: evm_address.to_vec().into(), - eureka: false, - contract_address: zkgm_proxy_calculated - .to_string() - .as_bytes() - .to_vec() - .into(), - contract_calldata: zkgm_msg_json.as_bytes().to_vec().into(), - } - .abi_encode_params() - .into(), - }, - ], - } - .abi_encode_params() - .into(), - }; - - let approve_tx_hash = ctx - .dst - .zkgmerc20_approve( - u_on_eth.into(), - EVM_ZKGM_BYTES.into(), - U256::from(100000000000u64), - evm_provider.clone(), - ) - .await; - - assert!( - approve_tx_hash.is_ok(), - "Failed to send approve transaction: {:?}, from_account: {:?}", - approve_tx_hash.err(), - evm_address - ); - - let ucs03_zkgm = UCS03Zkgm::new(EVM_ZKGM_BYTES.into(), evm_provider.clone()); - - let call = ucs03_zkgm - .send( - dst_channel_id, - 0u64, - 4294967295000000000u64, - salt_bytes.into(), - instruction_from_evm_to_union.clone(), - ) - .clear_decoder(); - - let acked_packet = ctx - .send_and_recv_and_ack_with_retry::( - &ctx.dst, - EVM_ZKGM_BYTES.into(), - call, - &ctx.src, - 3, - Duration::from_secs(20), - Duration::from_secs(720), - &evm_provider, - ) - .await; - - let acked_packet = acked_packet.unwrap(); - assert!( - acked_packet.tag == 0, - "Packet is acked successfully, but it should not be. Tag: {:?}", - acked_packet.tag - ); - - let proxy_balance = ctx - .src - .native_balance(zkgm_proxy_calculated, "muno") - .await - .unwrap(); - - println!("Proxy balance before: {}", proxy_balance); -} - -#[tokio::test] -async fn test_escher_lst_unhappy_wrong_denom() { - let ctx = init_ctx().await; - - let (evm_address, evm_provider) = ctx.dst.get_provider().await; - let (cosmos_address, cosmos_provider) = ctx.src.get_signer().await; - let cosmos_address_bytes = cosmos_address.to_string().into_bytes(); - - // ensure_channels_opened(ctx.channel_count).await; - // let available_channel = ctx.get_available_channel_count().await; - // assert!(available_channel > 0); - // let pair = ctx.get_channel().await.expect("channel available"); - - let dst_channel_id = 1; - let src_channel_id = 1; - - let vault_on_union = "union1skg5244hpkad603zz77kdekzw6ffgpfrde3ldk8rpdz06n62k4hqct0w4j"; - - let u_on_eth = hex_literal::hex!("0c8C6f58156D10d18193A8fFdD853e1b9F8D8836"); - - let metadata = SolverMetadata { - solverAddress: u_on_eth.to_vec().into(), - metadata: Default::default(), - } - .abi_encode_params(); - - let instruction_cosmos = Instruction { - version: INSTR_VERSION_2, - opcode: OP_TOKEN_ORDER, - operand: TokenOrderV2 { - sender: cosmos_address_bytes.clone().into(), - receiver: evm_address.to_vec().into(), - base_token: "muno".as_bytes().into(), - base_amount: "100000".parse().unwrap(), - kind: TOKEN_ORDER_KIND_SOLVE, - metadata: metadata.into(), - quote_token: u_on_eth.to_vec().into(), - quote_amount: "100000".parse().unwrap(), - } - .abi_encode_params() - .into(), - }; - - let (_, zkgm_deployer_provider) = ctx.dst.get_provider_privileged().await; - println!("registering u counterpart"); - ctx.dst - .u_register_fungible_counterpart( - H160::from(u_on_eth), - zkgm_deployer_provider.clone(), - alloy::primitives::U256::ZERO, - dst_channel_id, - b"muno".to_vec().into(), - evm::u::U::FungibleCounterparty { - beneficiary: vault_on_union.as_bytes().to_vec().into(), - }, - ) - .await - .unwrap(); - println!("u counterpart is registered"); - - let mut salt_bytes = [0u8; 32]; - rand::rng().fill_bytes(&mut salt_bytes); - - let cw_msg = ucs03_zkgm::msg::ExecuteMsg::Send { - channel_id: src_channel_id.try_into().unwrap(), - timeout_height: 0u64.into(), - timeout_timestamp: voyager_sdk::primitives::Timestamp::from_secs(u32::MAX.into()), - salt: salt_bytes.into(), - instruction: instruction_cosmos.abi_encode_params().into(), - }; - let bin_msg: Vec = Encode::::encode(&cw_msg); - - let funds = vec![Coin { - denom: "muno".into(), - amount: "100000".into(), - }]; - - let contract: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); - - let ack_packet_data = ctx - .send_and_recv_and_ack_with_retry::( - &ctx.src, - contract, - (bin_msg, funds), - &ctx.dst, - 3, - Duration::from_secs(20), - Duration::from_secs(720), - cosmos_provider, - ) - .await; - - assert!( - ack_packet_data.is_ok(), - "Failed to send and ack packet: {:?}", - ack_packet_data.err() - ); - - let new_u_balance = ctx - .dst - .zkgmerc20_balance_of( - H160::from(u_on_eth), - evm_address.into(), - evm_provider.clone(), - ) - .await - .unwrap(); - - let new_vault_balance = ctx - .src - .native_balance(Bech32::from_str(vault_on_union).unwrap(), "muno") - .await - .unwrap(); - - // both balances are updated - assert!(new_u_balance > U256::ZERO); - assert!(new_vault_balance > 0); - - println!("new_u_balance: {}", new_u_balance); - - let lst_hub = "union1fdg764zzxwvwyqkx3fuj0236l9ddh5xmutgvj2mv9cduffy82z9sp62ygc"; - // let lst = "union1jansh23v7teaznyljq6ss4vx6eym8yrz0dsjchap4u7j3etx94vqhmcwn5"; - - let addr: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); - let canon = cosmwasm_std::CanonicalAddr::from(addr.data().as_ref()); - - let zkgm_proxy_canon = instantiate2_address( - // Checksum of the base contract - &hex_literal::hex!("ec827349ed4c1fec5a9c3462ff7c979d4c40e7aa43b16ed34469d04ff835f2a1"), - &canon, - proxy_account_salt_for_tests( - alloy::primitives::U256::ZERO, - dst_channel_id, - evm_address.as_slice(), - ) - .get() - .as_slice(), - ) - .unwrap(); - - let hrp = Bech32::>::from_str(UNION_ZKGM_ADDRESS) - .unwrap() - .hrp() - .to_string(); - - // 3. Build a Bech32 address with same HRP - let zkgm_proxy_calculated = Bech32::>::new( - hrp, - FixedBytes::<32>::try_from(zkgm_proxy_canon.as_slice()).unwrap(), - ); - println!("ZKGM Proxy: {}", zkgm_proxy_calculated); - - // let zkgm_proxy = zkgm_proxy_calculated.to_string().as_str(); - - // let bond_message: Bytes = json!({ - // "bond": { - // "mint_to_address": "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", - // "min_mint_amount": "3" - // } - // }) - // .to_string() - // .as_bytes() - // .into(); - - // let zkgm_message = json!({ - // "contract": lst_hub, - // "msg": bond_message.to_string(), - // "funds": [{ "denom": "muno", "amount": "3" }], - // "call_action": "call_proxy" - // }) - // .to_string(); - - let zkgm_msg_json = make_zkgm_call_payload( - lst_hub, - "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", - "10", - "muan", // wrong denom to make it fail - 10, - ); - - let proxy_balance = ctx - .src - .native_balance(zkgm_proxy_calculated.clone(), "muno") - .await - .unwrap(); - - println!("Proxy balance before: {}", proxy_balance); - - let addr_str = zkgm_proxy_calculated.to_string(); - let receiver = addr_str.into_bytes().into(); - - let instruction_from_evm_to_union = InstructionEvm { - version: INSTR_VERSION_0, - opcode: OP_BATCH, - operand: Batch { - instructions: vec![ - Instruction { - version: INSTR_VERSION_2, - opcode: OP_TOKEN_ORDER, - operand: TokenOrderV2 { - sender: evm_address.to_vec().into(), - receiver, - base_token: u_on_eth.to_vec().into(), - base_amount: "150".parse().unwrap(), - kind: TOKEN_ORDER_KIND_SOLVE, - metadata: SolverMetadata { - solverAddress: vault_on_union.as_bytes().into(), - metadata: Default::default(), - } - .abi_encode_params() - .into(), - quote_token: "muno".as_bytes().into(), - quote_amount: "150".parse().unwrap(), - } - .abi_encode_params() - .into(), - }, - Instruction { - version: INSTR_VERSION_0, - opcode: OP_CALL, - operand: Call { - sender: evm_address.to_vec().into(), - eureka: false, - contract_address: zkgm_proxy_calculated - .to_string() - .as_bytes() - .to_vec() - .into(), - contract_calldata: zkgm_msg_json.as_bytes().to_vec().into(), - } - .abi_encode_params() - .into(), - }, - ], - } - .abi_encode_params() - .into(), - }; - - let approve_tx_hash = ctx - .dst - .zkgmerc20_approve( - u_on_eth.into(), - EVM_ZKGM_BYTES.into(), - U256::from(100000000000u64), - evm_provider.clone(), - ) - .await; - - assert!( - approve_tx_hash.is_ok(), - "Failed to send approve transaction: {:?}, from_account: {:?}", - approve_tx_hash.err(), - evm_address - ); - - let ucs03_zkgm = UCS03Zkgm::new(EVM_ZKGM_BYTES.into(), evm_provider.clone()); - - let call = ucs03_zkgm - .send( - dst_channel_id, - 0u64, - 4294967295000000000u64, - salt_bytes.into(), - instruction_from_evm_to_union.clone(), - ) - .clear_decoder(); - - let acked_packet = ctx - .send_and_recv_and_ack_with_retry::( - &ctx.dst, - EVM_ZKGM_BYTES.into(), - call, - &ctx.src, - 3, - Duration::from_secs(20), - Duration::from_secs(720), - &evm_provider, - ) - .await; - - let acked_packet = acked_packet.unwrap(); - assert!( - acked_packet.tag == 0, - "Packet is acked successfully, but it should not be. Tag: {:?}", - acked_packet.tag - ); - - let proxy_balance = ctx - .src - .native_balance(zkgm_proxy_calculated, "muno") - .await - .unwrap(); - - println!("Proxy balance before: {}", proxy_balance); -} - -#[tokio::test] -async fn test_escher_lst_unhappy_under_minimum_ls_amount() { - let ctx = init_ctx().await; - - let (evm_address, evm_provider) = ctx.dst.get_provider().await; - let (cosmos_address, cosmos_provider) = ctx.src.get_signer().await; - let cosmos_address_bytes = cosmos_address.to_string().into_bytes(); - - // ensure_channels_opened(ctx.channel_count).await; - // let available_channel = ctx.get_available_channel_count().await; - // assert!(available_channel > 0); - // let pair = ctx.get_channel().await.expect("channel available"); - - let dst_channel_id = 1; - let src_channel_id = 1; - - let vault_on_union = "union1skg5244hpkad603zz77kdekzw6ffgpfrde3ldk8rpdz06n62k4hqct0w4j"; - - let u_on_eth = hex_literal::hex!("0c8C6f58156D10d18193A8fFdD853e1b9F8D8836"); - - let metadata = SolverMetadata { - solverAddress: u_on_eth.to_vec().into(), - metadata: Default::default(), - } - .abi_encode_params(); - - let instruction_cosmos = Instruction { - version: INSTR_VERSION_2, - opcode: OP_TOKEN_ORDER, - operand: TokenOrderV2 { - sender: cosmos_address_bytes.clone().into(), - receiver: evm_address.to_vec().into(), - base_token: "muno".as_bytes().into(), - base_amount: "100000".parse().unwrap(), - kind: TOKEN_ORDER_KIND_SOLVE, - metadata: metadata.into(), - quote_token: u_on_eth.to_vec().into(), - quote_amount: "100000".parse().unwrap(), - } - .abi_encode_params() - .into(), - }; - - let (_, zkgm_deployer_provider) = ctx.dst.get_provider_privileged().await; - println!("registering u counterpart"); - ctx.dst - .u_register_fungible_counterpart( - H160::from(u_on_eth), - zkgm_deployer_provider.clone(), - alloy::primitives::U256::ZERO, - dst_channel_id, - b"muno".to_vec().into(), - evm::u::U::FungibleCounterparty { - beneficiary: vault_on_union.as_bytes().to_vec().into(), - }, - ) - .await - .unwrap(); - println!("u counterpart is registered"); - - let mut salt_bytes = [0u8; 32]; - rand::rng().fill_bytes(&mut salt_bytes); - - let cw_msg = ucs03_zkgm::msg::ExecuteMsg::Send { - channel_id: src_channel_id.try_into().unwrap(), - timeout_height: 0u64.into(), - timeout_timestamp: voyager_sdk::primitives::Timestamp::from_secs(u32::MAX.into()), - salt: salt_bytes.into(), - instruction: instruction_cosmos.abi_encode_params().into(), - }; - let bin_msg: Vec = Encode::::encode(&cw_msg); - - let funds = vec![Coin { - denom: "muno".into(), - amount: "100000".into(), - }]; - - let contract: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); - - let ack_packet_data = ctx - .send_and_recv_and_ack_with_retry::( - &ctx.src, - contract, - (bin_msg, funds), - &ctx.dst, - 3, - Duration::from_secs(20), - Duration::from_secs(720), - cosmos_provider, - ) - .await; - - assert!( - ack_packet_data.is_ok(), - "Failed to send and ack packet: {:?}", - ack_packet_data.err() - ); - - let new_u_balance = ctx - .dst - .zkgmerc20_balance_of( - H160::from(u_on_eth), - evm_address.into(), - evm_provider.clone(), - ) - .await - .unwrap(); - - let new_vault_balance = ctx - .src - .native_balance(Bech32::from_str(vault_on_union).unwrap(), "muno") - .await - .unwrap(); - - // both balances are updated - assert!(new_u_balance > U256::ZERO); - assert!(new_vault_balance > 0); - - println!("new_u_balance: {}", new_u_balance); - - let lst_hub = "union1fdg764zzxwvwyqkx3fuj0236l9ddh5xmutgvj2mv9cduffy82z9sp62ygc"; - // let lst = "union1jansh23v7teaznyljq6ss4vx6eym8yrz0dsjchap4u7j3etx94vqhmcwn5"; - - let addr: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); - let canon = cosmwasm_std::CanonicalAddr::from(addr.data().as_ref()); - - let zkgm_proxy_canon = instantiate2_address( - // Checksum of the base contract - &hex_literal::hex!("ec827349ed4c1fec5a9c3462ff7c979d4c40e7aa43b16ed34469d04ff835f2a1"), - &canon, - proxy_account_salt_for_tests( - alloy::primitives::U256::ZERO, - dst_channel_id, - evm_address.as_slice(), - ) - .get() - .as_slice(), - ) - .unwrap(); - - let hrp = Bech32::>::from_str(UNION_ZKGM_ADDRESS) - .unwrap() - .hrp() - .to_string(); - - // 3. Build a Bech32 address with same HRP - let zkgm_proxy_calculated = Bech32::>::new( - hrp, - FixedBytes::<32>::try_from(zkgm_proxy_canon.as_slice()).unwrap(), - ); - println!("ZKGM Proxy: {}", zkgm_proxy_calculated); - - // let zkgm_proxy = zkgm_proxy_calculated.to_string().as_str(); - - // let bond_message: Bytes = json!({ - // "bond": { - // "mint_to_address": "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", - // "min_mint_amount": "3" - // } - // }) - // .to_string() - // .as_bytes() - // .into(); - - // let zkgm_message = json!({ - // "contract": lst_hub, - // "msg": bond_message.to_string(), - // "funds": [{ "denom": "muno", "amount": "3" }], - // "call_action": "call_proxy" - // }) - // .to_string(); - - let zkgm_msg_json = make_zkgm_call_payload( - lst_hub, - "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", - "0", - "muno", - 0, // under minimum amount to make it fail - ); - - let proxy_balance = ctx - .src - .native_balance(zkgm_proxy_calculated.clone(), "muno") - .await - .unwrap(); - - println!("Proxy balance before: {}", proxy_balance); - - let addr_str = zkgm_proxy_calculated.to_string(); - let receiver = addr_str.into_bytes().into(); - - let instruction_from_evm_to_union = InstructionEvm { - version: INSTR_VERSION_0, - opcode: OP_BATCH, - operand: Batch { - instructions: vec![ - Instruction { - version: INSTR_VERSION_2, - opcode: OP_TOKEN_ORDER, - operand: TokenOrderV2 { - sender: evm_address.to_vec().into(), - receiver, - base_token: u_on_eth.to_vec().into(), - base_amount: "150".parse().unwrap(), - kind: TOKEN_ORDER_KIND_SOLVE, - metadata: SolverMetadata { - solverAddress: vault_on_union.as_bytes().into(), - metadata: Default::default(), - } - .abi_encode_params() - .into(), - quote_token: "muno".as_bytes().into(), - quote_amount: "150".parse().unwrap(), - } - .abi_encode_params() - .into(), - }, - Instruction { - version: INSTR_VERSION_0, - opcode: OP_CALL, - operand: Call { - sender: evm_address.to_vec().into(), - eureka: false, - contract_address: zkgm_proxy_calculated - .to_string() - .as_bytes() - .to_vec() - .into(), - contract_calldata: zkgm_msg_json.as_bytes().to_vec().into(), - } - .abi_encode_params() - .into(), - }, - ], - } - .abi_encode_params() - .into(), - }; - - let approve_tx_hash = ctx - .dst - .zkgmerc20_approve( - u_on_eth.into(), - EVM_ZKGM_BYTES.into(), - U256::from(100000000000u64), - evm_provider.clone(), - ) - .await; - - assert!( - approve_tx_hash.is_ok(), - "Failed to send approve transaction: {:?}, from_account: {:?}", - approve_tx_hash.err(), - evm_address - ); - - let ucs03_zkgm = UCS03Zkgm::new(EVM_ZKGM_BYTES.into(), evm_provider.clone()); - - let call = ucs03_zkgm - .send( - dst_channel_id, - 0u64, - 4294967295000000000u64, - salt_bytes.into(), - instruction_from_evm_to_union.clone(), - ) - .clear_decoder(); - - let acked_packet = ctx - .send_and_recv_and_ack_with_retry::( - &ctx.dst, - EVM_ZKGM_BYTES.into(), - call, - &ctx.src, - 3, - Duration::from_secs(20), - Duration::from_secs(720), - &evm_provider, - ) - .await; - - let acked_packet = acked_packet.unwrap(); - assert!( - acked_packet.tag == 0, - "Packet is acked successfully, but it should not be. Tag: {:?}", - acked_packet.tag - ); - - let proxy_balance = ctx - .src - .native_balance(zkgm_proxy_calculated, "muno") - .await - .unwrap(); - - println!("Proxy balance before: {}", proxy_balance); -} - -#[tokio::test] -async fn test_escher_lst_unhappy_no_funds() { - let ctx = init_ctx().await; - - let (evm_address, evm_provider) = ctx.dst.get_provider().await; - let (cosmos_address, cosmos_provider) = ctx.src.get_signer().await; - let cosmos_address_bytes = cosmos_address.to_string().into_bytes(); - - // ensure_channels_opened(ctx.channel_count).await; - // let available_channel = ctx.get_available_channel_count().await; - // assert!(available_channel > 0); - // let pair = ctx.get_channel().await.expect("channel available"); - - let dst_channel_id = 1; - let src_channel_id = 1; - - let vault_on_union = "union1skg5244hpkad603zz77kdekzw6ffgpfrde3ldk8rpdz06n62k4hqct0w4j"; - - let u_on_eth = hex_literal::hex!("0c8C6f58156D10d18193A8fFdD853e1b9F8D8836"); - - let metadata = SolverMetadata { - solverAddress: u_on_eth.to_vec().into(), - metadata: Default::default(), - } - .abi_encode_params(); - - let instruction_cosmos = Instruction { - version: INSTR_VERSION_2, - opcode: OP_TOKEN_ORDER, - operand: TokenOrderV2 { - sender: cosmos_address_bytes.clone().into(), - receiver: evm_address.to_vec().into(), - base_token: "muno".as_bytes().into(), - base_amount: "100000".parse().unwrap(), - kind: TOKEN_ORDER_KIND_SOLVE, - metadata: metadata.into(), - quote_token: u_on_eth.to_vec().into(), - quote_amount: "100000".parse().unwrap(), - } - .abi_encode_params() - .into(), - }; - - let (_, zkgm_deployer_provider) = ctx.dst.get_provider_privileged().await; - println!("registering u counterpart"); - ctx.dst - .u_register_fungible_counterpart( - H160::from(u_on_eth), - zkgm_deployer_provider.clone(), - alloy::primitives::U256::ZERO, - dst_channel_id, - b"muno".to_vec().into(), - evm::u::U::FungibleCounterparty { - beneficiary: vault_on_union.as_bytes().to_vec().into(), - }, - ) - .await - .unwrap(); - println!("u counterpart is registered"); - - let mut salt_bytes = [0u8; 32]; - rand::rng().fill_bytes(&mut salt_bytes); - - let cw_msg = ucs03_zkgm::msg::ExecuteMsg::Send { - channel_id: src_channel_id.try_into().unwrap(), - timeout_height: 0u64.into(), - timeout_timestamp: voyager_sdk::primitives::Timestamp::from_secs(u32::MAX.into()), - salt: salt_bytes.into(), - instruction: instruction_cosmos.abi_encode_params().into(), - }; - let bin_msg: Vec = Encode::::encode(&cw_msg); - - let funds = vec![Coin { - denom: "muno".into(), - amount: "100000".into(), - }]; - - let contract: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); - - let ack_packet_data = ctx - .send_and_recv_and_ack_with_retry::( - &ctx.src, - contract, - (bin_msg, funds), - &ctx.dst, - 3, - Duration::from_secs(20), - Duration::from_secs(720), - cosmos_provider, - ) - .await; - - assert!( - ack_packet_data.is_ok(), - "Failed to send and ack packet: {:?}", - ack_packet_data.err() - ); - - let new_u_balance = ctx - .dst - .zkgmerc20_balance_of( - H160::from(u_on_eth), - evm_address.into(), - evm_provider.clone(), - ) - .await - .unwrap(); - - let new_vault_balance = ctx - .src - .native_balance(Bech32::from_str(vault_on_union).unwrap(), "muno") - .await - .unwrap(); - - // both balances are updated - assert!(new_u_balance > U256::ZERO); - assert!(new_vault_balance > 0); - - println!("new_u_balance: {}", new_u_balance); - - let lst_hub = "union1fdg764zzxwvwyqkx3fuj0236l9ddh5xmutgvj2mv9cduffy82z9sp62ygc"; - // let lst = "union1jansh23v7teaznyljq6ss4vx6eym8yrz0dsjchap4u7j3etx94vqhmcwn5"; - - let addr: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); - let canon = cosmwasm_std::CanonicalAddr::from(addr.data().as_ref()); - - let zkgm_proxy_canon = instantiate2_address( - // Checksum of the base contract - &hex_literal::hex!("ec827349ed4c1fec5a9c3462ff7c979d4c40e7aa43b16ed34469d04ff835f2a1"), - &canon, - proxy_account_salt_for_tests( - alloy::primitives::U256::ZERO, - dst_channel_id, - evm_address.as_slice(), - ) - .get() - .as_slice(), - ) - .unwrap(); - - let hrp = Bech32::>::from_str(UNION_ZKGM_ADDRESS) - .unwrap() - .hrp() - .to_string(); - - // 3. Build a Bech32 address with same HRP - let zkgm_proxy_calculated = Bech32::>::new( - hrp, - FixedBytes::<32>::try_from(zkgm_proxy_canon.as_slice()).unwrap(), - ); - println!("ZKGM Proxy: {}", zkgm_proxy_calculated); - - // let zkgm_proxy = zkgm_proxy_calculated.to_string().as_str(); - - // let bond_message: Bytes = json!({ - // "bond": { - // "mint_to_address": "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", - // "min_mint_amount": "3" - // } - // }) - // .to_string() - // .as_bytes() - // .into(); - - // let zkgm_message = json!({ - // "contract": lst_hub, - // "msg": bond_message.to_string(), - // "funds": [{ "denom": "muno", "amount": "3" }], - // "call_action": "call_proxy" - // }) - // .to_string(); - - let bond = BondMsg { - bond: BondInner { - mint_to_address: "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", - min_mint_amount: "0", - }, - }; - - let wasm_exec: CosmosMsg = CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: lst_hub.to_string(), - msg: to_json_binary(&bond).unwrap(), - funds: vec![], // no funds array so it will fail. - }); - - let zkgm_msg_json = - voyager_sdk::serde_json::to_string(&vec![wasm_exec]).expect("vec cosmosmsg json"); - - let proxy_balance = ctx - .src - .native_balance(zkgm_proxy_calculated.clone(), "muno") - .await - .unwrap(); - - println!("Proxy balance before: {}", proxy_balance); - - let addr_str = zkgm_proxy_calculated.to_string(); - let receiver = addr_str.into_bytes().into(); - - let instruction_from_evm_to_union = InstructionEvm { - version: INSTR_VERSION_0, - opcode: OP_BATCH, - operand: Batch { - instructions: vec![ - Instruction { - version: INSTR_VERSION_2, - opcode: OP_TOKEN_ORDER, - operand: TokenOrderV2 { - sender: evm_address.to_vec().into(), - receiver, - base_token: u_on_eth.to_vec().into(), - base_amount: "150".parse().unwrap(), //giving 150 but expecting 1000000 so it will fail. - kind: TOKEN_ORDER_KIND_SOLVE, - metadata: SolverMetadata { - solverAddress: vault_on_union.as_bytes().into(), - metadata: Default::default(), - } - .abi_encode_params() - .into(), - quote_token: "muno".as_bytes().into(), - quote_amount: "150".parse().unwrap(), //giving 150 but expecting 1000000 so it will fail. - } - .abi_encode_params() - .into(), - }, - Instruction { - version: INSTR_VERSION_0, - opcode: OP_CALL, - operand: Call { - sender: evm_address.to_vec().into(), - eureka: false, - contract_address: zkgm_proxy_calculated - .to_string() - .as_bytes() - .to_vec() - .into(), - contract_calldata: zkgm_msg_json.as_bytes().to_vec().into(), - } - .abi_encode_params() - .into(), - }, - ], - } - .abi_encode_params() - .into(), - }; - - let approve_tx_hash = ctx - .dst - .zkgmerc20_approve( - u_on_eth.into(), - EVM_ZKGM_BYTES.into(), - U256::from(100000000000u64), - evm_provider.clone(), - ) - .await; - - assert!( - approve_tx_hash.is_ok(), - "Failed to send approve transaction: {:?}, from_account: {:?}", - approve_tx_hash.err(), - evm_address - ); - - let ucs03_zkgm = UCS03Zkgm::new(EVM_ZKGM_BYTES.into(), evm_provider.clone()); - - let call = ucs03_zkgm - .send( - dst_channel_id, - 0u64, - 4294967295000000000u64, - salt_bytes.into(), - instruction_from_evm_to_union.clone(), - ) - .clear_decoder(); - - let acked_packet = ctx - .send_and_recv_and_ack_with_retry::( - &ctx.dst, - EVM_ZKGM_BYTES.into(), - call, - &ctx.src, - 3, - Duration::from_secs(20), - Duration::from_secs(720), - &evm_provider, - ) - .await; - - let acked_packet = acked_packet.unwrap(); - assert!( - acked_packet.tag == 0, - "Packet is acked successfully, but it should not be. Tag: {:?}", - acked_packet.tag - ); - - let proxy_balance = ctx - .src - .native_balance(zkgm_proxy_calculated, "muno") - .await - .unwrap(); - - println!("Proxy balance before: {}", proxy_balance); -} - -fn proxy_account_salt_for_tests( - path: alloy::primitives::U256, - channel_id: u32, - sender: &[u8], -) -> unionlabs::primitives::H256 { - use alloy_sol_types::SolValue; - use unionlabs::ethereum::keccak256; - - let encoded = (path, channel_id, sender.to_vec()).abi_encode_params(); - keccak256(encoded) -} diff --git a/tools/union-test/tests/lib.rs b/tools/union-test/tests/lib.rs new file mode 100644 index 0000000000..b39d7f9cbe --- /dev/null +++ b/tools/union-test/tests/lib.rs @@ -0,0 +1 @@ +pub mod lst; diff --git a/tools/union-test/tests/lst/bond.rs b/tools/union-test/tests/lst/bond.rs new file mode 100644 index 0000000000..4df2072de9 --- /dev/null +++ b/tools/union-test/tests/lst/bond.rs @@ -0,0 +1,1547 @@ +use std::{str::FromStr, time::Duration}; + +use alloy::sol_types::SolValue; +use cosmwasm_std::{ + instantiate2_address, to_json_binary, Addr, Coin as CwCoin, CosmosMsg, Uint128, WasmMsg, +}; +use lst::msg::ExecuteMsg as LstExecuteMsg; +use protos::cosmos::base::v1beta1::Coin; +use rand::RngCore; +use ucs03_zkgm::{ + self, + com::{ + Batch, Call, Instruction, SolverMetadata, TokenOrderV2, INSTR_VERSION_0, INSTR_VERSION_2, + OP_BATCH, OP_CALL, OP_TOKEN_ORDER, TOKEN_ORDER_KIND_SOLVE, + }, +}; +use union_test::{ + cosmos::{self}, + evm::{ + self, + zkgm::{Instruction as InstructionEvm, UCS03Zkgm}, + }, +}; +use unionlabs::{ + encoding::{Encode, Json}, + primitives::{Bech32, FixedBytes, H160, U256}, +}; + +use crate::lst::*; + +// static ERC20: OnceCell = OnceCell::const_new(); + +// u: union1pntx7gm7shsp6slef74ae7wvcc35t3wdmanh7wrg4xkq95m24qds5atmcp +// lst: union1fdg764zzxwvwyqkx3fuj0236l9ddh5xmutgvj2mv9cduffy82z9sp62ygc + +fn make_zkgm_call_payload( + lst_hub: &str, + mint_to: &str, + min_mint_amount: Uint128, + funds_denom: &str, + funds_amount: u32, +) -> String { + let wasm_exec: CosmosMsg = CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: lst_hub.to_string(), + msg: to_json_binary(&LstExecuteMsg::Bond { + mint_to_address: Addr::unchecked(mint_to), + min_mint_amount, + }) + .unwrap(), + funds: vec![CwCoin { + denom: funds_denom.to_string(), + amount: funds_amount.into(), + }], + }); + + voyager_sdk::serde_json::to_string(&vec![wasm_exec]).expect("vec cosmosmsg json") +} + +#[tokio::test] +async fn test_escher_lst_success() { + let t = init_ctx().await; + + let (evm_address, evm_provider) = t.ctx.dst.get_provider().await; + let (cosmos_address, cosmos_provider) = t.ctx.src.get_signer().await; + let cosmos_address_bytes = cosmos_address.to_string().into_bytes(); + + // ensure_channels_opened(ctx.channel_count).await; + // let available_channel = ctx.get_available_channel_count().await; + // assert!(available_channel > 0); + // let pair = ctx.get_channel().await.expect("channel available"); + + let dst_channel_id = 1; + let src_channel_id = 1; + + let vault_on_union = "union1skg5244hpkad603zz77kdekzw6ffgpfrde3ldk8rpdz06n62k4hqct0w4j"; + + let u_on_eth = hex_literal::hex!("0c8C6f58156D10d18193A8fFdD853e1b9F8D8836"); + + let metadata = SolverMetadata { + solverAddress: u_on_eth.to_vec().into(), + metadata: Default::default(), + } + .abi_encode_params(); + + let instruction_cosmos = Instruction { + version: INSTR_VERSION_2, + opcode: OP_TOKEN_ORDER, + operand: TokenOrderV2 { + sender: cosmos_address_bytes.clone().into(), + receiver: evm_address.to_vec().into(), + base_token: "muno".as_bytes().into(), + base_amount: "100000".parse().unwrap(), + kind: TOKEN_ORDER_KIND_SOLVE, + metadata: metadata.into(), + quote_token: u_on_eth.to_vec().into(), + quote_amount: "100000".parse().unwrap(), + } + .abi_encode_params() + .into(), + }; + + let (_, zkgm_deployer_provider) = t.ctx.dst.get_provider_privileged().await; + println!("registering u counterpart"); + t.ctx + .dst + .u_register_fungible_counterpart( + H160::from(u_on_eth), + zkgm_deployer_provider.clone(), + alloy::primitives::U256::ZERO, + dst_channel_id, + b"muno".to_vec().into(), + evm::u::U::FungibleCounterparty { + beneficiary: vault_on_union.as_bytes().to_vec().into(), + }, + ) + .await + .unwrap(); + println!("u counterpart is registered"); + + let mut salt_bytes = [0u8; 32]; + rand::rng().fill_bytes(&mut salt_bytes); + + let cw_msg = ucs03_zkgm::msg::ExecuteMsg::Send { + channel_id: src_channel_id.try_into().unwrap(), + timeout_height: 0u64.into(), + timeout_timestamp: voyager_sdk::primitives::Timestamp::from_secs(u32::MAX.into()), + salt: salt_bytes.into(), + instruction: instruction_cosmos.abi_encode_params().into(), + }; + let bin_msg: Vec = Encode::::encode(&cw_msg); + + let funds = vec![Coin { + denom: "muno".into(), + amount: "100000".into(), + }]; + + let ack_packet_data = t + .ctx + .send_and_recv_and_ack_with_retry::( + &t.ctx.src, + contract, + (bin_msg, funds), + &t.ctx.dst, + 3, + Duration::from_secs(20), + Duration::from_secs(720), + cosmos_provider, + ) + .await; + + assert!( + ack_packet_data.is_ok(), + "Failed to send and ack packet: {:?}", + ack_packet_data.err() + ); + + let new_u_balance = t + .ctx + .dst + .zkgmerc20_balance_of( + H160::from(u_on_eth), + evm_address.into(), + evm_provider.clone(), + ) + .await + .unwrap(); + + let new_vault_balance = t + .ctx + .src + .native_balance(Bech32::from_str(vault_on_union).unwrap(), "muno") + .await + .unwrap(); + + // both balances are updated + assert!(new_u_balance > U256::ZERO); + assert!(new_vault_balance > 0); + + println!("new_u_balance: {}", new_u_balance); + + let lst_hub = "union1fdg764zzxwvwyqkx3fuj0236l9ddh5xmutgvj2mv9cduffy82z9sp62ygc"; + // let lst = "union1jansh23v7teaznyljq6ss4vx6eym8yrz0dsjchap4u7j3etx94vqhmcwn5"; + + let addr: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); + let canon = cosmwasm_std::CanonicalAddr::from(addr.data().as_ref()); + + let zkgm_proxy_canon = instantiate2_address( + // Checksum of the base contract + &hex_literal::hex!("ec827349ed4c1fec5a9c3462ff7c979d4c40e7aa43b16ed34469d04ff835f2a1"), + &canon, + proxy_account_salt_for_tests( + alloy::primitives::U256::ZERO, + dst_channel_id, + evm_address.as_slice(), + ) + .get() + .as_slice(), + ) + .unwrap(); + + let hrp = Bech32::>::from_str(UNION_ZKGM_ADDRESS) + .unwrap() + .hrp() + .to_string(); + + // 3. Build a Bech32 address with same HRP + let zkgm_proxy_calculated = Bech32::>::new( + hrp, + FixedBytes::<32>::try_from(zkgm_proxy_canon.as_slice()).unwrap(), + ); + println!("ZKGM Proxy: {}", zkgm_proxy_calculated); + + // let zkgm_proxy = zkgm_proxy_calculated.to_string().as_str(); + + // let bond_message: Bytes = json!({ + // "bond": { + // "mint_to_address": "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", + // "min_mint_amount": "3" + // } + // }) + // .to_string() + // .as_bytes() + // .into(); + + // let zkgm_message = json!({ + // "contract": lst_hub, + // "msg": bond_message.to_string(), + // "funds": [{ "denom": "muno", "amount": "3" }], + // "call_action": "call_proxy" + // }) + // .to_string(); + + let zkgm_msg_json = make_zkgm_call_payload( + lst_hub, + "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", + 150u128.into(), + "muno", + 150, + ); + + let proxy_balance = t + .ctx + .src + .native_balance(zkgm_proxy_calculated.clone(), "muno") + .await + .unwrap(); + + println!("Proxy balance before: {}", proxy_balance); + + let addr_str = zkgm_proxy_calculated.to_string(); + let receiver = addr_str.into_bytes().into(); + + let instruction_from_evm_to_union = InstructionEvm { + version: INSTR_VERSION_0, + opcode: OP_BATCH, + operand: Batch { + instructions: vec![ + Instruction { + version: INSTR_VERSION_2, + opcode: OP_TOKEN_ORDER, + operand: TokenOrderV2 { + sender: evm_address.to_vec().into(), + receiver, + base_token: u_on_eth.to_vec().into(), + base_amount: "150".parse().unwrap(), + kind: TOKEN_ORDER_KIND_SOLVE, + metadata: SolverMetadata { + solverAddress: vault_on_union.as_bytes().into(), + metadata: Default::default(), + } + .abi_encode_params() + .into(), + quote_token: "muno".as_bytes().into(), + quote_amount: "150".parse().unwrap(), + } + .abi_encode_params() + .into(), + }, + Instruction { + version: INSTR_VERSION_0, + opcode: OP_CALL, + operand: Call { + sender: evm_address.to_vec().into(), + eureka: false, + contract_address: zkgm_proxy_calculated + .to_string() + .as_bytes() + .to_vec() + .into(), + contract_calldata: zkgm_msg_json.as_bytes().to_vec().into(), + } + .abi_encode_params() + .into(), + }, + ], + } + .abi_encode_params() + .into(), + }; + + let approve_tx_hash = t + .ctx + .dst + .zkgmerc20_approve( + u_on_eth.into(), + ETH_ADDRESS_ZKGM.into(), + U256::from(100000000000u64), + evm_provider.clone(), + ) + .await; + + assert!( + approve_tx_hash.is_ok(), + "Failed to send approve transaction: {:?}, from_account: {:?}", + approve_tx_hash.err(), + evm_address + ); + + let ucs03_zkgm = UCS03Zkgm::new(ETH_ADDRESS_ZKGM.into(), evm_provider.clone()); + + let call = ucs03_zkgm + .send( + dst_channel_id, + 0u64, + 4294967295000000000u64, + salt_bytes.into(), + instruction_from_evm_to_union.clone(), + ) + .clear_decoder() + .with_cloned_provider(); + + let acked_packet = t + .ctx + .send_and_recv_and_ack_with_retry::( + &t.ctx.dst, + ETH_ADDRESS_ZKGM.into(), + call, + &t.ctx.src, + 3, + Duration::from_secs(20), + Duration::from_secs(720), + &evm_provider, + ) + .await; + + let acked_packet = acked_packet.unwrap(); + assert!( + acked_packet.tag == 1, + "Packet is not acked successfully, but it should be. Tag: {:?}", + acked_packet.tag + ); + + let proxy_balance = t + .ctx + .src + .native_balance(zkgm_proxy_calculated, "muno") + .await + .unwrap(); + + println!("Proxy balance before: {}", proxy_balance); +} + +// #[tokio::test] +// async fn test_escher_lst_unhappy_less_money_than_required() { +// let t = init_ctx().await; + +// let (evm_address, evm_provider) = t.ctx.dst.get_provider().await; +// let (cosmos_address, _) = t.ctx.src.get_signer().await; + +// // ensure_channels_opened(t.ctx.channel_count).await; +// // let available_channel = t.ctx.get_available_channel_count().await; +// // assert!(available_channel > 0); +// // let pair = t.ctx.get_channel().await.expect("channel available"); + +// let dst_channel_id = 1; +// let src_channel_id = 1; + +// let vault_on_union = "union1skg5244hpkad603zz77kdekzw6ffgpfrde3ldk8rpdz06n62k4hqct0w4j"; + +// let u_on_eth = hex_literal::hex!("0c8C6f58156D10d18193A8fFdD853e1b9F8D8836"); + +// eth_set_fungible_counterparty( +// &t.ctx.dst, +// dst_channel_id, +// b"muno", +// t.union_address.escrow_vault.as_bytes(), +// ) +// .await +// .unwrap(); + +// eth_fund_u( +// &t, +// src_channel_id, +// cosmos_address.to_string(), +// evm_address.into(), +// 5_000, +// 10_000, +// ) +// .await +// .unwrap(); + +// let mut salt_bytes = [0u8; 32]; +// rand::rng().fill_bytes(&mut salt_bytes); + +// let new_u_balance = t +// .ctx +// .dst +// .zkgmerc20_balance_of( +// H160::from(u_on_eth), +// evm_address.into(), +// evm_provider.clone(), +// ) +// .await +// .unwrap(); + +// let new_vault_balance = t +// .ctx +// .src +// .native_balance(Bech32::from_str(vault_on_union).unwrap(), "muno") +// .await +// .unwrap(); + +// // both balances are updated +// assert!(new_u_balance > U256::ZERO); +// assert!(new_vault_balance > 0); + +// println!("new_u_balance: {}", new_u_balance); + +// let lst_hub = "union1fdg764zzxwvwyqkx3fuj0236l9ddh5xmutgvj2mv9cduffy82z9sp62ygc"; +// // let lst = "union1jansh23v7teaznyljq6ss4vx6eym8yrz0dsjchap4u7j3etx94vqhmcwn5"; + +// let addr: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); +// let canon = cosmwasm_std::CanonicalAddr::from(addr.data().as_ref()); + +// let zkgm_proxy_canon = instantiate2_address( +// // Checksum of the base contract +// &hex_literal::hex!("ec827349ed4c1fec5a9c3462ff7c979d4c40e7aa43b16ed34469d04ff835f2a1"), +// &canon, +// proxy_account_salt_for_tests( +// alloy::primitives::U256::ZERO, +// dst_channel_id, +// evm_address.as_slice(), +// ) +// .get() +// .as_slice(), +// ) +// .unwrap(); + +// let hrp = Bech32::>::from_str(UNION_ZKGM_ADDRESS) +// .unwrap() +// .hrp() +// .to_string(); + +// // 3. Build a Bech32 address with same HRP +// let zkgm_proxy_calculated = Bech32::>::new( +// hrp, +// FixedBytes::<32>::try_from(zkgm_proxy_canon.as_slice()).unwrap(), +// ); +// println!("ZKGM Proxy: {}", zkgm_proxy_calculated); + +// // let zkgm_proxy = zkgm_proxy_calculated.to_string().as_str(); + +// // let bond_message: Bytes = json!({ +// // "bond": { +// // "mint_to_address": "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", +// // "min_mint_amount": "3" +// // } +// // }) +// // .to_string() +// // .as_bytes() +// // .into(); + +// // let zkgm_message = json!({ +// // "contract": lst_hub, +// // "msg": bond_message.to_string(), +// // "funds": [{ "denom": "muno", "amount": "3" }], +// // "call_action": "call_proxy" +// // }) +// // .to_string(); + +// let zkgm_msg_json = make_zkgm_call_payload( +// lst_hub, +// "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", +// 1000000u128.into(), +// "muno", +// 1000000, +// ); + +// let proxy_balance = t +// .ctx +// .src +// .native_balance(zkgm_proxy_calculated.clone(), "muno") +// .await +// .unwrap(); + +// println!("Proxy balance before: {}", proxy_balance); + +// let addr_str = zkgm_proxy_calculated.to_string(); +// let receiver = addr_str.into_bytes().into(); + +// let instruction_from_evm_to_union = InstructionEvm { +// version: INSTR_VERSION_0, +// opcode: OP_BATCH, +// operand: Batch { +// instructions: vec![ +// Instruction { +// version: INSTR_VERSION_2, +// opcode: OP_TOKEN_ORDER, +// operand: TokenOrderV2 { +// sender: evm_address.to_vec().into(), +// receiver, +// base_token: u_on_eth.to_vec().into(), +// // giving 150 but expecting 1000000 so it will fail. +// base_amount: "150".parse().unwrap(), +// kind: TOKEN_ORDER_KIND_SOLVE, +// metadata: SolverMetadata { +// solverAddress: vault_on_union.as_bytes().into(), +// metadata: Default::default(), +// } +// .abi_encode_params() +// .into(), +// quote_token: "muno".as_bytes().into(), +// // giving 150 but expecting 1000000 so it will fail. +// quote_amount: "150".parse().unwrap(), +// } +// .abi_encode_params() +// .into(), +// }, +// Instruction { +// version: INSTR_VERSION_0, +// opcode: OP_CALL, +// operand: Call { +// sender: evm_address.to_vec().into(), +// eureka: false, +// contract_address: zkgm_proxy_calculated +// .to_string() +// .as_bytes() +// .to_vec() +// .into(), +// contract_calldata: zkgm_msg_json.as_bytes().to_vec().into(), +// } +// .abi_encode_params() +// .into(), +// }, +// ], +// } +// .abi_encode_params() +// .into(), +// }; + +// let approve_tx_hash = t +// .ctx +// .dst +// .zkgmerc20_approve( +// u_on_eth.into(), +// ETH_ADDRESS_ZKGM.into(), +// U256::from(100000000000u64), +// evm_provider.clone(), +// ) +// .await; + +// assert!( +// approve_tx_hash.is_ok(), +// "Failed to send approve transaction: {:?}, from_account: {:?}", +// approve_tx_hash.err(), +// evm_address +// ); + +// let ucs03_zkgm = UCS03Zkgm::new(ETH_ADDRESS_ZKGM.into(), evm_provider.clone()); + +// let call = ucs03_zkgm +// .send( +// dst_channel_id, +// 0u64, +// 4294967295000000000u64, +// salt_bytes.into(), +// instruction_from_evm_to_union.clone(), +// ) +// .clear_decoder() +// .with_cloned_provider(); + +// let acked_packet = t +// .ctx +// .send_and_recv_and_ack_with_retry::( +// &t.ctx.dst, +// ETH_ADDRESS_ZKGM.into(), +// call, +// &t.ctx.src, +// 3, +// Duration::from_secs(20), +// Duration::from_secs(720), +// &evm_provider, +// ) +// .await; + +// let acked_packet = acked_packet.unwrap(); +// assert!( +// acked_packet.tag == 0, +// "Packet is acked successfully, but it should not be. Tag: {:?}", +// acked_packet.tag +// ); + +// let proxy_balance = t +// .ctx +// .src +// .native_balance(zkgm_proxy_calculated, "muno") +// .await +// .unwrap(); + +// println!("Proxy balance before: {}", proxy_balance); +// } + +// #[tokio::test] +// async fn test_escher_lst_unhappy_wrong_denom() { +// let t = init_ctx().await; + +// let (evm_address, evm_provider) = t.ctx.dst.get_provider().await; +// let (cosmos_address, cosmos_provider) = t.ctx.src.get_signer().await; +// let cosmos_address_bytes = cosmos_address.to_string().into_bytes(); + +// // ensure_channels_opened(t.ctx.channel_count).await; +// // let available_channel = t.ctx.get_available_channel_count().await; +// // assert!(available_channel > 0); +// // let pair = t.ctx.get_channel().await.expect("channel available"); + +// let dst_channel_id = 1; +// let src_channel_id = 1; + +// let vault_on_union = "union1skg5244hpkad603zz77kdekzw6ffgpfrde3ldk8rpdz06n62k4hqct0w4j"; + +// let u_on_eth = hex_literal::hex!("0c8C6f58156D10d18193A8fFdD853e1b9F8D8836"); + +// let metadata = SolverMetadata { +// solverAddress: u_on_eth.to_vec().into(), +// metadata: Default::default(), +// } +// .abi_encode_params(); + +// let instruction_cosmos = Instruction { +// version: INSTR_VERSION_2, +// opcode: OP_TOKEN_ORDER, +// operand: TokenOrderV2 { +// sender: cosmos_address_bytes.clone().into(), +// receiver: evm_address.to_vec().into(), +// base_token: "muno".as_bytes().into(), +// base_amount: "100000".parse().unwrap(), +// kind: TOKEN_ORDER_KIND_SOLVE, +// metadata: metadata.into(), +// quote_token: u_on_eth.to_vec().into(), +// quote_amount: "100000".parse().unwrap(), +// } +// .abi_encode_params() +// .into(), +// }; + +// let (_, zkgm_deployer_provider) = t.ctx.dst.get_provider_privileged().await; +// println!("registering u counterpart"); +// t.ctx +// .dst +// .u_register_fungible_counterpart( +// H160::from(u_on_eth), +// zkgm_deployer_provider.clone(), +// alloy::primitives::U256::ZERO, +// dst_channel_id, +// b"muno".to_vec().into(), +// evm::u::U::FungibleCounterparty { +// beneficiary: vault_on_union.as_bytes().to_vec().into(), +// }, +// ) +// .await +// .unwrap(); +// println!("u counterpart is registered"); + +// let mut salt_bytes = [0u8; 32]; +// rand::rng().fill_bytes(&mut salt_bytes); + +// let cw_msg = ucs03_zkgm::msg::ExecuteMsg::Send { +// channel_id: src_channel_id.try_into().unwrap(), +// timeout_height: 0u64.into(), +// timeout_timestamp: voyager_sdk::primitives::Timestamp::from_secs(u32::MAX.into()), +// salt: salt_bytes.into(), +// instruction: instruction_cosmos.abi_encode_params().into(), +// }; +// let bin_msg: Vec = Encode::::encode(&cw_msg); + +// let funds = vec![Coin { +// denom: "muno".into(), +// amount: "100000".into(), +// }]; + +// let contract: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); + +// let ack_packet_data = t +// .ctx +// .send_and_recv_and_ack_with_retry::( +// &t.ctx.src, +// contract, +// (bin_msg, funds), +// &t.ctx.dst, +// 3, +// Duration::from_secs(20), +// Duration::from_secs(720), +// cosmos_provider, +// ) +// .await; + +// assert!( +// ack_packet_data.is_ok(), +// "Failed to send and ack packet: {:?}", +// ack_packet_data.err() +// ); + +// let new_u_balance = t +// .ctx +// .dst +// .zkgmerc20_balance_of( +// H160::from(u_on_eth), +// evm_address.into(), +// evm_provider.clone(), +// ) +// .await +// .unwrap(); + +// let new_vault_balance = t +// .ctx +// .src +// .native_balance(Bech32::from_str(vault_on_union).unwrap(), "muno") +// .await +// .unwrap(); + +// // both balances are updated +// assert!(new_u_balance > U256::ZERO); +// assert!(new_vault_balance > 0); + +// println!("new_u_balance: {}", new_u_balance); + +// let lst_hub = "union1fdg764zzxwvwyqkx3fuj0236l9ddh5xmutgvj2mv9cduffy82z9sp62ygc"; +// // let lst = "union1jansh23v7teaznyljq6ss4vx6eym8yrz0dsjchap4u7j3etx94vqhmcwn5"; + +// let addr: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); +// let canon = cosmwasm_std::CanonicalAddr::from(addr.data().as_ref()); + +// let zkgm_proxy_canon = instantiate2_address( +// // Checksum of the base contract +// &hex_literal::hex!("ec827349ed4c1fec5a9c3462ff7c979d4c40e7aa43b16ed34469d04ff835f2a1"), +// &canon, +// proxy_account_salt_for_tests( +// alloy::primitives::U256::ZERO, +// dst_channel_id, +// evm_address.as_slice(), +// ) +// .get() +// .as_slice(), +// ) +// .unwrap(); + +// let hrp = Bech32::>::from_str(UNION_ZKGM_ADDRESS) +// .unwrap() +// .hrp() +// .to_string(); + +// // 3. Build a Bech32 address with same HRP +// let zkgm_proxy_calculated = Bech32::>::new( +// hrp, +// FixedBytes::<32>::try_from(zkgm_proxy_canon.as_slice()).unwrap(), +// ); +// println!("ZKGM Proxy: {}", zkgm_proxy_calculated); + +// // let zkgm_proxy = zkgm_proxy_calculated.to_string().as_str(); + +// // let bond_message: Bytes = json!({ +// // "bond": { +// // "mint_to_address": "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", +// // "min_mint_amount": "3" +// // } +// // }) +// // .to_string() +// // .as_bytes() +// // .into(); + +// // let zkgm_message = json!({ +// // "contract": lst_hub, +// // "msg": bond_message.to_string(), +// // "funds": [{ "denom": "muno", "amount": "3" }], +// // "call_action": "call_proxy" +// // }) +// // .to_string(); + +// let zkgm_msg_json = make_zkgm_call_payload( +// lst_hub, +// "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", +// 10u128.into(), +// "muan", // wrong denom to make it fail +// 10, +// ); + +// let proxy_balance = t +// .ctx +// .src +// .native_balance(zkgm_proxy_calculated.clone(), "muno") +// .await +// .unwrap(); + +// println!("Proxy balance before: {}", proxy_balance); + +// let addr_str = zkgm_proxy_calculated.to_string(); +// let receiver = addr_str.into_bytes().into(); + +// let instruction_from_evm_to_union = InstructionEvm { +// version: INSTR_VERSION_0, +// opcode: OP_BATCH, +// operand: Batch { +// instructions: vec![ +// Instruction { +// version: INSTR_VERSION_2, +// opcode: OP_TOKEN_ORDER, +// operand: TokenOrderV2 { +// sender: evm_address.to_vec().into(), +// receiver, +// base_token: u_on_eth.to_vec().into(), +// base_amount: "150".parse().unwrap(), +// kind: TOKEN_ORDER_KIND_SOLVE, +// metadata: SolverMetadata { +// solverAddress: vault_on_union.as_bytes().into(), +// metadata: Default::default(), +// } +// .abi_encode_params() +// .into(), +// quote_token: "muno".as_bytes().into(), +// quote_amount: "150".parse().unwrap(), +// } +// .abi_encode_params() +// .into(), +// }, +// Instruction { +// version: INSTR_VERSION_0, +// opcode: OP_CALL, +// operand: Call { +// sender: evm_address.to_vec().into(), +// eureka: false, +// contract_address: zkgm_proxy_calculated +// .to_string() +// .as_bytes() +// .to_vec() +// .into(), +// contract_calldata: zkgm_msg_json.as_bytes().to_vec().into(), +// } +// .abi_encode_params() +// .into(), +// }, +// ], +// } +// .abi_encode_params() +// .into(), +// }; + +// let approve_tx_hash = t +// .ctx +// .dst +// .zkgmerc20_approve( +// u_on_eth.into(), +// ETH_ADDRESS_ZKGM.into(), +// U256::from(100000000000u64), +// evm_provider.clone(), +// ) +// .await; + +// assert!( +// approve_tx_hash.is_ok(), +// "Failed to send approve transaction: {:?}, from_account: {:?}", +// approve_tx_hash.err(), +// evm_address +// ); + +// let ucs03_zkgm = UCS03Zkgm::new(ETH_ADDRESS_ZKGM.into(), evm_provider.clone()); + +// let call = ucs03_zkgm +// .send( +// dst_channel_id, +// 0u64, +// 4294967295000000000u64, +// salt_bytes.into(), +// instruction_from_evm_to_union.clone(), +// ) +// .clear_decoder() +// .with_cloned_provider(); + +// let acked_packet = t +// .ctx +// .send_and_recv_and_ack_with_retry::( +// &t.ctx.dst, +// ETH_ADDRESS_ZKGM.into(), +// call, +// &t.ctx.src, +// 3, +// Duration::from_secs(20), +// Duration::from_secs(720), +// &evm_provider, +// ) +// .await; + +// let acked_packet = acked_packet.unwrap(); +// assert!( +// acked_packet.tag == 0, +// "Packet is acked successfully, but it should not be. Tag: {:?}", +// acked_packet.tag +// ); + +// let proxy_balance = t +// .ctx +// .src +// .native_balance(zkgm_proxy_calculated, "muno") +// .await +// .unwrap(); + +// println!("Proxy balance before: {}", proxy_balance); +// } + +// #[tokio::test] +// async fn test_escher_lst_unhappy_under_minimum_ls_amount() { +// let t = init_ctx().await; + +// let (evm_address, evm_provider) = t.ctx.dst.get_provider().await; +// let (cosmos_address, cosmos_provider) = t.ctx.src.get_signer().await; +// let cosmos_address_bytes = cosmos_address.to_string().into_bytes(); + +// // ensure_channels_opened(t.ctx.channel_count).await; +// // let available_channel = t.ctx.get_available_channel_count().await; +// // assert!(available_channel > 0); +// // let pair = ctx.get_channel().await.expect("channel available"); + +// let dst_channel_id = 1; +// let src_channel_id = 1; + +// let vault_on_union = "union1skg5244hpkad603zz77kdekzw6ffgpfrde3ldk8rpdz06n62k4hqct0w4j"; + +// let u_on_eth = hex_literal::hex!("0c8C6f58156D10d18193A8fFdD853e1b9F8D8836"); + +// let metadata = SolverMetadata { +// solverAddress: u_on_eth.to_vec().into(), +// metadata: Default::default(), +// } +// .abi_encode_params(); + +// let instruction_cosmos = Instruction { +// version: INSTR_VERSION_2, +// opcode: OP_TOKEN_ORDER, +// operand: TokenOrderV2 { +// sender: cosmos_address_bytes.clone().into(), +// receiver: evm_address.to_vec().into(), +// base_token: "muno".as_bytes().into(), +// base_amount: "100000".parse().unwrap(), +// kind: TOKEN_ORDER_KIND_SOLVE, +// metadata: metadata.into(), +// quote_token: u_on_eth.to_vec().into(), +// quote_amount: "100000".parse().unwrap(), +// } +// .abi_encode_params() +// .into(), +// }; + +// let (_, zkgm_deployer_provider) = t.ctx.dst.get_provider_privileged().await; +// println!("registering u counterpart"); +// t.ctx +// .dst +// .u_register_fungible_counterpart( +// H160::from(u_on_eth), +// zkgm_deployer_provider.clone(), +// alloy::primitives::U256::ZERO, +// dst_channel_id, +// b"muno".to_vec().into(), +// evm::u::U::FungibleCounterparty { +// beneficiary: vault_on_union.as_bytes().to_vec().into(), +// }, +// ) +// .await +// .unwrap(); +// println!("u counterpart is registered"); + +// let mut salt_bytes = [0u8; 32]; +// rand::rng().fill_bytes(&mut salt_bytes); + +// let cw_msg = ucs03_zkgm::msg::ExecuteMsg::Send { +// channel_id: src_channel_id.try_into().unwrap(), +// timeout_height: 0u64.into(), +// timeout_timestamp: voyager_sdk::primitives::Timestamp::from_secs(u32::MAX.into()), +// salt: salt_bytes.into(), +// instruction: instruction_cosmos.abi_encode_params().into(), +// }; +// let bin_msg: Vec = Encode::::encode(&cw_msg); + +// let funds = vec![Coin { +// denom: "muno".into(), +// amount: "100000".into(), +// }]; + +// let contract: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); + +// let ack_packet_data = t +// .ctx +// .send_and_recv_and_ack_with_retry::( +// &t.ctx.src, +// contract, +// (bin_msg, funds), +// &t.ctx.dst, +// 3, +// Duration::from_secs(20), +// Duration::from_secs(720), +// cosmos_provider, +// ) +// .await; + +// assert!( +// ack_packet_data.is_ok(), +// "Failed to send and ack packet: {:?}", +// ack_packet_data.err() +// ); + +// let new_u_balance = t +// .ctx +// .dst +// .zkgmerc20_balance_of( +// H160::from(u_on_eth), +// evm_address.into(), +// evm_provider.clone(), +// ) +// .await +// .unwrap(); + +// let new_vault_balance = t +// .ctx +// .src +// .native_balance(Bech32::from_str(vault_on_union).unwrap(), "muno") +// .await +// .unwrap(); + +// // both balances are updated +// assert!(new_u_balance > U256::ZERO); +// assert!(new_vault_balance > 0); + +// println!("new_u_balance: {}", new_u_balance); + +// let lst_hub = "union1fdg764zzxwvwyqkx3fuj0236l9ddh5xmutgvj2mv9cduffy82z9sp62ygc"; +// // let lst = "union1jansh23v7teaznyljq6ss4vx6eym8yrz0dsjchap4u7j3etx94vqhmcwn5"; + +// let addr: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); +// let canon = cosmwasm_std::CanonicalAddr::from(addr.data().as_ref()); + +// let zkgm_proxy_canon = instantiate2_address( +// // Checksum of the base contract +// &hex_literal::hex!("ec827349ed4c1fec5a9c3462ff7c979d4c40e7aa43b16ed34469d04ff835f2a1"), +// &canon, +// proxy_account_salt_for_tests( +// alloy::primitives::U256::ZERO, +// dst_channel_id, +// evm_address.as_slice(), +// ) +// .get() +// .as_slice(), +// ) +// .unwrap(); + +// let hrp = Bech32::>::from_str(UNION_ZKGM_ADDRESS) +// .unwrap() +// .hrp() +// .to_string(); + +// // 3. Build a Bech32 address with same HRP +// let zkgm_proxy_calculated = Bech32::>::new( +// hrp, +// FixedBytes::<32>::try_from(zkgm_proxy_canon.as_slice()).unwrap(), +// ); +// println!("ZKGM Proxy: {}", zkgm_proxy_calculated); + +// // let zkgm_proxy = zkgm_proxy_calculated.to_string().as_str(); + +// // let bond_message: Bytes = json!({ +// // "bond": { +// // "mint_to_address": "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", +// // "min_mint_amount": "3" +// // } +// // }) +// // .to_string() +// // .as_bytes() +// // .into(); + +// // let zkgm_message = json!({ +// // "contract": lst_hub, +// // "msg": bond_message.to_string(), +// // "funds": [{ "denom": "muno", "amount": "3" }], +// // "call_action": "call_proxy" +// // }) +// // .to_string(); + +// let zkgm_msg_json = make_zkgm_call_payload( +// lst_hub, +// "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", +// 0u128.into(), +// "muno", +// 0, // under minimum amount to make it fail +// ); + +// let proxy_balance = t +// .ctx +// .src +// .native_balance(zkgm_proxy_calculated.clone(), "muno") +// .await +// .unwrap(); + +// println!("Proxy balance before: {}", proxy_balance); + +// let addr_str = zkgm_proxy_calculated.to_string(); +// let receiver = addr_str.into_bytes().into(); + +// let instruction_from_evm_to_union = InstructionEvm { +// version: INSTR_VERSION_0, +// opcode: OP_BATCH, +// operand: Batch { +// instructions: vec![ +// Instruction { +// version: INSTR_VERSION_2, +// opcode: OP_TOKEN_ORDER, +// operand: TokenOrderV2 { +// sender: evm_address.to_vec().into(), +// receiver, +// base_token: u_on_eth.to_vec().into(), +// base_amount: "150".parse().unwrap(), +// kind: TOKEN_ORDER_KIND_SOLVE, +// metadata: SolverMetadata { +// solverAddress: vault_on_union.as_bytes().into(), +// metadata: Default::default(), +// } +// .abi_encode_params() +// .into(), +// quote_token: "muno".as_bytes().into(), +// quote_amount: "150".parse().unwrap(), +// } +// .abi_encode_params() +// .into(), +// }, +// Instruction { +// version: INSTR_VERSION_0, +// opcode: OP_CALL, +// operand: Call { +// sender: evm_address.to_vec().into(), +// eureka: false, +// contract_address: zkgm_proxy_calculated +// .to_string() +// .as_bytes() +// .to_vec() +// .into(), +// contract_calldata: zkgm_msg_json.as_bytes().to_vec().into(), +// } +// .abi_encode_params() +// .into(), +// }, +// ], +// } +// .abi_encode_params() +// .into(), +// }; + +// let approve_tx_hash = t +// .ctx +// .dst +// .zkgmerc20_approve( +// u_on_eth.into(), +// ETH_ADDRESS_ZKGM.into(), +// U256::from(100000000000u64), +// evm_provider.clone(), +// ) +// .await; + +// assert!( +// approve_tx_hash.is_ok(), +// "Failed to send approve transaction: {:?}, from_account: {:?}", +// approve_tx_hash.err(), +// evm_address +// ); + +// let ucs03_zkgm = UCS03Zkgm::new(ETH_ADDRESS_ZKGM.into(), evm_provider.clone()); + +// let call = ucs03_zkgm +// .send( +// dst_channel_id, +// 0u64, +// 4294967295000000000u64, +// salt_bytes.into(), +// instruction_from_evm_to_union.clone(), +// ) +// .clear_decoder() +// .with_cloned_provider(); + +// let acked_packet = t +// .ctx +// .send_and_recv_and_ack_with_retry::( +// &t.ctx.dst, +// ETH_ADDRESS_ZKGM.into(), +// call, +// &t.ctx.src, +// 3, +// Duration::from_secs(20), +// Duration::from_secs(720), +// &evm_provider, +// ) +// .await; + +// let acked_packet = acked_packet.unwrap(); +// assert!( +// acked_packet.tag == 0, +// "Packet is acked successfully, but it should not be. Tag: {:?}", +// acked_packet.tag +// ); + +// let proxy_balance = t +// .ctx +// .src +// .native_balance(zkgm_proxy_calculated, "muno") +// .await +// .unwrap(); + +// println!("Proxy balance before: {}", proxy_balance); +// } + +// #[tokio::test] +// async fn test_escher_lst_unhappy_no_funds() { +// let t = init_ctx().await; + +// let (evm_address, evm_provider) = t.ctx.dst.get_provider().await; +// let (cosmos_address, cosmos_provider) = t.ctx.src.get_signer().await; +// let cosmos_address_bytes = cosmos_address.to_string().into_bytes(); + +// // ensure_channels_opened(t.ctx.channel_count).await; +// // let available_channel = t.ctx.get_available_channel_count().await; +// // assert!(available_channel > 0); +// // let pair = t.ctx.get_channel().await.expect("channel available"); + +// let dst_channel_id = 1; +// let src_channel_id = 1; + +// let vault_on_union = "union1skg5244hpkad603zz77kdekzw6ffgpfrde3ldk8rpdz06n62k4hqct0w4j"; + +// let u_on_eth = hex_literal::hex!("0c8C6f58156D10d18193A8fFdD853e1b9F8D8836"); + +// let metadata = SolverMetadata { +// solverAddress: u_on_eth.to_vec().into(), +// metadata: Default::default(), +// } +// .abi_encode_params(); + +// let instruction_cosmos = Instruction { +// version: INSTR_VERSION_2, +// opcode: OP_TOKEN_ORDER, +// operand: TokenOrderV2 { +// sender: cosmos_address_bytes.clone().into(), +// receiver: evm_address.to_vec().into(), +// base_token: "muno".as_bytes().into(), +// base_amount: "100000".parse().unwrap(), +// kind: TOKEN_ORDER_KIND_SOLVE, +// metadata: metadata.into(), +// quote_token: u_on_eth.to_vec().into(), +// quote_amount: "100000".parse().unwrap(), +// } +// .abi_encode_params() +// .into(), +// }; + +// let (_, zkgm_deployer_provider) = t.ctx.dst.get_provider_privileged().await; +// println!("registering u counterpart"); +// t.ctx +// .dst +// .u_register_fungible_counterpart( +// H160::from(u_on_eth), +// zkgm_deployer_provider.clone(), +// alloy::primitives::U256::ZERO, +// dst_channel_id, +// b"muno".to_vec().into(), +// evm::u::U::FungibleCounterparty { +// beneficiary: vault_on_union.as_bytes().to_vec().into(), +// }, +// ) +// .await +// .unwrap(); +// println!("u counterpart is registered"); + +// let mut salt_bytes = [0u8; 32]; +// rand::rng().fill_bytes(&mut salt_bytes); + +// let cw_msg = ucs03_zkgm::msg::ExecuteMsg::Send { +// channel_id: src_channel_id.try_into().unwrap(), +// timeout_height: 0u64.into(), +// timeout_timestamp: voyager_sdk::primitives::Timestamp::from_secs(u32::MAX.into()), +// salt: salt_bytes.into(), +// instruction: instruction_cosmos.abi_encode_params().into(), +// }; +// let bin_msg: Vec = Encode::::encode(&cw_msg); + +// let funds = vec![Coin { +// denom: "muno".into(), +// amount: "100000".into(), +// }]; + +// let contract: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); + +// let ack_packet_data = t +// .ctx +// .send_and_recv_and_ack_with_retry::( +// &t.ctx.src, +// contract, +// (bin_msg, funds), +// &t.ctx.dst, +// 3, +// Duration::from_secs(20), +// Duration::from_secs(720), +// cosmos_provider, +// ) +// .await; + +// assert!( +// ack_packet_data.is_ok(), +// "Failed to send and ack packet: {:?}", +// ack_packet_data.err() +// ); + +// let new_u_balance = t +// .ctx +// .dst +// .zkgmerc20_balance_of( +// H160::from(u_on_eth), +// evm_address.into(), +// evm_provider.clone(), +// ) +// .await +// .unwrap(); + +// let new_vault_balance = t +// .ctx +// .src +// .native_balance(Bech32::from_str(vault_on_union).unwrap(), "muno") +// .await +// .unwrap(); + +// // both balances are updated +// assert!(new_u_balance > U256::ZERO); +// assert!(new_vault_balance > 0); + +// println!("new_u_balance: {}", new_u_balance); + +// let lst_hub = "union1fdg764zzxwvwyqkx3fuj0236l9ddh5xmutgvj2mv9cduffy82z9sp62ygc"; +// // let lst = "union1jansh23v7teaznyljq6ss4vx6eym8yrz0dsjchap4u7j3etx94vqhmcwn5"; + +// let addr: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); +// let canon = cosmwasm_std::CanonicalAddr::from(addr.data().as_ref()); + +// let zkgm_proxy_canon = instantiate2_address( +// // Checksum of the base contract +// &hex_literal::hex!("ec827349ed4c1fec5a9c3462ff7c979d4c40e7aa43b16ed34469d04ff835f2a1"), +// &canon, +// proxy_account_salt_for_tests( +// alloy::primitives::U256::ZERO, +// dst_channel_id, +// evm_address.as_slice(), +// ) +// .get() +// .as_slice(), +// ) +// .unwrap(); + +// let hrp = Bech32::>::from_str(UNION_ZKGM_ADDRESS) +// .unwrap() +// .hrp() +// .to_string(); + +// // 3. Build a Bech32 address with same HRP +// let zkgm_proxy_calculated = Bech32::>::new( +// hrp, +// FixedBytes::<32>::try_from(zkgm_proxy_canon.as_slice()).unwrap(), +// ); +// println!("ZKGM Proxy: {}", zkgm_proxy_calculated); + +// // let zkgm_proxy = zkgm_proxy_calculated.to_string().as_str(); + +// // let bond_message: Bytes = json!({ +// // "bond": { +// // "mint_to_address": "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", +// // "min_mint_amount": "3" +// // } +// // }) +// // .to_string() +// // .as_bytes() +// // .into(); + +// // let zkgm_message = json!({ +// // "contract": lst_hub, +// // "msg": bond_message.to_string(), +// // "funds": [{ "denom": "muno", "amount": "3" }], +// // "call_action": "call_proxy" +// // }) +// // .to_string(); + +// let bond = LstExecuteMsg::Bond { +// mint_to_address: Addr::unchecked("union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2"), +// min_mint_amount: 0u128.into(), +// }; + +// let wasm_exec: CosmosMsg = CosmosMsg::Wasm(WasmMsg::Execute { +// contract_addr: lst_hub.to_string(), +// msg: to_json_binary(&bond).unwrap(), +// funds: vec![], // no funds array so it will fail. +// }); + +// let zkgm_msg_json = +// voyager_sdk::serde_json::to_string(&vec![wasm_exec]).expect("vec cosmosmsg json"); + +// let proxy_balance = t +// .ctx +// .src +// .native_balance(zkgm_proxy_calculated.clone(), "muno") +// .await +// .unwrap(); + +// println!("Proxy balance before: {}", proxy_balance); + +// let addr_str = zkgm_proxy_calculated.to_string(); +// let receiver = addr_str.into_bytes().into(); + +// let instruction_from_evm_to_union = InstructionEvm { +// version: INSTR_VERSION_0, +// opcode: OP_BATCH, +// operand: Batch { +// instructions: vec![ +// Instruction { +// version: INSTR_VERSION_2, +// opcode: OP_TOKEN_ORDER, +// operand: TokenOrderV2 { +// sender: evm_address.to_vec().into(), +// receiver, +// base_token: u_on_eth.to_vec().into(), +// base_amount: "150".parse().unwrap(), //giving 150 but expecting 1000000 so it will fail. +// kind: TOKEN_ORDER_KIND_SOLVE, +// metadata: SolverMetadata { +// solverAddress: vault_on_union.as_bytes().into(), +// metadata: Default::default(), +// } +// .abi_encode_params() +// .into(), +// quote_token: "muno".as_bytes().into(), +// quote_amount: "150".parse().unwrap(), //giving 150 but expecting 1000000 so it will fail. +// } +// .abi_encode_params() +// .into(), +// }, +// Instruction { +// version: INSTR_VERSION_0, +// opcode: OP_CALL, +// operand: Call { +// sender: evm_address.to_vec().into(), +// eureka: false, +// contract_address: zkgm_proxy_calculated +// .to_string() +// .as_bytes() +// .to_vec() +// .into(), +// contract_calldata: zkgm_msg_json.as_bytes().to_vec().into(), +// } +// .abi_encode_params() +// .into(), +// }, +// ], +// } +// .abi_encode_params() +// .into(), +// }; + +// let approve_tx_hash = t +// .ctx +// .dst +// .zkgmerc20_approve( +// u_on_eth.into(), +// ETH_ADDRESS_ZKGM.into(), +// U256::from(100000000000u64), +// evm_provider.clone(), +// ) +// .await; + +// assert!( +// approve_tx_hash.is_ok(), +// "Failed to send approve transaction: {:?}, from_account: {:?}", +// approve_tx_hash.err(), +// evm_address +// ); + +// let ucs03_zkgm = UCS03Zkgm::new(ETH_ADDRESS_ZKGM.into(), evm_provider.clone()); + +// let call = ucs03_zkgm +// .send( +// dst_channel_id, +// 0u64, +// 4294967295000000000u64, +// salt_bytes.into(), +// instruction_from_evm_to_union.clone(), +// ) +// .clear_decoder() +// .with_cloned_provider(); + +// let acked_packet = t +// .ctx +// .send_and_recv_and_ack_with_retry::( +// &t.ctx.dst, +// ETH_ADDRESS_ZKGM.into(), +// call, +// &t.ctx.src, +// 3, +// Duration::from_secs(20), +// Duration::from_secs(720), +// &evm_provider, +// ) +// .await; + +// let acked_packet = acked_packet.unwrap(); +// assert!( +// acked_packet.tag == 0, +// "Packet is acked successfully, but it should not be. Tag: {:?}", +// acked_packet.tag +// ); + +// let proxy_balance = t +// .ctx +// .src +// .native_balance(zkgm_proxy_calculated, "muno") +// .await +// .unwrap(); + +// println!("Proxy balance before: {}", proxy_balance); +// } + +fn proxy_account_salt_for_tests( + path: alloy::primitives::U256, + channel_id: u32, + sender: &[u8], +) -> unionlabs::primitives::H256 { + use alloy_sol_types::SolValue; + use unionlabs::ethereum::keccak256; + + let encoded = (path, channel_id, sender.to_vec()).abi_encode_params(); + keccak256(encoded) +} diff --git a/tools/union-test/tests/lst/config.json b/tools/union-test/tests/lst/config.json new file mode 100644 index 0000000000..1ff41c4dda --- /dev/null +++ b/tools/union-test/tests/lst/config.json @@ -0,0 +1,114 @@ +{ + "union": { + "chain_id": "union-devnet-1", + "ibc_host_contract_address": "union1nk3nes4ef6vcjan5tz6stf9g8p08q2kgqysx6q5exxh89zakp0msq5z79t", + "keyring": { + "name": "alice", + "keys": [ + { + "type": "raw", + "name": "bob", + "key": "0xf562d20f0a4ffd8814d262f7023f33971cbcd14a96d60027585777f174b9cdeb" + }, + { + "type": "raw", + "name": "dave", + "key": "0xedc165ff1ebc27044ddc284c9cf5da656dcbff324f6ecbb9d3203cf5f4738d6d" + }, + { + "type": "raw", + "name": "charlie", + "key": "0xa1f713e0f36404586085a599a45ca8233e23709e23cd54bc8d5452ef8f7bc1e6" + } + ] + }, + "privileged_acc_keyring": { + "name": "privileged_acc", + "keys": [ + { + "type": "raw", + "name": "privileged_acc", + "key": "0xaa820fa947beb242032a41b6dc9a8b9c37d8f5fbcda0966b1ec80335b10a7d6f" + } + ] + }, + "rpc_url": "http://0.0.0.0:26657", + "gas_config": { + "type": "feemarket", + "config": { + "max_gas": 10000000, + "gas_multiplier": 1.4, + "denom": null + } + }, + "fee_recipient": null + }, + "evm": { + "chain_id": "32382", + "ibc_handler_address": "0xed2af2ad7fe0d92011b26a2e5d1b4dc7d12a47c5", + "multicall_address": "0x84c4c2ee43ccfd523af9f78740256e0f60d38068", + "rpc_url": "http://0.0.0.0:8545", + "ws_url": "ws://0.0.0.0:8546", + "keyring": { + "name": "evm-keyring", + "keys": [ + { + "type": "raw", + "name": "dev-key0.prv", + "key": "0x4e9444a6efd6d42725a250b650a781da2737ea308c839eaccb0f7f3dbd2fea77" + }, + { + "type": "raw", + "name": "dev-key1.prv", + "key": "0xd9c5dc47ed678fc3e63249953866d79e5cf48418e79d8eec1a985be7393ef3b9" + }, + { + "type": "raw", + "name": "dev-key2.prv", + "key": "0xeadf66c84a1c2768a14e883512724d6023a54d500bf91d910a7dace376a97d6b" + }, + { + "type": "raw", + "name": "dev-key3.prv", + "key": "0xd56f932b298ba86341037f3871141a707330316f6f9493641a2cd59ba4a53710" + }, + { + "type": "raw", + "name": "dev-key4.prv", + "key": "0x084494a1ff88a1319e493d32aa6e127ab0eaaaf74b8714edfd670a9ddc4a060d" + }, + { + "type": "raw", + "name": "dev-key5.prv", + "key": "0xf977996449841b13ce9bbb99873006e04590ddbe28d9cd449dd33505851e74ba" + }, + { + "type": "raw", + "name": "dev-key6.prv", + "key": "0x523776c0e15a5826c85f08e0dd20d70190b0001e87f6ff9f25854d10f24db63c" + }, + { + "type": "raw", + "name": "dev-key7.prv", + "key": "0xb7d500ecae3d26deaa9547557822c95208163e230cc04345bd223da99f5bd058" + } + ] + }, + "privileged_acc_keyring": { + "name": "zkgm-deployer", + "keys": [ + { + "type": "raw", + "name": "zkgm-deployer-key", + "key": "0x4e9444a6efd6d42725a250b650a781da2737ea308c839eaccb0f7f3dbd2fea77" + } + ] + }, + "max_gas_price": null, + "fixed_gas_price": null, + "gas_multiplier": 2.0 + }, + "needed_channel_count": 1, + "voyager_config_file_path": "./voyager", + "union_deployer_addr": "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2" +} diff --git a/tools/union-test/tests/lst/mod.rs b/tools/union-test/tests/lst/mod.rs new file mode 100644 index 0000000000..a9feb33fe0 --- /dev/null +++ b/tools/union-test/tests/lst/mod.rs @@ -0,0 +1,266 @@ +use std::{str::FromStr as _, sync::Arc, time::Duration}; + +use alloy_sol_types::SolValue as _; +use cosmwasm_std::Addr; +use hex_literal::hex; +use protos::cosmos::base::v1beta1::Coin as ProtoCoin; +use rand::RngCore as _; +use serde::Deserialize; +use tokio::sync::OnceCell; +use ucs03_zkgm::com::{ + Instruction, SolverMetadata, TokenOrderV2, INSTR_VERSION_2, OP_TOKEN_ORDER, + TOKEN_ORDER_KIND_SOLVE, +}; +use union_test::{ + cosmos::{self}, + cosmos_helpers::{ + calculate_cosmos_contract_address, SALT_ESCROW_VAULT, SALT_EU, SALT_LST_HUB, SALT_ZKGM, + }, + evm, TestContext, +}; +use unionlabs::{ + encoding::{EncodeAs, Json}, + primitives::{Bech32, H160}, +}; +use voyager_sdk::{anyhow, serde_json}; + +pub mod bond; + +pub static CTX: OnceCell> = OnceCell::const_new(); +pub static CHANNELS_OPENED: OnceCell<()> = OnceCell::const_new(); + +pub const ETH_ADDRESS_U: H160 = H160::new(hex!("0c8C6f58156D10d18193A8fFdD853e1b9F8D8836")); +pub const ETH_ADDRESS_ZKGM: H160 = H160::new(hex!("05FD55C1AbE31D3ED09A76216cA8F0372f4B2eC5")); + +pub struct UnionAddressBook { + pub zkgm: Addr, + pub lst_hub: Addr, + pub eu: Addr, + pub escrow_vault: Addr, +} + +pub struct LstContext { + union_address: UnionAddressBook, + ctx: TestContext, +} + +#[derive(Deserialize)] +pub struct Config { + evm: evm::Config, + union: cosmos::Config, + needed_channel_count: u32, + voyager_config_file_path: String, + union_deployer_addr: String, +} + +async fn init_ctx<'a>() -> Arc { + CTX.get_or_init(|| async { + let cfg: Config = serde_json::from_str(include_str!("./config.json")).unwrap(); + + let src = cosmos::Module::new(cfg.union).await.unwrap(); + let dst = evm::Module::new(cfg.evm).await.unwrap(); + + let ctx = TestContext::new( + src, + dst, + cfg.needed_channel_count as usize, + &cfg.voyager_config_file_path, + ) + .await + .unwrap(); + + Arc::new(LstContext { + union_address: UnionAddressBook { + zkgm: calculate_cosmos_contract_address(&cfg.union_deployer_addr, SALT_ZKGM) + .unwrap(), + lst_hub: calculate_cosmos_contract_address(&cfg.union_deployer_addr, SALT_LST_HUB) + .unwrap(), + eu: calculate_cosmos_contract_address(&cfg.union_deployer_addr, SALT_EU).unwrap(), + escrow_vault: calculate_cosmos_contract_address( + &cfg.union_deployer_addr, + SALT_ESCROW_VAULT, + ) + .unwrap(), + }, + ctx, + }) + }) + .await + .clone() +} + +pub async fn ensure_channels_opened(channel_count: usize) { + CHANNELS_OPENED + .get_or_init(|| async move { + let t = init_ctx().await; + + let (src_client, dst_client) = t + .ctx + .create_clients( + Duration::from_secs(60), + "ibc-cosmwasm", + "trusted/evm/mpt", + "ibc-solidity", + "cometbls", + ) + .await + .unwrap(); + + assert!(src_client.client_id > 0); + assert!(dst_client.client_id > 0); + + let conn = t + .ctx + .open_connection::( + &t.ctx.src, + src_client.client_id, + &t.ctx.dst, + dst_client.client_id, + Duration::from_secs(180), + ) + .await + .unwrap(); + assert!(conn.connection_id > 0); + assert!(conn.counterparty_connection_id > 0); + + let current_available_count = t.ctx.get_available_channel_count().await; + + let opened = t + .ctx + .open_channels( + true, + t.union_address.zkgm.as_bytes().into(), + ETH_ADDRESS_ZKGM.into_bytes(), + conn.counterparty_connection_id, + "ucs03-zkgm-0".into(), + channel_count, + Duration::from_secs(360 * channel_count as u64), + ) + .await + .unwrap(); + assert_eq!(opened, channel_count); + + let available_count_after_open = t.ctx.get_available_channel_count().await; + assert_eq!( + current_available_count + channel_count, + available_count_after_open + ); + let pair = t.ctx.get_channel().await.expect("channel available"); + let available_count_after_get = t.ctx.get_available_channel_count().await; + assert_eq!(available_count_after_open - 1, available_count_after_get); + t.ctx.release_channel(pair).await; + let available_count_after_release = t.ctx.get_available_channel_count().await; + assert_eq!(available_count_after_open, available_count_after_release); + }) + .await; +} + +pub async fn eth_set_fungible_counterparty( + module: &evm::Module, + channel_id: u32, + base_token: &[u8], + beneficiary: &[u8], +) -> anyhow::Result<()> { + tracing::info!("registering fungible counterparty"); + + let (_, priviledged_account) = module.get_provider_privileged().await; + module + .u_register_fungible_counterpart( + ETH_ADDRESS_U, + priviledged_account.clone(), + alloy::primitives::U256::ZERO, + channel_id, + base_token.to_vec().into(), + evm::u::U::FungibleCounterparty { + beneficiary: beneficiary.to_vec().into(), + }, + ) + .await + .unwrap(); + + Ok(()) +} + +pub async fn eth_fund_u( + t: &LstContext, + src_channel_id: u32, + sender: String, + receiver: H160, + min_amount: u64, + amount: u64, +) -> anyhow::Result<()> { + let (_, evm_provider) = t.ctx.dst.get_provider().await; + let (_, cosmos_provider) = t.ctx.src.get_signer().await; + + let u_balance = t + .ctx + .dst + .zkgmerc20_balance_of(ETH_ADDRESS_U, receiver, evm_provider.clone()) + .await + .unwrap(); + + if min_amount > amount { + return Err(anyhow::anyhow!("you seriously wanna fund your contract less than min amount, when min amount is greater?")); + } + + if u_balance > min_amount.into() { + Ok(()) + } else { + let metadata = SolverMetadata { + solverAddress: ETH_ADDRESS_U.into_bytes().into(), + metadata: Default::default(), + } + .abi_encode_params(); + + let instruction_cosmos = Instruction { + version: INSTR_VERSION_2, + opcode: OP_TOKEN_ORDER, + operand: TokenOrderV2 { + sender: sender.into_bytes().into(), + receiver: receiver.into_bytes().into(), + base_token: "muno".as_bytes().into(), + base_amount: "100000".parse().unwrap(), + kind: TOKEN_ORDER_KIND_SOLVE, + metadata: metadata.into(), + quote_token: ETH_ADDRESS_U.into_bytes().into(), + quote_amount: Into::::into(amount).into(), + } + .abi_encode_params() + .into(), + }; + + let mut salt_bytes = [0u8; 32]; + rand::rng().fill_bytes(&mut salt_bytes); + + let _ = t + .ctx + .send_and_recv_and_ack_with_retry::( + &t.ctx.src, + t.union_address.zkgm.clone(), + ( + ucs03_zkgm::msg::ExecuteMsg::Send { + channel_id: src_channel_id.try_into().unwrap(), + timeout_height: 0u64.into(), + timeout_timestamp: voyager_sdk::primitives::Timestamp::from_secs( + u32::MAX.into(), + ), + salt: salt_bytes.into(), + instruction: instruction_cosmos.abi_encode_params().into(), + } + .encode_as::(), + vec![ProtoCoin { + denom: "muno".into(), + amount: amount.to_string(), + }], + ), + &t.ctx.dst, + 3, + Duration::from_secs(20), + Duration::from_secs(720), + cosmos_provider, + ) + .await?; + + Ok(()) + } +} From e163e113cd1385910bb7bc91353d3dfc921c72d5 Mon Sep 17 00:00:00 2001 From: aeryz Date: Mon, 22 Sep 2025 11:29:52 +0300 Subject: [PATCH 13/33] chore: moar Signed-off-by: aeryz --- tools/union-test/src/cosmos.rs | 16 +- tools/union-test/src/cosmos_helpers.rs | 31 ++- tools/union-test/src/evm.rs | 20 +- tools/union-test/src/helpers.rs | 3 +- tools/union-test/src/lib.rs | 3 +- tools/union-test/src/zkgm_helper.rs | 26 +++ tools/union-test/tests/lst/bond.rs | 275 +++++-------------------- tools/union-test/tests/lst/mod.rs | 44 +++- 8 files changed, 166 insertions(+), 252 deletions(-) create mode 100644 tools/union-test/src/zkgm_helper.rs diff --git a/tools/union-test/src/cosmos.rs b/tools/union-test/src/cosmos.rs index 35c8a93fc3..7a6baa82c4 100644 --- a/tools/union-test/src/cosmos.rs +++ b/tools/union-test/src/cosmos.rs @@ -12,6 +12,7 @@ use cosmos_client::{ BroadcastTxCommitError, TxClient, }; use cosmos_sdk_event::CosmosSdkEvent; +use cosmwasm_std::Addr; use ibc_union_spec::{ChannelId, ClientId, ConnectionId, Timestamp}; use protos::{ cosmos::{ @@ -158,7 +159,7 @@ impl Module { }) } - pub async fn native_balance(&self, address: Bech32, token: &str) -> anyhow::Result { + pub async fn native_balance(&self, address: Addr, token: &str) -> anyhow::Result { let balance: u128 = self .rpc .client() @@ -438,12 +439,9 @@ impl Module { let ack_bytes: &[u8] = acknowledgement.as_ref(); // Grab the first 32 bytes — this is the uint256 in ABI encoding - let mut tag_be = [0u8; 32]; - tag_be.copy_from_slice(&ack_bytes[..32]); - let tag_u128 = u128::from_be_bytes(tag_be[16..].try_into().ok()?); return Some(helpers::PacketAck { packet_hash: *packet_hash, - tag: tag_u128, + tag: alloy::primitives::U256::from_le_slice(&ack_bytes[..32]), }); } None @@ -519,7 +517,7 @@ impl Module { pub async fn predict_wrapped_token( &self, - contract: Bech32, + contract: Addr, channel_id: ChannelId, token: Vec, ) -> anyhow::Result { @@ -614,7 +612,7 @@ impl Module { pub async fn send_transaction_with_retry( &self, - contract: Bech32, + contract: Addr, msg: (Vec, Vec), signer: &LocalSigner, ) -> Option> { @@ -650,7 +648,7 @@ impl Module { // TODO(aeryz): return the digest pub async fn send_transaction( &self, - contract: Bech32, + contract: Addr, msg: (Vec, Vec), signer: &LocalSigner, ) -> Option> { @@ -690,7 +688,7 @@ impl Module { pub async fn send_ibc_transaction( &self, - contract: Bech32, + contract: Addr, msg: (Vec, Vec), signer: &LocalSigner, ) -> anyhow::Result<(H256, u64)> { diff --git a/tools/union-test/src/cosmos_helpers.rs b/tools/union-test/src/cosmos_helpers.rs index bfbd85aef9..69a293bc37 100644 --- a/tools/union-test/src/cosmos_helpers.rs +++ b/tools/union-test/src/cosmos_helpers.rs @@ -1,8 +1,12 @@ use std::str::FromStr; -use cosmwasm_std::{instantiate2_address, Addr}; +use alloy_sol_types::SolValue as _; +use cosmwasm_std::{instantiate2_address, Addr, CanonicalAddr}; use hex_literal::hex; -use unionlabs::primitives::Bech32; +use unionlabs::{ + ethereum::keccak256, + primitives::{Bech32, FixedBytes}, +}; use voyager_sdk::anyhow; pub const COSMOS_BASE_CONTRACT_HASH: [u8; 32] = @@ -28,3 +32,26 @@ pub fn calculate_cosmos_contract_address(creator: &str, salt: &[u8]) -> anyhow:: Ok(Addr::unchecked(bech_addr.to_string())) } + +pub fn calculate_proxy_address( + zkgm_address: &Addr, + path: alloy::primitives::U256, + channel_id: u32, + sender: &[u8], +) -> Addr { + let addr = Bech32::>::from_str(zkgm_address.as_str()).unwrap(); + let canonical_addr = instantiate2_address( + &COSMOS_BASE_CONTRACT_HASH, + &CanonicalAddr::from(addr.data().as_ref()), + keccak256((path, channel_id, sender.to_vec()).abi_encode_params()).as_ref(), + ) + .unwrap(); + + Addr::unchecked( + Bech32::>::new( + addr.hrp().clone(), + canonical_addr.as_slice().try_into().unwrap(), + ) + .to_string(), + ) +} diff --git a/tools/union-test/src/evm.rs b/tools/union-test/src/evm.rs index f84e05a5d0..57a78f7b80 100644 --- a/tools/union-test/src/evm.rs +++ b/tools/union-test/src/evm.rs @@ -337,16 +337,9 @@ impl Module { { let ack_bytes: &[u8] = ev.acknowledgement.as_ref(); - // Grab the first 32 bytes — this is the uint256 in ABI encoding - let mut tag_be = [0u8; 32]; - tag_be.copy_from_slice(&ack_bytes[..32]); - - // If you want it as u128 (will fail if > u128::MAX) - let tag_u128 = u128::from_be_bytes(tag_be[16..].try_into().ok()?); - Some(helpers::PacketAck { packet_hash: ev.packet_hash.into(), - tag: tag_u128, + tag: alloy::primitives::U256::from_le_slice(&ack_bytes[..32]), }) } _ => None, @@ -989,6 +982,17 @@ impl Module { } pub mod zkgm { + + impl From for Instruction { + fn from(value: ucs03_zkgm::com::Instruction) -> Self { + Self { + version: value.version, + opcode: value.opcode, + operand: value.operand, + } + } + } + alloy::sol! { #![sol(rpc)] struct GovernanceToken { diff --git a/tools/union-test/src/helpers.rs b/tools/union-test/src/helpers.rs index 28e749a652..018960a294 100644 --- a/tools/union-test/src/helpers.rs +++ b/tools/union-test/src/helpers.rs @@ -1,3 +1,4 @@ +use alloy::primitives::U256; use unionlabs::primitives::FixedBytes; #[derive(Debug, Clone, PartialEq)] @@ -30,7 +31,7 @@ pub struct PacketTimeout { #[derive(Debug, Clone, PartialEq)] pub struct PacketAck { pub packet_hash: FixedBytes<32>, - pub tag: u128, + pub tag: U256, } #[derive(Debug, Clone, PartialEq)] diff --git a/tools/union-test/src/lib.rs b/tools/union-test/src/lib.rs index bda8aa6903..8e97bfad16 100644 --- a/tools/union-test/src/lib.rs +++ b/tools/union-test/src/lib.rs @@ -27,6 +27,7 @@ pub mod cosmos_helpers; pub mod evm; pub mod helpers; pub mod voyager; +pub mod zkgm_helper; use crate::{ channel_provider::{ChannelConfirm, ChannelPair, ChannelPool}, @@ -405,7 +406,7 @@ impl ChainEndpoint for cosmos::Module { async fn send_ibc_transaction( &self, - contract: Bech32, + contract: Addr, msg: Self::Msg, signer: &Self::ProviderType, ) -> anyhow::Result<(H256, u64)> { diff --git a/tools/union-test/src/zkgm_helper.rs b/tools/union-test/src/zkgm_helper.rs new file mode 100644 index 0000000000..b989b370ed --- /dev/null +++ b/tools/union-test/src/zkgm_helper.rs @@ -0,0 +1,26 @@ +use alloy::primitives::Bytes; +use alloy_sol_types::SolValue as _; +use ucs03_zkgm::com::{Call, Instruction, INSTR_VERSION_0, OP_BATCH, OP_CALL}; + +pub fn make_batch(instructions: Vec) -> Instruction { + Instruction { + version: INSTR_VERSION_0, + opcode: OP_BATCH, + operand: instructions.abi_encode_params().into(), + } +} + +pub fn make_call(sender: Bytes, contract_address: Bytes, contract_calldata: Bytes) -> Instruction { + Instruction { + version: INSTR_VERSION_0, + opcode: OP_CALL, + operand: Call { + sender, + eureka: false, + contract_address, + contract_calldata, + } + .abi_encode_params() + .into(), + } +} diff --git a/tools/union-test/tests/lst/bond.rs b/tools/union-test/tests/lst/bond.rs index 4df2072de9..68eee513ae 100644 --- a/tools/union-test/tests/lst/bond.rs +++ b/tools/union-test/tests/lst/bond.rs @@ -16,10 +16,12 @@ use ucs03_zkgm::{ }; use union_test::{ cosmos::{self}, + cosmos_helpers::calculate_proxy_address, evm::{ self, zkgm::{Instruction as InstructionEvm, UCS03Zkgm}, }, + zkgm_helper, }; use unionlabs::{ encoding::{Encode, Json}, @@ -72,163 +74,37 @@ async fn test_escher_lst_success() { let dst_channel_id = 1; let src_channel_id = 1; - let vault_on_union = "union1skg5244hpkad603zz77kdekzw6ffgpfrde3ldk8rpdz06n62k4hqct0w4j"; - - let u_on_eth = hex_literal::hex!("0c8C6f58156D10d18193A8fFdD853e1b9F8D8836"); - - let metadata = SolverMetadata { - solverAddress: u_on_eth.to_vec().into(), - metadata: Default::default(), - } - .abi_encode_params(); - - let instruction_cosmos = Instruction { - version: INSTR_VERSION_2, - opcode: OP_TOKEN_ORDER, - operand: TokenOrderV2 { - sender: cosmos_address_bytes.clone().into(), - receiver: evm_address.to_vec().into(), - base_token: "muno".as_bytes().into(), - base_amount: "100000".parse().unwrap(), - kind: TOKEN_ORDER_KIND_SOLVE, - metadata: metadata.into(), - quote_token: u_on_eth.to_vec().into(), - quote_amount: "100000".parse().unwrap(), - } - .abi_encode_params() - .into(), - }; - - let (_, zkgm_deployer_provider) = t.ctx.dst.get_provider_privileged().await; - println!("registering u counterpart"); - t.ctx - .dst - .u_register_fungible_counterpart( - H160::from(u_on_eth), - zkgm_deployer_provider.clone(), - alloy::primitives::U256::ZERO, - dst_channel_id, - b"muno".to_vec().into(), - evm::u::U::FungibleCounterparty { - beneficiary: vault_on_union.as_bytes().to_vec().into(), - }, - ) - .await - .unwrap(); - println!("u counterpart is registered"); - - let mut salt_bytes = [0u8; 32]; - rand::rng().fill_bytes(&mut salt_bytes); - - let cw_msg = ucs03_zkgm::msg::ExecuteMsg::Send { - channel_id: src_channel_id.try_into().unwrap(), - timeout_height: 0u64.into(), - timeout_timestamp: voyager_sdk::primitives::Timestamp::from_secs(u32::MAX.into()), - salt: salt_bytes.into(), - instruction: instruction_cosmos.abi_encode_params().into(), - }; - let bin_msg: Vec = Encode::::encode(&cw_msg); - - let funds = vec![Coin { - denom: "muno".into(), - amount: "100000".into(), - }]; - - let ack_packet_data = t - .ctx - .send_and_recv_and_ack_with_retry::( - &t.ctx.src, - contract, - (bin_msg, funds), - &t.ctx.dst, - 3, - Duration::from_secs(20), - Duration::from_secs(720), - cosmos_provider, - ) - .await; - - assert!( - ack_packet_data.is_ok(), - "Failed to send and ack packet: {:?}", - ack_packet_data.err() - ); - - let new_u_balance = t - .ctx - .dst - .zkgmerc20_balance_of( - H160::from(u_on_eth), - evm_address.into(), - evm_provider.clone(), - ) - .await - .unwrap(); - - let new_vault_balance = t - .ctx - .src - .native_balance(Bech32::from_str(vault_on_union).unwrap(), "muno") - .await - .unwrap(); - - // both balances are updated - assert!(new_u_balance > U256::ZERO); - assert!(new_vault_balance > 0); - - println!("new_u_balance: {}", new_u_balance); - - let lst_hub = "union1fdg764zzxwvwyqkx3fuj0236l9ddh5xmutgvj2mv9cduffy82z9sp62ygc"; - // let lst = "union1jansh23v7teaznyljq6ss4vx6eym8yrz0dsjchap4u7j3etx94vqhmcwn5"; - - let addr: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); - let canon = cosmwasm_std::CanonicalAddr::from(addr.data().as_ref()); + // setting "muno" as the fungible counterparty + eth_set_fungible_counterparty( + &t.ctx.dst, + src_channel_id, + b"muno", + t.union_address.escrow_vault.as_bytes(), + ) + .await + .unwrap(); - let zkgm_proxy_canon = instantiate2_address( - // Checksum of the base contract - &hex_literal::hex!("ec827349ed4c1fec5a9c3462ff7c979d4c40e7aa43b16ed34469d04ff835f2a1"), - &canon, - proxy_account_salt_for_tests( - alloy::primitives::U256::ZERO, - dst_channel_id, - evm_address.as_slice(), - ) - .get() - .as_slice(), + // funding the eth address that we are execute bond with, with muno + eth_fund_u( + &t, + src_channel_id, + cosmos_address.to_string(), + evm_address.into(), + 100_000, + 500_000, ) + .await .unwrap(); - let hrp = Bech32::>::from_str(UNION_ZKGM_ADDRESS) - .unwrap() - .hrp() - .to_string(); + let mut salt_bytes = [0u8; 32]; + rand::rng().fill_bytes(&mut salt_bytes); - // 3. Build a Bech32 address with same HRP - let zkgm_proxy_calculated = Bech32::>::new( - hrp, - FixedBytes::<32>::try_from(zkgm_proxy_canon.as_slice()).unwrap(), + let proxy_address = calculate_proxy_address( + &t.union_address.zkgm, + alloy::primitives::U256::ZERO, + dst_channel_id, + evm_address.as_slice(), ); - println!("ZKGM Proxy: {}", zkgm_proxy_calculated); - - // let zkgm_proxy = zkgm_proxy_calculated.to_string().as_str(); - - // let bond_message: Bytes = json!({ - // "bond": { - // "mint_to_address": "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", - // "min_mint_amount": "3" - // } - // }) - // .to_string() - // .as_bytes() - // .into(); - - // let zkgm_message = json!({ - // "contract": lst_hub, - // "msg": bond_message.to_string(), - // "funds": [{ "denom": "muno", "amount": "3" }], - // "call_action": "call_proxy" - // }) - // .to_string(); let zkgm_msg_json = make_zkgm_call_payload( lst_hub, @@ -241,80 +117,23 @@ async fn test_escher_lst_success() { let proxy_balance = t .ctx .src - .native_balance(zkgm_proxy_calculated.clone(), "muno") + .native_balance(proxy_address.clone(), "muno") .await .unwrap(); println!("Proxy balance before: {}", proxy_balance); - let addr_str = zkgm_proxy_calculated.to_string(); - let receiver = addr_str.into_bytes().into(); - - let instruction_from_evm_to_union = InstructionEvm { - version: INSTR_VERSION_0, - opcode: OP_BATCH, - operand: Batch { - instructions: vec![ - Instruction { - version: INSTR_VERSION_2, - opcode: OP_TOKEN_ORDER, - operand: TokenOrderV2 { - sender: evm_address.to_vec().into(), - receiver, - base_token: u_on_eth.to_vec().into(), - base_amount: "150".parse().unwrap(), - kind: TOKEN_ORDER_KIND_SOLVE, - metadata: SolverMetadata { - solverAddress: vault_on_union.as_bytes().into(), - metadata: Default::default(), - } - .abi_encode_params() - .into(), - quote_token: "muno".as_bytes().into(), - quote_amount: "150".parse().unwrap(), - } - .abi_encode_params() - .into(), - }, - Instruction { - version: INSTR_VERSION_0, - opcode: OP_CALL, - operand: Call { - sender: evm_address.to_vec().into(), - eureka: false, - contract_address: zkgm_proxy_calculated - .to_string() - .as_bytes() - .to_vec() - .into(), - contract_calldata: zkgm_msg_json.as_bytes().to_vec().into(), - } - .abi_encode_params() - .into(), - }, - ], - } - .abi_encode_params() - .into(), - }; - - let approve_tx_hash = t + let _ = t .ctx .dst .zkgmerc20_approve( - u_on_eth.into(), - ETH_ADDRESS_ZKGM.into(), + ETH_ADDRESS_U, + ETH_ADDRESS_ZKGM, U256::from(100000000000u64), evm_provider.clone(), ) - .await; - - assert!( - approve_tx_hash.is_ok(), - "Failed to send approve transaction: {:?}, from_account: {:?}", - approve_tx_hash.err(), - evm_address - ); + .await + .unwrap(); let ucs03_zkgm = UCS03Zkgm::new(ETH_ADDRESS_ZKGM.into(), evm_provider.clone()); @@ -324,7 +143,19 @@ async fn test_escher_lst_success() { 0u64, 4294967295000000000u64, salt_bytes.into(), - instruction_from_evm_to_union.clone(), + InstructionEvm::from(zkgm_helper::make_batch(vec![ + evm_helper::make_token_order_v2( + &t.union_address.escrow_vault, + &evm_address, + &proxy_address, + alloy::primitives::U256::from(150u128), + ), + zkgm_helper::make_call( + evm_address.to_vec().into(), + proxy_address.as_bytes().to_vec().into(), + zkgm_msg_json.as_bytes().to_vec().into(), + ), + ])), ) .clear_decoder() .with_cloned_provider(); @@ -345,7 +176,7 @@ async fn test_escher_lst_success() { let acked_packet = acked_packet.unwrap(); assert!( - acked_packet.tag == 1, + acked_packet.tag == TAG_ACK_SUCCESS, "Packet is not acked successfully, but it should be. Tag: {:?}", acked_packet.tag ); @@ -1533,15 +1364,3 @@ async fn test_escher_lst_success() { // println!("Proxy balance before: {}", proxy_balance); // } - -fn proxy_account_salt_for_tests( - path: alloy::primitives::U256, - channel_id: u32, - sender: &[u8], -) -> unionlabs::primitives::H256 { - use alloy_sol_types::SolValue; - use unionlabs::ethereum::keccak256; - - let encoded = (path, channel_id, sender.to_vec()).abi_encode_params(); - keccak256(encoded) -} diff --git a/tools/union-test/tests/lst/mod.rs b/tools/union-test/tests/lst/mod.rs index a9feb33fe0..c29ecc6eef 100644 --- a/tools/union-test/tests/lst/mod.rs +++ b/tools/union-test/tests/lst/mod.rs @@ -1,14 +1,14 @@ use std::{str::FromStr as _, sync::Arc, time::Duration}; use alloy_sol_types::SolValue as _; -use cosmwasm_std::Addr; +use cosmwasm_std::{instantiate2_address, Addr}; use hex_literal::hex; use protos::cosmos::base::v1beta1::Coin as ProtoCoin; use rand::RngCore as _; use serde::Deserialize; use tokio::sync::OnceCell; use ucs03_zkgm::com::{ - Instruction, SolverMetadata, TokenOrderV2, INSTR_VERSION_2, OP_TOKEN_ORDER, + Instruction, SolverMetadata, TokenOrderV2, INSTR_VERSION_2, OP_TOKEN_ORDER, TAG_ACK_SUCCESS, TOKEN_ORDER_KIND_SOLVE, }; use union_test::{ @@ -232,7 +232,7 @@ pub async fn eth_fund_u( let mut salt_bytes = [0u8; 32]; rand::rng().fill_bytes(&mut salt_bytes); - let _ = t + let ack = t .ctx .send_and_recv_and_ack_with_retry::( &t.ctx.src, @@ -261,6 +261,44 @@ pub async fn eth_fund_u( ) .await?; + // make sure the transfer is successful + assert_eq!(ack.tag, TAG_ACK_SUCCESS); + Ok(()) } } + +pub mod evm_helper { + use alloy::primitives::Address; + + use super::*; + + pub fn make_token_order_v2( + escrow_vault_address: &Addr, + sender: &Address, + receiver: &Addr, + amount: alloy::primitives::U256, + ) -> Instruction { + Instruction { + version: INSTR_VERSION_2, + opcode: OP_TOKEN_ORDER, + operand: TokenOrderV2 { + sender: sender.to_vec().into(), + receiver: receiver.as_bytes().to_vec().into(), + base_token: ETH_ADDRESS_U.into_bytes().into(), + base_amount: amount, + quote_token: b"muno".into(), + quote_amount: amount, + kind: TOKEN_ORDER_KIND_SOLVE, + metadata: SolverMetadata { + solverAddress: escrow_vault_address.as_bytes().to_vec().into(), + metadata: Default::default(), + } + .abi_encode_params() + .into(), + } + .abi_encode_params() + .into(), + } + } +} From 3c73d8a4665a9798a5c877c5c86174a1a182c3b5 Mon Sep 17 00:00:00 2001 From: aeryz Date: Tue, 23 Sep 2025 15:54:42 +0300 Subject: [PATCH 14/33] chore: bond test with test queue Signed-off-by: aeryz --- Cargo.lock | 168 ++++++++++++- tools/union-test/Cargo.toml | 11 +- tools/union-test/src/cosmos.rs | 122 +++++++--- tools/union-test/src/evm.rs | 10 +- tools/union-test/src/lib.rs | 26 +- tools/union-test/tests/lst/bond.rs | 264 ++++++++++++-------- tools/union-test/tests/lst/mod.rs | 374 ++++++++++++++++++++--------- 7 files changed, 692 insertions(+), 283 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e6eef67e1b..04aab58375 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1839,6 +1839,15 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7460f7dd8e100147b82a63afca1a20eb6c231ee36b90ba7272e14951cb58af59" +[[package]] +name = "autocfg" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" +dependencies = [ + "autocfg 1.4.0", +] + [[package]] name = "autocfg" version = "1.4.0" @@ -3071,6 +3080,15 @@ dependencies = [ "error-code", ] +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "cmac" version = "0.7.2" @@ -4455,7 +4473,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18e4fdb82bd54a12e42fb58a800dcae6b9e13982238ce2296dc3570b92148e1f" dependencies = [ "data-encoding", - "syn 1.0.109", + "syn 2.0.101", ] [[package]] @@ -5934,7 +5952,7 @@ version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41" dependencies = [ - "autocfg", + "autocfg 1.4.0", ] [[package]] @@ -5943,6 +5961,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + [[package]] name = "funty" version = "1.1.0" @@ -6322,7 +6346,7 @@ dependencies = [ "ff 0.13.1", "rand 0.8.5", "rand_core 0.6.4", - "rand_xorshift", + "rand_xorshift 0.3.0", "subtle 2.6.1", ] @@ -7194,7 +7218,7 @@ version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ - "autocfg", + "autocfg 1.4.0", "hashbrown 0.12.3", "serde", ] @@ -8086,7 +8110,7 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ - "autocfg", + "autocfg 1.4.0", "scopeguard", ] @@ -8380,7 +8404,7 @@ version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ - "autocfg", + "autocfg 1.4.0", ] [[package]] @@ -9263,7 +9287,7 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f6f7833f2cbf2360a6cfd58cd41a53aa7a90bd4c202f5b1c7dd2ed73c57b2c3" dependencies = [ - "autocfg", + "autocfg 1.4.0", "num-integer", "num-traits", ] @@ -9327,7 +9351,7 @@ version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" dependencies = [ - "autocfg", + "autocfg 1.4.0", "num-integer", "num-traits", ] @@ -9349,7 +9373,7 @@ version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ - "autocfg", + "autocfg 1.4.0", "libm", ] @@ -10588,7 +10612,7 @@ dependencies = [ "num-traits", "rand 0.8.5", "rand_chacha 0.3.1", - "rand_xorshift", + "rand_xorshift 0.3.0", "regex-syntax 0.8.5", "rusty-fork", "tempfile", @@ -10822,6 +10846,25 @@ dependencies = [ "nibble_vec", ] +[[package]] +name = "rand" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +dependencies = [ + "autocfg 0.1.8", + "libc", + "rand_chacha 0.1.1", + "rand_core 0.4.2", + "rand_hc 0.1.0", + "rand_isaac", + "rand_jitter", + "rand_os", + "rand_pcg", + "rand_xorshift 0.1.1", + "winapi", +] + [[package]] name = "rand" version = "0.7.3" @@ -10832,7 +10875,7 @@ dependencies = [ "libc", "rand_chacha 0.2.2", "rand_core 0.5.1", - "rand_hc", + "rand_hc 0.2.0", ] [[package]] @@ -10858,6 +10901,16 @@ dependencies = [ "serde", ] +[[package]] +name = "rand_chacha" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" +dependencies = [ + "autocfg 0.1.8", + "rand_core 0.3.1", +] + [[package]] name = "rand_chacha" version = "0.2.2" @@ -10888,6 +10941,21 @@ dependencies = [ "rand_core 0.9.3", ] +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + [[package]] name = "rand_core" version = "0.5.1" @@ -10916,6 +10984,15 @@ dependencies = [ "serde", ] +[[package]] +name = "rand_hc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +dependencies = [ + "rand_core 0.3.1", +] + [[package]] name = "rand_hc" version = "0.2.0" @@ -10925,6 +11002,59 @@ dependencies = [ "rand_core 0.5.1", ] +[[package]] +name = "rand_isaac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rand_jitter" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" +dependencies = [ + "libc", + "rand_core 0.4.2", + "winapi", +] + +[[package]] +name = "rand_os" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" +dependencies = [ + "cloudabi", + "fuchsia-cprng", + "libc", + "rand_core 0.4.2", + "rdrand", + "winapi", +] + +[[package]] +name = "rand_pcg" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" +dependencies = [ + "autocfg 0.1.8", + "rand_core 0.4.2", +] + +[[package]] +name = "rand_xorshift" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +dependencies = [ + "rand_core 0.3.1", +] + [[package]] name = "rand_xorshift" version = "0.3.0" @@ -11006,6 +11136,15 @@ dependencies = [ "yasna", ] +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + [[package]] name = "readonly" version = "0.2.13" @@ -12484,7 +12623,7 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ - "autocfg", + "autocfg 1.4.0", ] [[package]] @@ -12526,7 +12665,7 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1961e2ef424c1424204d3a5d6975f934f56b6d50ff5732382d84ebf460e147f7" dependencies = [ - "heck 0.4.1", + "heck 0.5.0", "proc-macro2", "quote", "syn 2.0.101", @@ -15258,7 +15397,9 @@ dependencies = [ "lst", "once_cell", "protos", + "rand 0.6.5", "rand 0.8.5", + "rand_chacha 0.3.1", "regex", "serde", "serde-utils", @@ -15266,6 +15407,7 @@ dependencies = [ "thiserror 2.0.12", "tokio", "tracing", + "tracing-subscriber", "trusted-mpt-light-client-types", "ucs03-zkgm", "unionlabs", diff --git a/tools/union-test/Cargo.toml b/tools/union-test/Cargo.toml index a98b16e369..3851d72165 100644 --- a/tools/union-test/Cargo.toml +++ b/tools/union-test/Cargo.toml @@ -25,6 +25,7 @@ ibc-solidity = { workspace = true, features = ["serde", "rpc"] ibc-union-msg = { workspace = true } ibc-union-spec = { workspace = true } jsonrpsee = { workspace = true, features = ["tracing", "ws-client", "http-client"] } +lst = { workspace = true, features = ["library"] } protos = { workspace = true } rand = { workspace = true, features = ["default"] } regex = "1" @@ -37,12 +38,14 @@ trusted-mpt-light-client-types = { workspace = true, features = ["serde", "binco ucs03-zkgm = { workspace = true, features = ["library"] } unionlabs = { workspace = true } voyager-sdk = { workspace = true } -lst = { workspace = true, features = [ "library" ] } [dev-dependencies] -once_cell = "1.17" -serial_test = "0.5" -tokio = { version = "1", features = ["macros", "rt"] } +once_cell = "1.17" +serial_test = "0.5" +tokio = { version = "1", features = ["macros", "rt"] } +tracing-subscriber = "0.3" +rand = "0.6" +rand_chacha = "0.3.1" [lints] diff --git a/tools/union-test/src/cosmos.rs b/tools/union-test/src/cosmos.rs index 7a6baa82c4..029f626114 100644 --- a/tools/union-test/src/cosmos.rs +++ b/tools/union-test/src/cosmos.rs @@ -13,6 +13,7 @@ use cosmos_client::{ }; use cosmos_sdk_event::CosmosSdkEvent; use cosmwasm_std::Addr; +use cw20::Cw20QueryMsg; use ibc_union_spec::{ChannelId, ClientId, ConnectionId, Timestamp}; use protos::{ cosmos::{ @@ -21,16 +22,17 @@ use protos::{ }, cosmwasm::wasm::v1::{QuerySmartContractStateRequest, QuerySmartContractStateResponse}, }; -use serde::{Deserialize, Serialize}; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; use ucs03_zkgm::msg::{PredictWrappedTokenResponse, QueryMsg}; use unionlabs::{ self, google::protobuf::any::mk_any, ibc::core::client::height::Height, primitives::{encoding::HexUnprefixed, Bech32, Bytes, H160, H256}, + prost, }; use voyager_sdk::{ - anyhow::{self, anyhow, bail, Context}, + anyhow::{self, anyhow, bail}, primitives::ChainId, serde_json, vm::BoxDynError, @@ -441,7 +443,7 @@ impl Module { // Grab the first 32 bytes — this is the uint256 in ABI encoding return Some(helpers::PacketAck { packet_hash: *packet_hash, - tag: alloy::primitives::U256::from_le_slice(&ack_bytes[..32]), + tag: alloy::primitives::U256::from_be_slice(&ack_bytes[..32]), }); } None @@ -521,35 +523,17 @@ impl Module { channel_id: ChannelId, token: Vec, ) -> anyhow::Result { - let msg = QueryMsg::PredictWrappedToken { - path: "0".to_string(), - channel_id, - token: token.into(), - }; - let req = QuerySmartContractStateRequest { - address: contract.to_string(), - query_data: serde_json::to_vec(&msg) - .context("serializing PredictWrappedToken QueryMsg")?, - }; - - let raw = self - .rpc - .client() - .grpc_abci_query::<_, QuerySmartContractStateResponse>( - "/cosmwasm.wasm.v1.Query/SmartContractState", - &req, - None, - false, + Ok(self + .query_wasm_smart::<_, PredictWrappedTokenResponse>( + contract, + &QueryMsg::PredictWrappedToken { + path: "0".to_string(), + channel_id, + token: token.into(), + }, ) .await? - .into_result()? - .unwrap() - .data; - - let resp: PredictWrappedTokenResponse = - serde_json::from_slice(&raw).context("deserializing PredictWrappedTokenResponse")?; - - Ok(resp.wrapped_token) + .wrapped_token) } pub async fn get_signer(&self) -> (Bech32, &LocalSigner) { @@ -564,10 +548,19 @@ impl Module { } } - pub async fn get_minter(&self, contract: Bech32) -> anyhow::Result { + pub async fn get_minter(&self, contract: Addr) -> anyhow::Result { + self.query_wasm_smart::<_, String>(contract, QueryMsg::GetMinter {}) + .await + } + + pub async fn query_wasm_smart( + &self, + contract: Addr, + req: Req, + ) -> anyhow::Result { let req = QuerySmartContractStateRequest { address: contract.to_string(), - query_data: serde_json::to_vec(&QueryMsg::GetMinter {})?, + query_data: serde_json::to_vec(&req)?, }; let raw = self @@ -584,10 +577,20 @@ impl Module { .unwrap() .data; - // 3) Deserialize the JSON `{ "minter": "union1..." }` into our struct - let resp = serde_json::from_slice(&raw).context("deserializing GetMinterResponse")?; + Ok(serde_json::from_slice(&raw)?) + } - Ok(resp) + pub async fn get_cw20_balance(&self, address: &Addr, token: &Addr) -> anyhow::Result { + let resp = self + .query_wasm_smart::<_, cw20::BalanceResponse>( + token.clone(), + Cw20QueryMsg::Balance { + address: address.to_string(), + }, + ) + .await?; + + Ok(resp.balance.u128()) } pub async fn get_balance( @@ -610,7 +613,7 @@ impl Module { .ok_or_else(|| anyhow::anyhow!("no balance for denom {}", denom)) } - pub async fn send_transaction_with_retry( + pub async fn send_cosmwasm_transaction_with_retry( &self, contract: Addr, msg: (Vec, Vec), @@ -619,7 +622,7 @@ impl Module { let max_retries = 5; for attempt in 1..=max_retries { let outcome = self - .send_transaction(contract.clone(), msg.clone(), signer) + .send_cosmwasm_transaction(contract.clone(), msg.clone(), signer) .await; if let Some(Ok(_)) = &outcome { @@ -645,8 +648,22 @@ impl Module { None } + pub async fn send_transaction( + &self, + msg: T, + signer: &LocalSigner, + ) -> Option> { + let tx_client = TxClient::new(signer, &self.rpc, &self.gas_config); + + let outcome = tx_client + .broadcast_tx_commit([mk_any(&msg)], "memo", true) + .await; + + Some(outcome) + } + // TODO(aeryz): return the digest - pub async fn send_transaction( + pub async fn send_cosmwasm_transaction( &self, contract: Addr, msg: (Vec, Vec), @@ -676,6 +693,33 @@ impl Module { Some(outcome) } + pub async fn stake( + &self, + validator_address: String, + amount: u128, + signer: &LocalSigner, + ) -> Option> { + let tx_client = TxClient::new(signer, &self.rpc, &self.gas_config); + + let signer_address = signer.address(); + let outcome = tx_client + .broadcast_tx_commit( + [mk_any(&protos::cosmos::staking::v1beta1::MsgDelegate { + delegator_address: signer_address.to_string(), + validator_address, + amount: Some(Coin { + denom: "muno".to_string(), + amount: amount.to_string(), + }), + })], + "memo", + true, + ) + .await; + + Some(outcome) + } + /// Helper to detect the ABCI “account sequence mismatch” error. fn is_sequence_mismatch(&self, err: &BroadcastTxCommitError) -> bool { match err { @@ -692,7 +736,7 @@ impl Module { msg: (Vec, Vec), signer: &LocalSigner, ) -> anyhow::Result<(H256, u64)> { - let result = self.send_transaction(contract, msg, signer).await; + let result = self.send_cosmwasm_transaction(contract, msg, signer).await; let tx_result = result.ok_or_else(|| anyhow!("failed to send transaction"))??; let height = tx_result .height diff --git a/tools/union-test/src/evm.rs b/tools/union-test/src/evm.rs index 57a78f7b80..3780ac6de6 100644 --- a/tools/union-test/src/evm.rs +++ b/tools/union-test/src/evm.rs @@ -1,4 +1,4 @@ -use std::{marker::PhantomData, panic::AssertUnwindSafe, str::FromStr, time::Duration}; +use std::{panic::AssertUnwindSafe, str::FromStr, time::Duration}; use alloy::{ contract::{Error, RawCallBuilder, Result}, @@ -20,7 +20,7 @@ use ibc_solidity::Ibc::IbcEvents; use ibc_union_spec::{datagram::Datagram, ChannelId}; use jsonrpsee::{core::RpcResult, types::ErrorObjectOwned}; use serde::{Deserialize, Serialize}; -use tracing::{error, info_span, warn, Instrument}; +use tracing::{debug, error, info_span, warn, Instrument}; use unionlabs::{ primitives::{FixedBytes, H160, H256, U256}, ErrorReporter, @@ -339,7 +339,7 @@ impl Module { Some(helpers::PacketAck { packet_hash: ev.packet_hash.into(), - tag: alloy::primitives::U256::from_le_slice(&ack_bytes[..32]), + tag: alloy::primitives::U256::from_be_slice(&ack_bytes[..32]), }) } _ => None, @@ -520,12 +520,12 @@ impl Module { .map_err(|_rpc_err| TxSubmitError::InclusionError)?; if let Some(rcpt) = maybe_rcpt { - println!("✅ tx {tx_hash:?} mined in block {:?}", rcpt.block_number); + debug!("✅ tx {tx_hash:?} mined in block {:?}", rcpt.block_number); return Ok(()); } if attempts <= 5 { attempts += 1; - println!("receipt not yet available, retry {attempts}/5…"); + debug!("receipt not yet available, retry {attempts}/5…"); tokio::time::sleep(Duration::from_secs(4)).await; continue; } diff --git a/tools/union-test/src/lib.rs b/tools/union-test/src/lib.rs index 8e97bfad16..f344c05853 100644 --- a/tools/union-test/src/lib.rs +++ b/tools/union-test/src/lib.rs @@ -11,6 +11,7 @@ use ibc_union_spec::{ use jsonrpsee::http_client::HttpClient; use protos::cosmos::base::v1beta1::Coin; use regex::Regex; +use tracing::info; use unionlabs::{ ibc::core::client::height::Height, primitives::{Bech32, Bytes, FixedBytes, H160, H256}, @@ -722,7 +723,7 @@ where destination_chain: &Dst, timeout: Duration, signer: &Src::ProviderType, - ) -> anyhow::Result { + ) -> anyhow::Result<(helpers::PacketRecv, helpers::PacketAck)> { let (packet_hash, _height) = match source_chain .send_ibc_transaction(contract.clone(), msg.clone(), signer) .await @@ -735,25 +736,24 @@ where anyhow::bail!("send_ibc_transaction failed: {:?}", e); } }; - println!( + + info!( "Packet sent from {} to {} with hash: {}", source_chain.chain_id(), destination_chain.chain_id(), packet_hash ); - match destination_chain + let recv = destination_chain .wait_for_packet_recv(packet_hash, timeout) - .await - { - Ok(evt) => evt, - Err(e) => anyhow::bail!("wait_for_packet_recv failed: {:?}", e), - }; + .await?; - match source_chain.wait_for_packet_ack(packet_hash, timeout).await { - Ok(evt) => Ok(evt), - Err(e) => anyhow::bail!("wait_for_packet_ack failed: {:?}", e), - } + Ok(( + recv, + source_chain + .wait_for_packet_ack(packet_hash, timeout) + .await?, + )) } #[allow(clippy::too_many_arguments)] @@ -1161,7 +1161,7 @@ where retry_delay: Duration, timeout: Duration, signer: &Src::ProviderType, - ) -> anyhow::Result { + ) -> anyhow::Result<(helpers::PacketRecv, helpers::PacketAck)> { let mut attempt = 0; println!( "Starting send_and_recv_with_retry with max_retries: {}, retry_delay: {:?}", diff --git a/tools/union-test/tests/lst/bond.rs b/tools/union-test/tests/lst/bond.rs index 68eee513ae..2664368123 100644 --- a/tools/union-test/tests/lst/bond.rs +++ b/tools/union-test/tests/lst/bond.rs @@ -1,19 +1,10 @@ -use std::{str::FromStr, time::Duration}; +use std::time::Duration; -use alloy::sol_types::SolValue; -use cosmwasm_std::{ - instantiate2_address, to_json_binary, Addr, Coin as CwCoin, CosmosMsg, Uint128, WasmMsg, -}; -use lst::msg::ExecuteMsg as LstExecuteMsg; -use protos::cosmos::base::v1beta1::Coin; +use alloy::{network::AnyNetwork, primitives::Address, providers::DynProvider}; +use cosmwasm_std::{to_json_binary, Addr, Coin as CwCoin, CosmosMsg, Decimal, WasmMsg}; +use lst::msg::{AccountingStateResponse, ExecuteMsg as LstExecuteMsg}; use rand::RngCore; -use ucs03_zkgm::{ - self, - com::{ - Batch, Call, Instruction, SolverMetadata, TokenOrderV2, INSTR_VERSION_0, INSTR_VERSION_2, - OP_BATCH, OP_CALL, OP_TOKEN_ORDER, TOKEN_ORDER_KIND_SOLVE, - }, -}; +use tracing::info; use union_test::{ cosmos::{self}, cosmos_helpers::calculate_proxy_address, @@ -23,10 +14,7 @@ use union_test::{ }, zkgm_helper, }; -use unionlabs::{ - encoding::{Encode, Json}, - primitives::{Bech32, FixedBytes, H160, U256}, -}; +use unionlabs::primitives::U256; use crate::lst::*; @@ -35,18 +23,18 @@ use crate::lst::*; // u: union1pntx7gm7shsp6slef74ae7wvcc35t3wdmanh7wrg4xkq95m24qds5atmcp // lst: union1fdg764zzxwvwyqkx3fuj0236l9ddh5xmutgvj2mv9cduffy82z9sp62ygc -fn make_zkgm_call_payload( +fn make_zkgm_bond_payload_via_call( lst_hub: &str, mint_to: &str, - min_mint_amount: Uint128, + min_mint_amount: u128, funds_denom: &str, - funds_amount: u32, -) -> String { + funds_amount: u128, +) -> Vec { let wasm_exec: CosmosMsg = CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: lst_hub.to_string(), msg: to_json_binary(&LstExecuteMsg::Bond { mint_to_address: Addr::unchecked(mint_to), - min_mint_amount, + min_mint_amount: min_mint_amount.into(), }) .unwrap(), funds: vec![CwCoin { @@ -55,73 +43,32 @@ fn make_zkgm_call_payload( }], }); - voyager_sdk::serde_json::to_string(&vec![wasm_exec]).expect("vec cosmosmsg json") + voyager_sdk::serde_json::to_vec(&vec![wasm_exec]).expect("vec cosmosmsg json") } -#[tokio::test] -async fn test_escher_lst_success() { - let t = init_ctx().await; - - let (evm_address, evm_provider) = t.ctx.dst.get_provider().await; - let (cosmos_address, cosmos_provider) = t.ctx.src.get_signer().await; - let cosmos_address_bytes = cosmos_address.to_string().into_bytes(); - - // ensure_channels_opened(ctx.channel_count).await; - // let available_channel = ctx.get_available_channel_count().await; - // assert!(available_channel > 0); - // let pair = ctx.get_channel().await.expect("channel available"); - - let dst_channel_id = 1; - let src_channel_id = 1; - - // setting "muno" as the fungible counterparty - eth_set_fungible_counterparty( - &t.ctx.dst, - src_channel_id, - b"muno", - t.union_address.escrow_vault.as_bytes(), - ) - .await - .unwrap(); - - // funding the eth address that we are execute bond with, with muno - eth_fund_u( - &t, - src_channel_id, - cosmos_address.to_string(), - evm_address.into(), - 100_000, - 500_000, - ) - .await - .unwrap(); - - let mut salt_bytes = [0u8; 32]; - rand::rng().fill_bytes(&mut salt_bytes); - - let proxy_address = calculate_proxy_address( +async fn bond( + t: &LstContext, + src_channel_id: u32, + dst_channel_id: u32, + sender_on_evm: Address, + sender_evm_provider: DynProvider, + min_mint_amount: u128, + bond_amount: u128, +) { + let proxy_address_on_union = calculate_proxy_address( &t.union_address.zkgm, alloy::primitives::U256::ZERO, dst_channel_id, - evm_address.as_slice(), - ); - - let zkgm_msg_json = make_zkgm_call_payload( - lst_hub, - "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", - 150u128.into(), - "muno", - 150, + sender_on_evm.as_ref(), ); - let proxy_balance = t - .ctx - .src - .native_balance(proxy_address.clone(), "muno") + // funding the eth address that we execute bond with, with muno + eth_fund_u(&t, src_channel_id, sender_on_evm.into(), 100_000, 500_000) .await .unwrap(); - println!("Proxy balance before: {}", proxy_balance); + let mut salt_bytes = [0u8; 32]; + rand::thread_rng().fill_bytes(&mut salt_bytes); let _ = t .ctx @@ -130,12 +77,12 @@ async fn test_escher_lst_success() { ETH_ADDRESS_U, ETH_ADDRESS_ZKGM, U256::from(100000000000u64), - evm_provider.clone(), + sender_evm_provider.clone(), ) .await .unwrap(); - let ucs03_zkgm = UCS03Zkgm::new(ETH_ADDRESS_ZKGM.into(), evm_provider.clone()); + let ucs03_zkgm = UCS03Zkgm::new(ETH_ADDRESS_ZKGM.into(), sender_evm_provider.clone()); let call = ucs03_zkgm .send( @@ -146,21 +93,28 @@ async fn test_escher_lst_success() { InstructionEvm::from(zkgm_helper::make_batch(vec![ evm_helper::make_token_order_v2( &t.union_address.escrow_vault, - &evm_address, - &proxy_address, - alloy::primitives::U256::from(150u128), + &sender_on_evm, + &proxy_address_on_union, + alloy::primitives::U256::from(bond_amount), ), zkgm_helper::make_call( - evm_address.to_vec().into(), - proxy_address.as_bytes().to_vec().into(), - zkgm_msg_json.as_bytes().to_vec().into(), + sender_on_evm.to_vec().into(), + proxy_address_on_union.as_bytes().to_vec().into(), + make_zkgm_bond_payload_via_call( + t.union_address.lst_hub.as_str(), + &proxy_address_on_union.to_string(), + min_mint_amount, + "muno", + bond_amount, + ) + .into(), ), ])), ) .clear_decoder() .with_cloned_provider(); - let acked_packet = t + let (_, ack) = t .ctx .send_and_recv_and_ack_with_retry::( &t.ctx.dst, @@ -170,25 +124,133 @@ async fn test_escher_lst_success() { 3, Duration::from_secs(20), Duration::from_secs(720), - &evm_provider, + &sender_evm_provider, ) - .await; + .await + .unwrap(); - let acked_packet = acked_packet.unwrap(); - assert!( - acked_packet.tag == TAG_ACK_SUCCESS, - "Packet is not acked successfully, but it should be. Tag: {:?}", - acked_packet.tag - ); + assert_eq!(ack.tag, TAG_ACK_SUCCESS); +} - let proxy_balance = t - .ctx +async fn get_accounting_state(t: &LstContext) -> anyhow::Result { + t.ctx .src - .native_balance(zkgm_proxy_calculated, "muno") + .query_wasm_smart::<_, AccountingStateResponse>( + t.union_address.lst_hub.clone(), + lst::msg::QueryMsg::AccountingState {}, + ) + .await +} + +#[tokio::test] +async fn test_bond_success() { + run_test_in_queue("bond", async |t| { + // ensure_channels_opened(ctx.channel_count).await; + // let available_channel = ctx.get_available_channel_count().await; + // assert!(available_channel > 0); + // let pair = ctx.get_channel().await.expect("channel available"); + + let dst_channel_id = 1; + let src_channel_id = 1; + + // setting "muno" as the fungible counterparty + eth_set_fungible_counterparty( + &t.ctx.dst, + src_channel_id, + b"muno", + t.union_address.escrow_vault.as_bytes(), + ) .await .unwrap(); - println!("Proxy balance before: {}", proxy_balance); + let bonds = [(120, 200), (400, 700)]; + + let evm_signers = [ + t.ctx.dst.get_provider().await, + t.ctx.dst.get_provider().await, + ]; + + for (bond_amount, evm_signer) in bonds.into_iter().zip(evm_signers) { + let (evm_address, evm_provider): (Address, DynProvider) = evm_signer; + let (min_mint_amount, bond_amount) = bond_amount; + + let proxy_address = calculate_proxy_address( + &t.union_address.zkgm, + alloy::primitives::U256::ZERO, + dst_channel_id, + evm_address.as_ref(), + ); + + let eu_balance = || async { + t.ctx + .src + .get_cw20_balance(&proxy_address, &t.union_address.eu) + .await + .unwrap() + }; + + let eu_balance_before = eu_balance().await; + + let state = get_accounting_state(&t).await.unwrap(); + + bond( + &t, + src_channel_id, + dst_channel_id, + evm_address, + evm_provider, + min_mint_amount, + bond_amount, + ) + .await; + + let new_state = get_accounting_state(&t).await.unwrap(); + + // We expect to get the same amount of `total_asset` change. We don't have to check the + // actual value since it's the unit test's job. + let eu_balance_after_stake = eu_balance().await; + assert_eq!( + eu_balance_after_stake - eu_balance_before, + new_state.total_shares.u128() - state.total_shares.u128() + ); + + let k = t + .ctx + .src + .privileged_acc_keyring + .with(async |k| k) + .await + .unwrap(); + + let outcome = t + .ctx + .src + .stake( + "unionvaloper1qp4uzhet2sd9mrs46kemse5dt9ncz4k3xuz7ej".to_string(), + bond_amount, + // &t.staker, + k, + ) + .await + .unwrap() + .unwrap(); + + assert_eq!(outcome.tx_result.code, Code::Ok); + } + + let mut prev_rate = Decimal::MAX; + for i in 1..10 { + tokio::time::sleep(Duration::from_secs(10)).await; + + let new_rate = get_accounting_state(&t).await.unwrap().purchase_rate; + info!("checking the rate ({i}).. new_rate: {new_rate} prev_rate: {prev_rate}"); + + assert!(new_rate < prev_rate); + + prev_rate = new_rate; + } + }) + .await; } // #[tokio::test] diff --git a/tools/union-test/tests/lst/mod.rs b/tools/union-test/tests/lst/mod.rs index c29ecc6eef..b3daa89c8a 100644 --- a/tools/union-test/tests/lst/mod.rs +++ b/tools/union-test/tests/lst/mod.rs @@ -1,12 +1,21 @@ -use std::{str::FromStr as _, sync::Arc, time::Duration}; +use std::{cell::RefCell, future::Future, sync::Arc, time::Duration}; use alloy_sol_types::SolValue as _; -use cosmwasm_std::{instantiate2_address, Addr}; +use bip32::secp256k1::ecdsa::SigningKey; +use cometbft_rpc::types::code::Code; +use cosmos_client::wallet::{LocalSigner, WalletT as _}; +use cosmwasm_std::Addr; use hex_literal::hex; use protos::cosmos::base::v1beta1::Coin as ProtoCoin; use rand::RngCore as _; +use rand_chacha::{ + rand_core::{block::BlockRng, SeedableRng}, + ChaChaCore, +}; use serde::Deserialize; -use tokio::sync::OnceCell; +use tokio::sync::{Mutex, OnceCell}; +use tracing::info; +use tracing_subscriber::FmtSubscriber; use ucs03_zkgm::com::{ Instruction, SolverMetadata, TokenOrderV2, INSTR_VERSION_2, OP_TOKEN_ORDER, TAG_ACK_SUCCESS, TOKEN_ORDER_KIND_SOLVE, @@ -20,13 +29,14 @@ use union_test::{ }; use unionlabs::{ encoding::{EncodeAs, Json}, - primitives::{Bech32, H160}, + primitives::{H160, H256}, }; use voyager_sdk::{anyhow, serde_json}; pub mod bond; -pub static CTX: OnceCell> = OnceCell::const_new(); +pub static CTX: OnceCell<(Mutex, Arc)> = OnceCell::const_new(); + pub static CHANNELS_OPENED: OnceCell<()> = OnceCell::const_new(); pub const ETH_ADDRESS_U: H160 = H160::new(hex!("0c8C6f58156D10d18193A8fFdD853e1b9F8D8836")); @@ -40,8 +50,9 @@ pub struct UnionAddressBook { } pub struct LstContext { - union_address: UnionAddressBook, - ctx: TestContext, + pub union_address: UnionAddressBook, + pub staker: LocalSigner, + pub ctx: TestContext, } #[derive(Deserialize)] @@ -53,107 +64,251 @@ pub struct Config { union_deployer_addr: String, } -async fn init_ctx<'a>() -> Arc { - CTX.get_or_init(|| async { - let cfg: Config = serde_json::from_str(include_str!("./config.json")).unwrap(); +pub struct Queue { + tests: Vec, +} - let src = cosmos::Module::new(cfg.union).await.unwrap(); - let dst = evm::Module::new(cfg.evm).await.unwrap(); +async fn run_test_in_queue<'a, Fut: Future, F: Fn(Arc) -> Fut>( + key: &str, + test_fn: F, +) { + let ctx = CTX + .get_or_init(|| async { + let subscriber = FmtSubscriber::builder() + .with_max_level(tracing::Level::INFO) + .finish(); + tracing::subscriber::set_global_default(subscriber) + .expect("setting default subscriber failed"); + let cfg: Config = serde_json::from_str(include_str!("./config.json")).unwrap(); + + let src = cosmos::Module::new(cfg.union).await.unwrap(); + let dst = evm::Module::new(cfg.evm).await.unwrap(); + + let ctx = TestContext::new( + src, + dst, + cfg.needed_channel_count as usize, + &cfg.voyager_config_file_path, + ) + .await + .unwrap(); - let ctx = TestContext::new( - src, - dst, - cfg.needed_channel_count as usize, - &cfg.voyager_config_file_path, - ) - .await - .unwrap(); + let mut rng = + BlockRng::new(ChaChaCore::from_rng(rand_chacha::rand_core::OsRng).unwrap()); - Arc::new(LstContext { - union_address: UnionAddressBook { - zkgm: calculate_cosmos_contract_address(&cfg.union_deployer_addr, SALT_ZKGM) - .unwrap(), - lst_hub: calculate_cosmos_contract_address(&cfg.union_deployer_addr, SALT_LST_HUB) - .unwrap(), - eu: calculate_cosmos_contract_address(&cfg.union_deployer_addr, SALT_EU).unwrap(), - escrow_vault: calculate_cosmos_contract_address( - &cfg.union_deployer_addr, - SALT_ESCROW_VAULT, - ) - .unwrap(), - }, - ctx, - }) - }) - .await - .clone() -} + let staker = LocalSigner::new(SigningKey::random(&mut rng).to_bytes().into(), "union"); -pub async fn ensure_channels_opened(channel_count: usize) { - CHANNELS_OPENED - .get_or_init(|| async move { - let t = init_ctx().await; - - let (src_client, dst_client) = t - .ctx - .create_clients( - Duration::from_secs(60), - "ibc-cosmwasm", - "trusted/evm/mpt", - "ibc-solidity", - "cometbls", - ) - .await - .unwrap(); - - assert!(src_client.client_id > 0); - assert!(dst_client.client_id > 0); - - let conn = t - .ctx - .open_connection::( - &t.ctx.src, - src_client.client_id, - &t.ctx.dst, - dst_client.client_id, - Duration::from_secs(180), - ) - .await - .unwrap(); - assert!(conn.connection_id > 0); - assert!(conn.counterparty_connection_id > 0); - - let current_available_count = t.ctx.get_available_channel_count().await; - - let opened = t - .ctx - .open_channels( - true, - t.union_address.zkgm.as_bytes().into(), - ETH_ADDRESS_ZKGM.into_bytes(), - conn.counterparty_connection_id, - "ucs03-zkgm-0".into(), - channel_count, - Duration::from_secs(360 * channel_count as u64), - ) + let k = ctx.src.keyring.with(async |k| k).await.unwrap(); + + if ctx + .src + .native_balance(Addr::unchecked(staker.address().to_string()), "muno") .await - .unwrap(); - assert_eq!(opened, channel_count); - - let available_count_after_open = t.ctx.get_available_channel_count().await; - assert_eq!( - current_available_count + channel_count, - available_count_after_open - ); - let pair = t.ctx.get_channel().await.expect("channel available"); - let available_count_after_get = t.ctx.get_available_channel_count().await; - assert_eq!(available_count_after_open - 1, available_count_after_get); - t.ctx.release_channel(pair).await; - let available_count_after_release = t.ctx.get_available_channel_count().await; - assert_eq!(available_count_after_open, available_count_after_release); + .unwrap() + < 90_000_000 + { + let outcome = ctx + .src + .send_transaction( + protos::cosmos::bank::v1beta1::MsgSend { + from_address: k.address().to_string(), + to_address: staker.address().to_string(), + amount: vec![ProtoCoin { + denom: "muno".to_string(), + amount: 100_000_000.to_string(), + }], + }, + k, + ) + .await + .unwrap() + .unwrap(); + + assert_eq!(outcome.tx_result.code, Code::Ok); + } + + ( + Mutex::new(Queue { + tests: { + let mut t = vec!["bond".into()]; + t.reverse(); + t + }, + }), + Arc::new(LstContext { + staker, + union_address: UnionAddressBook { + zkgm: calculate_cosmos_contract_address( + &cfg.union_deployer_addr, + SALT_ZKGM, + ) + .unwrap(), + lst_hub: calculate_cosmos_contract_address( + &cfg.union_deployer_addr, + SALT_LST_HUB, + ) + .unwrap(), + eu: calculate_cosmos_contract_address(&cfg.union_deployer_addr, SALT_EU) + .unwrap(), + escrow_vault: calculate_cosmos_contract_address( + &cfg.union_deployer_addr, + SALT_ESCROW_VAULT, + ) + .unwrap(), + }, + ctx, + }), + ) }) .await; + + loop { + { + let mut lock = ctx.0.lock().await; + if lock.tests.last().unwrap() == key { + test_fn(ctx.1.clone()).await; + let _ = lock.tests.pop(); + return; + } + } + tokio::time::sleep(Duration::from_secs(2)).await; + } } +// async fn init_ctx<'a>(key: &str) -> Arc { +// let ctx = CTX +// .get_or_init(|| async { +// let subscriber = FmtSubscriber::builder() +// .with_max_level(tracing::Level::INFO) +// .finish(); +// tracing::subscriber::set_global_default(subscriber) +// .expect("setting default subscriber failed"); +// let cfg: Config = serde_json::from_str(include_str!("./config.json")).unwrap(); + +// let src = cosmos::Module::new(cfg.union).await.unwrap(); +// let dst = evm::Module::new(cfg.evm).await.unwrap(); + +// let ctx = TestContext::new( +// src, +// dst, +// cfg.needed_channel_count as usize, +// &cfg.voyager_config_file_path, +// ) +// .await +// .unwrap(); + +// let mut rng = +// BlockRng::new(ChaChaCore::from_rng(rand_chacha::rand_core::OsRng).unwrap()); + +// ( +// Arc::new(Mutex::new(Queue { +// tests: vec!["first".into(), "second".into(), "third".into()], +// })), +// Arc::new(LstContext { +// staker: LocalSigner::new( +// SigningKey::random(&mut rng).to_bytes().into(), +// "union", +// ), +// union_address: UnionAddressBook { +// zkgm: calculate_cosmos_contract_address( +// &cfg.union_deployer_addr, +// SALT_ZKGM, +// ) +// .unwrap(), +// lst_hub: calculate_cosmos_contract_address( +// &cfg.union_deployer_addr, +// SALT_LST_HUB, +// ) +// .unwrap(), +// eu: calculate_cosmos_contract_address(&cfg.union_deployer_addr, SALT_EU) +// .unwrap(), +// escrow_vault: calculate_cosmos_contract_address( +// &cfg.union_deployer_addr, +// SALT_ESCROW_VAULT, +// ) +// .unwrap(), +// }, +// ctx, +// }), +// ) +// }) +// .await; + +// loop { +// { +// if ctx.0.lock().await.tests[0] == key { +// return ctx.1.clone(); +// } +// } + +// tokio::time::sleep(Duration::from_secs(1)).await +// } +// } + +// pub async fn ensure_channels_opened(channel_count: usize) { +// CHANNELS_OPENED +// .get_or_init(|| async move { +// let t = init_ctx().await; + +// let (src_client, dst_client) = t +// .ctx +// .create_clients( +// Duration::from_secs(60), +// "ibc-cosmwasm", +// "trusted/evm/mpt", +// "ibc-solidity", +// "cometbls", +// ) +// .await +// .unwrap(); + +// assert!(src_client.client_id > 0); +// assert!(dst_client.client_id > 0); + +// let conn = t +// .ctx +// .open_connection::( +// &t.ctx.src, +// src_client.client_id, +// &t.ctx.dst, +// dst_client.client_id, +// Duration::from_secs(180), +// ) +// .await +// .unwrap(); +// assert!(conn.connection_id > 0); +// assert!(conn.counterparty_connection_id > 0); + +// let current_available_count = t.ctx.get_available_channel_count().await; + +// let opened = t +// .ctx +// .open_channels( +// true, +// t.union_address.zkgm.as_bytes().into(), +// ETH_ADDRESS_ZKGM.into_bytes(), +// conn.counterparty_connection_id, +// "ucs03-zkgm-0".into(), +// channel_count, +// Duration::from_secs(360 * channel_count as u64), +// ) +// .await +// .unwrap(); +// assert_eq!(opened, channel_count); + +// let available_count_after_open = t.ctx.get_available_channel_count().await; +// assert_eq!( +// current_available_count + channel_count, +// available_count_after_open +// ); +// let pair = t.ctx.get_channel().await.expect("channel available"); +// let available_count_after_get = t.ctx.get_available_channel_count().await; +// assert_eq!(available_count_after_open - 1, available_count_after_get); +// t.ctx.release_channel(pair).await; +// let available_count_after_release = t.ctx.get_available_channel_count().await; +// assert_eq!(available_count_after_open, available_count_after_release); +// }) +// .await; +// } pub async fn eth_set_fungible_counterparty( module: &evm::Module, @@ -161,7 +316,7 @@ pub async fn eth_set_fungible_counterparty( base_token: &[u8], beneficiary: &[u8], ) -> anyhow::Result<()> { - tracing::info!("registering fungible counterparty"); + info!("registering fungible counterparty"); let (_, priviledged_account) = module.get_provider_privileged().await; module @@ -184,13 +339,12 @@ pub async fn eth_set_fungible_counterparty( pub async fn eth_fund_u( t: &LstContext, src_channel_id: u32, - sender: String, receiver: H160, min_amount: u64, amount: u64, ) -> anyhow::Result<()> { let (_, evm_provider) = t.ctx.dst.get_provider().await; - let (_, cosmos_provider) = t.ctx.src.get_signer().await; + let (cosmos_address, cosmos_provider) = t.ctx.src.get_signer().await; let u_balance = t .ctx @@ -206,33 +360,37 @@ pub async fn eth_fund_u( if u_balance > min_amount.into() { Ok(()) } else { + info!("the {receiver} is running low on U (u_balance), funding it with {amount}"); + let metadata = SolverMetadata { solverAddress: ETH_ADDRESS_U.into_bytes().into(), metadata: Default::default(), } .abi_encode_params(); + let amount = Into::::into(amount).into(); + let instruction_cosmos = Instruction { version: INSTR_VERSION_2, opcode: OP_TOKEN_ORDER, operand: TokenOrderV2 { - sender: sender.into_bytes().into(), + sender: cosmos_address.to_string().into_bytes().into(), receiver: receiver.into_bytes().into(), base_token: "muno".as_bytes().into(), - base_amount: "100000".parse().unwrap(), + base_amount: amount, kind: TOKEN_ORDER_KIND_SOLVE, metadata: metadata.into(), quote_token: ETH_ADDRESS_U.into_bytes().into(), - quote_amount: Into::::into(amount).into(), + quote_amount: amount, } .abi_encode_params() .into(), }; let mut salt_bytes = [0u8; 32]; - rand::rng().fill_bytes(&mut salt_bytes); + rand::thread_rng().fill_bytes(&mut salt_bytes); - let ack = t + let (_, ack) = t .ctx .send_and_recv_and_ack_with_retry::( &t.ctx.src, From 3f6a55b2bfeedcf4b1768486d8c889b378ec45cf Mon Sep 17 00:00:00 2001 From: aeryz Date: Fri, 26 Sep 2025 12:55:33 +0300 Subject: [PATCH 15/33] chore: omg tests Signed-off-by: aeryz --- tools/union-test/src/cosmos.rs | 41 ++- tools/union-test/src/evm.rs | 25 -- tools/union-test/tests/lst/bond.rs | 436 +++++++++++++++++++++++++++-- tools/union-test/tests/lst/mod.rs | 22 +- 4 files changed, 467 insertions(+), 57 deletions(-) diff --git a/tools/union-test/src/cosmos.rs b/tools/union-test/src/cosmos.rs index 029f626114..a2d1214920 100644 --- a/tools/union-test/src/cosmos.rs +++ b/tools/union-test/src/cosmos.rs @@ -23,6 +23,7 @@ use protos::{ cosmwasm::wasm::v1::{QuerySmartContractStateRequest, QuerySmartContractStateResponse}, }; use serde::{de::DeserializeOwned, Deserialize, Serialize}; +use tracing::info; use ucs03_zkgm::msg::{PredictWrappedTokenResponse, QueryMsg}; use unionlabs::{ self, @@ -228,11 +229,9 @@ impl Module { let event = match CosmosSdkEvent::::new(raw_ev) { Ok(event) => event, Err(cosmos_sdk_event::Error::Deserialize(_error)) => { - // println!("unable to parse event: {error}"); continue; } Err(_err) => { - // println!("error parsing event: {}", ErrorReporter(err)); continue; } }; @@ -342,12 +341,12 @@ impl Module { packet_hash_param: H256, max_wait: Duration, ) -> anyhow::Result { - println!("Waiting for packet recv event with hash: {packet_hash_param:?}"); + info!("Waiting for packet recv event with hash: {packet_hash_param:?}"); Ok(self .wait_for_event( move |evt| { if let ModuleEvent::WasmPacketRecv { packet_hash, .. } = evt { - println!("Packet recv event came with hash: {packet_hash:?}"); + info!("Packet recv event came with hash: {packet_hash:?}"); if packet_hash.as_ref() == packet_hash_param.as_ref() { return Some(helpers::PacketRecv { packet_hash: *packet_hash, @@ -398,12 +397,12 @@ impl Module { packet_hash_param: H256, max_wait: Duration, ) -> anyhow::Result { - println!("Waiting for packet timeout event with hash: {packet_hash_param:?}"); + info!("Waiting for packet timeout event with hash: {packet_hash_param:?}"); Ok(self .wait_for_event( move |evt| { if let ModuleEvent::WasmPacketTimeout { packet_hash, .. } = evt { - println!("Packet timeout event came with hash: {packet_hash:?}"); + info!("Packet timeout event came with hash: {packet_hash:?}"); if packet_hash.as_ref() == packet_hash_param.as_ref() { return Some(helpers::PacketTimeout { packet_hash: *packet_hash, @@ -427,7 +426,7 @@ impl Module { packet_hash_param: H256, max_wait: Duration, ) -> anyhow::Result { - println!("Waiting for packet ack event with hash: {packet_hash_param:?}"); + info!("Waiting for packet ack event with hash: {packet_hash_param:?}"); Ok(self .wait_for_event( move |evt| { @@ -495,7 +494,6 @@ impl Module { Ok(self .wait_for_event( move |evt| { - println!("EVT is: {:?}", evt); if let ModuleEvent::WithdrawRewards { validator, amount } = evt { if validator == &validator_filter { Some(helpers::WithdrawRewards { @@ -720,6 +718,33 @@ impl Module { Some(outcome) } + pub async fn unstake( + &self, + validator_address: String, + amount: u128, + signer: &LocalSigner, + ) -> Option> { + let tx_client = TxClient::new(signer, &self.rpc, &self.gas_config); + + let signer_address = signer.address(); + let outcome = tx_client + .broadcast_tx_commit( + [mk_any(&protos::cosmos::staking::v1beta1::MsgUndelegate { + delegator_address: signer_address.to_string(), + validator_address, + amount: Some(Coin { + denom: "muno".to_string(), + amount: amount.to_string(), + }), + })], + "memo", + true, + ) + .await; + + Some(outcome) + } + /// Helper to detect the ABCI “account sequence mismatch” error. fn is_sequence_mismatch(&self, err: &BroadcastTxCommitError) -> bool { match err { diff --git a/tools/union-test/src/evm.rs b/tools/union-test/src/evm.rs index 3780ac6de6..2907759df4 100644 --- a/tools/union-test/src/evm.rs +++ b/tools/union-test/src/evm.rs @@ -175,9 +175,7 @@ impl Module { }; for log in logs { if let Ok(ibc_event) = IbcEvents::decode_log(&log.inner) { - println!("Decoded IBC event: {:?}", ibc_event); if let Some(event) = filter_fn(ibc_event.data) { - println!("Event found: {:?}", event); events.push(event); } } @@ -535,7 +533,6 @@ impl Module { fn is_nonce_too_low(&self, e: &Error) -> bool { if let Error::TransportError(TransportError::ErrorResp(rpc)) = e { - println!("Nonce is too low, error entered here.: {:?}", rpc); rpc.message.contains("nonce too low") || rpc.message.contains("replacement transaction underpriced") } else { @@ -579,13 +576,10 @@ impl Module { match pending { Ok(pending) => { let tx_hash = ::from(*pending.tx_hash()); - println!("pending: {:?}", pending); self.wait_for_tx_inclusion(&provider, tx_hash).await?; - println!("Approved spender: {spender:?} for amount: {amount:?} on contract: {contract:?}"); return Ok(tx_hash); } Err(err) if attempts <= 5 && self.is_nonce_too_low(&err) => { - println!("Nonce too low, retrying... Attempt: {attempts}"); tokio::time::sleep(Duration::from_secs(10)).await; continue; } @@ -613,13 +607,10 @@ impl Module { match pending { Ok(pending) => { let tx_hash = ::from(*pending.tx_hash()); - println!("pending: {:?}", pending); self.wait_for_tx_inclusion(&provider, tx_hash).await?; - println!("Approved spender: {spender:?} for token_id: {token_id:?} on contract: {contract:?}"); return Ok(tx_hash); } Err(err) if attempts <= 5 && self.is_nonce_too_low(&err) => { - println!("Nonce too low, retrying... Attempt: {attempts}"); tokio::time::sleep(Duration::from_secs(10)).await; continue; } @@ -704,7 +695,6 @@ impl Module { return Ok(address.into()); } Err(err) if attempts <= 5 && self.is_nonce_too_low(&err) => { - println!("Nonce too low, retrying... Attempt: {attempts}"); tokio::time::sleep(Duration::from_secs(10)).await; continue; } @@ -795,14 +785,10 @@ impl Module { price: gas_price, }); } else { - println!("gas price: {}", gas_price); } } - println!("submitting evm tx"); - let gas_estimate = call.estimate_gas().await.map_err(|e| { - println!("error estimating gas: {:?}", e); if ErrorReporter(&e) .to_string() .contains("gas required exceeds") @@ -814,10 +800,6 @@ impl Module { })?; let gas_to_use = ((gas_estimate as f64) * self.gas_multiplier) as u64; - println!( - "gas estimate: {gas_estimate}, gas to use: {gas_to_use}, gas multiplier: {}", - self.gas_multiplier - ); if let Some(fixed) = self.fixed_gas_price { call = call.gas_price(fixed); @@ -828,7 +810,6 @@ impl Module { let tx_hash = ::from(*ok.tx_hash()); async move { self.wait_for_tx_inclusion(&self.provider, tx_hash).await?; - println!("tx included: {:?}", tx_hash); Ok(tx_hash) } @@ -883,11 +864,9 @@ impl Module { Ok(pending) => { let tx_hash = ::from(*pending.tx_hash()); self.wait_for_tx_inclusion(&provider, tx_hash).await?; - println!("migrateV1ToV2 executed, tx_hash = {tx_hash:?}"); return Ok(tx_hash); } Err(err) if attempts <= 5 && self.is_nonce_too_low(&err) => { - println!("nonce too low – retrying ({attempts}/5)"); tokio::time::sleep(Duration::from_secs(10)).await; continue; } @@ -962,18 +941,14 @@ impl Module { match pending { Ok(pending) => { let tx_hash = ::from(*pending.tx_hash()); - println!("pending: {:?}", pending); self.wait_for_tx_inclusion(&provider, tx_hash).await?; - println!("Registered governance token on channel {channel_id} with metadata image {metadata_image:?}"); return Ok(tx_hash); } Err(err) if attempts <= 10 && self.is_nonce_too_low(&err) => { - println!("Nonce too low, retrying... Attempt: {attempts}"); tokio::time::sleep(Duration::from_secs(10)).await; continue; } Err(err) => { - println!("Failed to register governance token: {:?}", err); return Err(err.into()); } } diff --git a/tools/union-test/tests/lst/bond.rs b/tools/union-test/tests/lst/bond.rs index 2664368123..bc31c2e42e 100644 --- a/tools/union-test/tests/lst/bond.rs +++ b/tools/union-test/tests/lst/bond.rs @@ -1,10 +1,17 @@ use std::time::Duration; use alloy::{network::AnyNetwork, primitives::Address, providers::DynProvider}; -use cosmwasm_std::{to_json_binary, Addr, Coin as CwCoin, CosmosMsg, Decimal, WasmMsg}; -use lst::msg::{AccountingStateResponse, ExecuteMsg as LstExecuteMsg}; +use cosmwasm_std::{ + to_json_binary, Addr, Binary, Coin as CwCoin, CosmosMsg, Decimal, Uint128, WasmMsg, +}; +use cw20::Cw20ExecuteMsg; +use lst::{ + msg::{AccountingStateResponse, Batch, BatchesResponse, ExecuteMsg as LstExecuteMsg}, + types::{BatchId, PendingBatch}, +}; use rand::RngCore; -use tracing::info; +use serde::{de::DeserializeOwned, Serialize}; +use tracing::{info, warn}; use union_test::{ cosmos::{self}, cosmos_helpers::calculate_proxy_address, @@ -15,6 +22,7 @@ use union_test::{ zkgm_helper, }; use unionlabs::primitives::U256; +use voyager_sdk::serde_json; use crate::lst::*; @@ -23,6 +31,21 @@ use crate::lst::*; // u: union1pntx7gm7shsp6slef74ae7wvcc35t3wdmanh7wrg4xkq95m24qds5atmcp // lst: union1fdg764zzxwvwyqkx3fuj0236l9ddh5xmutgvj2mv9cduffy82z9sp62ygc +fn make_proxy_call(funded_msgs: &[(&str, Binary, Vec)]) -> Vec { + let wasm_msgs: Vec = funded_msgs + .into_iter() + .map(|(contract, msg, funds)| { + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: contract.to_string(), + msg: msg.clone(), + funds: funds.clone(), + }) + }) + .collect(); + + serde_json::to_vec(&wasm_msgs).expect("vec cosmosmsg json") +} + fn make_zkgm_bond_payload_via_call( lst_hub: &str, mint_to: &str, @@ -30,20 +53,57 @@ fn make_zkgm_bond_payload_via_call( funds_denom: &str, funds_amount: u128, ) -> Vec { - let wasm_exec: CosmosMsg = CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: lst_hub.to_string(), - msg: to_json_binary(&LstExecuteMsg::Bond { + make_proxy_call(&[( + lst_hub, + to_json_binary(&LstExecuteMsg::Bond { mint_to_address: Addr::unchecked(mint_to), min_mint_amount: min_mint_amount.into(), }) .unwrap(), - funds: vec![CwCoin { + vec![CwCoin { denom: funds_denom.to_string(), amount: funds_amount.into(), }], - }); + )]) +} - voyager_sdk::serde_json::to_vec(&vec![wasm_exec]).expect("vec cosmosmsg json") +fn make_zkgm_unbond_payload_via_call(cw20_token: &str, lst_hub: &str, amount: u128) -> Vec { + make_proxy_call(&[ + ( + cw20_token, + to_json_binary(&Cw20ExecuteMsg::IncreaseAllowance { + spender: lst_hub.to_string(), + amount: amount.into(), + expires: None, + }) + .unwrap(), + Vec::new(), + ), + ( + lst_hub, + to_json_binary(&LstExecuteMsg::Unbond { + amount: amount.into(), + }) + .unwrap(), + Vec::new(), + ), + ]) +} + +fn make_zkgm_withdraw_payload_via_call( + lst_hub: &str, + withdraw_to_address: Addr, + batch_id: BatchId, +) -> Vec { + make_proxy_call(&[( + lst_hub, + to_json_binary(&LstExecuteMsg::Withdraw { + withdraw_to_address, + batch_id, + }) + .unwrap(), + Vec::new(), + )]) } async fn bond( @@ -132,19 +192,161 @@ async fn bond( assert_eq!(ack.tag, TAG_ACK_SUCCESS); } -async fn get_accounting_state(t: &LstContext) -> anyhow::Result { - t.ctx - .src - .query_wasm_smart::<_, AccountingStateResponse>( - t.union_address.lst_hub.clone(), - lst::msg::QueryMsg::AccountingState {}, +async fn unbond( + t: &LstContext, + channel_id_on_eth: u32, + channel_id_on_union: u32, + sender_on_evm: Address, + sender_evm_provider: DynProvider, + unbond_amount: u128, +) { + let proxy_address_on_union = calculate_proxy_address( + &t.union_address.zkgm, + alloy::primitives::U256::ZERO, + channel_id_on_union, + sender_on_evm.as_ref(), + ); + + let mut salt_bytes = [0u8; 32]; + rand::thread_rng().fill_bytes(&mut salt_bytes); + + let ucs03_zkgm = UCS03Zkgm::new(ETH_ADDRESS_ZKGM.into(), sender_evm_provider.clone()); + + let call = ucs03_zkgm + .send( + channel_id_on_eth, + 0u64, + 4294967295000000000u64, + salt_bytes.into(), + InstructionEvm::from(zkgm_helper::make_call( + sender_on_evm.to_vec().into(), + proxy_address_on_union.as_bytes().to_vec().into(), + make_zkgm_unbond_payload_via_call( + t.union_address.eu.as_str(), + t.union_address.lst_hub.as_str(), + unbond_amount, + ) + .into(), + )), + ) + .clear_decoder() + .with_cloned_provider(); + + let (_, ack) = t + .ctx + .send_and_recv_and_ack_with_retry::( + &t.ctx.dst, + ETH_ADDRESS_ZKGM.into(), + call, + &t.ctx.src, + 6, + Duration::from_secs(10), + Duration::from_secs(720), + &sender_evm_provider, + ) + .await + .unwrap(); + + assert_eq!(ack.tag, TAG_ACK_SUCCESS); +} + +async fn withdraw( + t: &LstContext, + channel_id_on_eth: u32, + channel_id_on_union: u32, + sender_on_evm: Address, + sender_evm_provider: DynProvider, + batch_id: BatchId, +) { + let proxy_address_on_union = calculate_proxy_address( + &t.union_address.zkgm, + alloy::primitives::U256::ZERO, + channel_id_on_union, + sender_on_evm.as_ref(), + ); + + let mut salt_bytes = [0u8; 32]; + rand::thread_rng().fill_bytes(&mut salt_bytes); + + let ucs03_zkgm = UCS03Zkgm::new(ETH_ADDRESS_ZKGM.into(), sender_evm_provider.clone()); + + let call = ucs03_zkgm + .send( + channel_id_on_eth, + 0u64, + 4294967295000000000u64, + salt_bytes.into(), + InstructionEvm::from(zkgm_helper::make_call( + sender_on_evm.to_vec().into(), + proxy_address_on_union.as_bytes().to_vec().into(), + make_zkgm_withdraw_payload_via_call( + t.union_address.lst_hub.as_str(), + proxy_address_on_union.clone(), + batch_id, + ) + .into(), + )), + ) + .clear_decoder() + .with_cloned_provider(); + + let (_, ack) = t + .ctx + .send_and_recv_and_ack_with_retry::( + &t.ctx.dst, + ETH_ADDRESS_ZKGM.into(), + call, + &t.ctx.src, + 6, + Duration::from_secs(10), + Duration::from_secs(720), + &sender_evm_provider, ) .await + .unwrap(); + + assert_eq!(ack.tag, TAG_ACK_SUCCESS); +} + +async fn query_lst_hub( + t: &LstContext, + query: Q, +) -> anyhow::Result { + loop { + match t + .ctx + .src + .query_wasm_smart::<_, Res>(t.union_address.lst_hub.clone(), query.clone()) + .await + { + Ok(state) => break Ok(state), + Err(_) => { + warn!("the query didn't work for some reason, will retry in a sec."); + tokio::time::sleep(Duration::from_secs(1)).await; + } + } + } +} + +async fn get_batch_by_id(t: &LstContext, id: BatchId) -> anyhow::Result { + Ok( + query_lst_hub::<_, Option>(t, lst::msg::QueryMsg::Batch { batch_id: id }) + .await? + .unwrap(), + ) +} + +async fn get_pending_batch(t: &LstContext) -> anyhow::Result { + query_lst_hub(t, lst::msg::QueryMsg::PendingBatch {}).await +} + +async fn get_accounting_state(t: &LstContext) -> anyhow::Result { + query_lst_hub(t, lst::msg::QueryMsg::AccountingState {}).await } #[tokio::test] async fn test_bond_success() { - run_test_in_queue("bond", async |t| { + run_test_in_queue("bond", async |t, mut shared_data| { // ensure_channels_opened(ctx.channel_count).await; // let available_channel = ctx.get_available_channel_count().await; // assert!(available_channel > 0); @@ -170,6 +372,8 @@ async fn test_bond_success() { t.ctx.dst.get_provider().await, ]; + shared_data.stakers = evm_signers.to_vec(); + for (bond_amount, evm_signer) in bonds.into_iter().zip(evm_signers) { let (evm_address, evm_provider): (Address, DynProvider) = evm_signer; let (min_mint_amount, bond_amount) = bond_amount; @@ -238,17 +442,211 @@ async fn test_bond_success() { assert_eq!(outcome.tx_result.code, Code::Ok); } + // we are making sure that the 2 mins ubonding time passes, while making sure that the + // rate continues to go down since more and more rewards will be earned with new blocks. let mut prev_rate = Decimal::MAX; - for i in 1..10 { - tokio::time::sleep(Duration::from_secs(10)).await; - + for i in 1..8 { let new_rate = get_accounting_state(&t).await.unwrap().purchase_rate; + + tokio::time::sleep(Duration::from_secs(15)).await; + info!("checking the rate ({i}).. new_rate: {new_rate} prev_rate: {prev_rate}"); assert!(new_rate < prev_rate); prev_rate = new_rate; } + + shared_data + }) + .await; +} + +#[tokio::test] +async fn test_unbond_success() { + run_test_in_queue("unbond", async |t, shared_data| { + let dst_channel_id = 1; + let src_channel_id = 1; + + let unbond_amounts = [30, 40]; + + let mut total_unbond_amount = 0; + + for (amount, staker) in unbond_amounts.into_iter().zip(&shared_data.stakers) { + unbond( + &t, + dst_channel_id, + src_channel_id, + staker.0, + staker.1.clone(), + amount, + ) + .await; + + // we are unbonding twice so that the `is_new_request` can be triggered + // and we test that case as well + unbond( + &t, + dst_channel_id, + src_channel_id, + staker.0, + staker.1.clone(), + amount, + ) + .await; + + total_unbond_amount += amount * 2; + } + + let k = t + .ctx + .src + .privileged_acc_keyring + .with(async |k| k) + .await + .unwrap(); + + let outcome = t + .ctx + .src + .unstake( + "unionvaloper1qp4uzhet2sd9mrs46kemse5dt9ncz4k3xuz7ej".to_string(), + total_unbond_amount, + k, + ) + .await + .unwrap() + .unwrap(); + + assert_eq!(outcome.tx_result.code, Code::Ok); + + let (_, signer) = t.ctx.src.get_signer().await; + + let state = get_accounting_state(&t).await.unwrap(); + let outcome = t + .ctx + .src + .send_cosmwasm_transaction( + t.union_address.lst_hub.clone(), + ( + to_json_binary(&LstExecuteMsg::SubmitBatch {}) + .unwrap() + .into(), + vec![], + ), + &signer, + ) + .await + .unwrap() + .unwrap(); + + assert_eq!(outcome.tx_result.code, Code::Ok); + + let new_state = get_accounting_state(&t).await.unwrap(); + + // We burned exactly the `total_unbond_amount` of eU's + assert_eq!( + total_unbond_amount, + state.total_shares.u128() - new_state.total_shares.u128() + ); + + shared_data + }) + .await; +} + +#[tokio::test] +async fn test_withdraw_success() { + run_test_in_queue("withdraw", async |t, shared_data| { + let dst_channel_id = 1; + let src_channel_id = 1; + + let unbond_amounts = [60u128, 80]; + + let (_, signer) = t.ctx.src.get_signer().await; + + let pending_batch = get_pending_batch(&t).await.unwrap(); + let submitted_batch_id = BatchId::from_raw(pending_batch.batch_id.get().get() - 1).unwrap(); + + let Batch::Submitted(submitted_batch) = + get_batch_by_id(&t, submitted_batch_id).await.unwrap() + else { + panic!("expected submitted batch"); + }; + + let fund_amount = submitted_batch.expected_native_unstaked; + + let outcome = t + .ctx + .src + .send_cosmwasm_transaction( + t.union_address.lst_hub.clone(), + ( + to_json_binary(&LstExecuteMsg::ReceiveUnstakedTokens { + batch_id: submitted_batch_id, + }) + .unwrap() + .into(), + vec![ProtoCoin { + denom: "muno".to_string(), + amount: fund_amount.to_string(), + }], + ), + &signer, + ) + .await + .unwrap() + .unwrap(); + + assert_eq!(outcome.tx_result.code, Code::Ok); + + // Now the batch turns into `Received` since we actually received it + let Batch::Received(received_batch) = + get_batch_by_id(&t, submitted_batch_id).await.unwrap() + else { + panic!("expected received batch"); + }; + + for (amount, staker) in unbond_amounts.into_iter().zip(&shared_data.stakers) { + let proxy_address = calculate_proxy_address( + &t.union_address.zkgm, + alloy::primitives::U256::ZERO, + src_channel_id, + staker.0.as_ref(), + ); + let u_balance_before = t + .ctx + .src + .native_balance(proxy_address.clone(), "muno") + .await + .unwrap(); + + withdraw( + &t, + dst_channel_id, + src_channel_id, + staker.0, + staker.1.clone(), + submitted_batch_id, + ) + .await; + + let u_balance_after = t + .ctx + .src + .native_balance(proxy_address, "muno") + .await + .unwrap(); + + assert_eq!( + u_balance_after - u_balance_before, + Uint128::new(received_batch.received_native_unstaked) + .multiply_ratio(amount, 140u128) + .u128() + ); + } + + shared_data }) .await; } diff --git a/tools/union-test/tests/lst/mod.rs b/tools/union-test/tests/lst/mod.rs index b3daa89c8a..976e54cdbe 100644 --- a/tools/union-test/tests/lst/mod.rs +++ b/tools/union-test/tests/lst/mod.rs @@ -1,5 +1,6 @@ -use std::{cell::RefCell, future::Future, sync::Arc, time::Duration}; +use std::{future::Future, sync::Arc, time::Duration}; +use alloy::{network::AnyNetwork, providers::DynProvider}; use alloy_sol_types::SolValue as _; use bip32::secp256k1::ecdsa::SigningKey; use cometbft_rpc::types::code::Code; @@ -29,7 +30,7 @@ use union_test::{ }; use unionlabs::{ encoding::{EncodeAs, Json}, - primitives::{H160, H256}, + primitives::H160, }; use voyager_sdk::{anyhow, serde_json}; @@ -64,11 +65,21 @@ pub struct Config { union_deployer_addr: String, } +#[derive(Clone)] +pub struct SharedData { + stakers: Vec<(alloy::primitives::Address, DynProvider)>, +} + pub struct Queue { tests: Vec, + shared_data: SharedData, } -async fn run_test_in_queue<'a, Fut: Future, F: Fn(Arc) -> Fut>( +async fn run_test_in_queue< + 'a, + Fut: Future, + F: Fn(Arc, SharedData) -> Fut, +>( key: &str, test_fn: F, ) { @@ -130,10 +141,11 @@ async fn run_test_in_queue<'a, Fut: Future, F: Fn(Arc) ( Mutex::new(Queue { tests: { - let mut t = vec!["bond".into()]; + let mut t = vec!["bond".into(), "unbond".into(), "withdraw".into()]; t.reverse(); t }, + shared_data: SharedData { stakers: vec![] }, }), Arc::new(LstContext { staker, @@ -166,7 +178,7 @@ async fn run_test_in_queue<'a, Fut: Future, F: Fn(Arc) { let mut lock = ctx.0.lock().await; if lock.tests.last().unwrap() == key { - test_fn(ctx.1.clone()).await; + lock.shared_data = test_fn(ctx.1.clone(), lock.shared_data.clone()).await; let _ = lock.tests.pop(); return; } From 1b72033e01e37c18277fab1d364fe61846e28016 Mon Sep 17 00:00:00 2001 From: aeryz Date: Fri, 26 Sep 2025 14:22:26 +0300 Subject: [PATCH 16/33] chore: bunch of cleanups Signed-off-by: aeryz --- Cargo.lock | 1 - cosmwasm/deployer/src/main.rs | 104 -- tools/union-test/Cargo.toml | 3 +- tools/union-test/tests/{lst => }/config.json | 0 tools/union-test/tests/e2e.rs | 977 ++++++++----------- tools/union-test/tests/lst/mod.rs | 177 +--- 6 files changed, 426 insertions(+), 836 deletions(-) rename tools/union-test/tests/{lst => }/config.json (100%) diff --git a/Cargo.lock b/Cargo.lock index 04aab58375..2b5b6125d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15399,7 +15399,6 @@ dependencies = [ "protos", "rand 0.6.5", "rand 0.8.5", - "rand_chacha 0.3.1", "regex", "serde", "serde-utils", diff --git a/cosmwasm/deployer/src/main.rs b/cosmwasm/deployer/src/main.rs index 97ff26454f..6615d4dc0a 100644 --- a/cosmwasm/deployer/src/main.rs +++ b/cosmwasm/deployer/src/main.rs @@ -92,31 +92,6 @@ enum App { #[command(flatten)] gas_config: GasFillerArgs, }, - DeployFungibleToken { - #[arg(long)] - rpc_url: String, - #[arg(long, env)] - private_key: H256, - #[arg(long)] - contract: PathBuf, - #[arg( - long, - // the autoref value parser selector chooses From before FromStr, but Value's From impl always returns Value::String(..), whereas FromStr actually parses the json contained within the string - value_parser(serde_json::Value::from_str), - )] - init_msg: Value, - #[arg(long)] - output: Option, - #[arg(long)] - salt: String, - /// Marks this chain as permissioned. - /// - /// Permisioned cosmwasm chains require special handling of instantiate permissions in order to deploy the stack. - #[arg(long)] - permissioned: bool, - #[command(flatten)] - gas_config: GasFillerArgs, - }, Instantiate2Address { #[arg(long)] deployer: Bech32, @@ -858,85 +833,6 @@ async fn do_main() -> Result<()> { write_output(output, contract_addresses)?; } - App::DeployFungibleToken { - rpc_url, - private_key, - contract, - init_msg, - output: _, - permissioned: _, - salt, - gas_config, - } => { - let ctx = Deployer::new(rpc_url, private_key, &gas_config).await?; - - let bytecode_base_address = ctx - .instantiate2_address(sha2(BYTECODE_BASE_BYTECODE), &BYTECODE_BASE) - .await?; - - let bytecode_base_contract = ctx.contract_info(&bytecode_base_address).await?; - - let bytecode_base_code_id = match bytecode_base_contract { - Some(_) => ctx - .instantiate_code_id_of_contract(bytecode_base_address) - .await? - .unwrap(), - // contract does not exist on chain - None => { - info!("bytecode-base has not yet been stored"); - - let (tx_hash, store_code_response) = ctx - .tx( - MsgStoreCode { - sender: ctx.wallet().address().map_data(Into::into), - wasm_byte_code: BYTECODE_BASE_BYTECODE.into(), - instantiate_permission: Some(AccessConfig::Everybody), - }, - "", - gas_config.simulate, - ) - .await - .context("store code")?; - - info!(%tx_hash, code_id = store_code_response.code_id, "stored bytecode-base"); - - let (tx_hash, instantiate_response) = ctx - .tx( - MsgInstantiateContract2 { - sender: ctx.wallet().address().map_data(Into::into), - admin: ctx.wallet().address().map_data(Into::into), - code_id: store_code_response.code_id, - label: BYTECODE_BASE.to_string(), - msg: b"{}".into(), - salt: BYTECODE_BASE.as_bytes().into(), - funds: vec![], - fix_msg: false, - }, - "", - gas_config.simulate, - ) - .await - .context("instantiate2")?; - - info!(%tx_hash, address = %instantiate_response.address, "instantiated bytecode-base"); - - store_code_response.code_id - } - }; - - info!("bytecode-base code_id is {bytecode_base_code_id}"); - - let address = ctx - .deploy_and_initiate( - std::fs::read(contract)?, - bytecode_base_code_id, - init_msg, - &Salt::Utf8(salt), - ) - .await?; - - info!("deployed at {address}"); - } App::Instantiate2Address { deployer, salt, diff --git a/tools/union-test/Cargo.toml b/tools/union-test/Cargo.toml index 3851d72165..a376f07169 100644 --- a/tools/union-test/Cargo.toml +++ b/tools/union-test/Cargo.toml @@ -44,8 +44,7 @@ once_cell = "1.17" serial_test = "0.5" tokio = { version = "1", features = ["macros", "rt"] } tracing-subscriber = "0.3" -rand = "0.6" -rand_chacha = "0.3.1" +rand = "0.6" [lints] diff --git a/tools/union-test/tests/lst/config.json b/tools/union-test/tests/config.json similarity index 100% rename from tools/union-test/tests/lst/config.json rename to tools/union-test/tests/config.json diff --git a/tools/union-test/tests/e2e.rs b/tools/union-test/tests/e2e.rs index 64d9c82084..d532391b18 100644 --- a/tools/union-test/tests/e2e.rs +++ b/tools/union-test/tests/e2e.rs @@ -1,6 +1,5 @@ use std::{ num::NonZero, - str::FromStr, sync::Arc, time::{Duration, SystemTime, UNIX_EPOCH}, }; @@ -9,13 +8,13 @@ use alloy::{ hex::decode as hex_decode, sol_types::{SolCall, SolValue}, }; -use concurrent_keyring::{KeyringConfig, KeyringConfigEntry}; -use cosmos::{FeemarketConfig, GasFillerConfig}; +use cosmwasm_std::Addr; use cw20::Cw20ExecuteMsg; use hex_literal::hex; use ibc_union_spec::ChannelId; use protos::cosmos::base::v1beta1::Coin; use rand::RngCore; +use serde::Deserialize; use tokio::sync::OnceCell; use ucs03_zkgm::{ self, @@ -27,6 +26,7 @@ use ucs03_zkgm::{ }; use union_test::{ cosmos::{self}, + cosmos_helpers::{calculate_cosmos_contract_address, SALT_ESCROW_VAULT, SALT_ZKGM}, evm::{ self, zkgm::{ @@ -39,165 +39,62 @@ use union_test::{ use unionlabs::{ encoding::{Encode, Json}, ethereum::keccak256, - primitives::{encoding::Base64, Bech32, Bytes, FixedBytes, H160, U256}, + primitives::{H160, U256}, }; -use voyager_sdk::{ - primitives::{ChainId, Timestamp}, - serde_json::json, -}; -static CTX: OnceCell>> = OnceCell::const_new(); +use voyager_sdk::{primitives::Timestamp, serde_json}; + +static CTX: OnceCell> = OnceCell::const_new(); static CHANNELS_OPENED: OnceCell<()> = OnceCell::const_new(); -// static ERC20: OnceCell = OnceCell::const_new(); -static UNION_ZKGM_ADDRESS: &str = - "union1rfz3ytg6l60wxk5rxsk27jvn2907cyav04sz8kde3xhmmf9nplxqr8y05c"; -// static UNION_MINTER_ADDRESS: &str = -// "union1tt6nn3qv0q0z4gq4s2h65a2acv3lcwxjwf8ey3jgnwmtqkfnyq9q4q5y8x"; -static EVM_ZKGM_BYTES: [u8; 20] = hex!("05fd55c1abe31d3ed09a76216ca8f0372f4b2ec5"); -static EVM_IBC_BYTES: [u8; 20] = hex!("ed2af2aD7FE0D92011b26A2e5D1B4dC7D12A47C5"); +pub const ETH_ADDRESS_U: H160 = H160::new(hex!("0c8C6f58156D10d18193A8fFdD853e1b9F8D8836")); +pub const ETH_ADDRESS_ZKGM: H160 = H160::new(hex!("05fd55c1abe31d3ed09a76216ca8f0372f4b2ec5")); +pub const ETH_ADDRESS_IBC: H160 = H160::new(hex!("ed2af2aD7FE0D92011b26A2e5D1B4dC7D12A47C5")); + +#[derive(Deserialize)] +pub struct Config { + evm: evm::Config, + union: cosmos::Config, + needed_channel_count: u32, + voyager_config_file_path: String, + union_deployer_addr: String, +} + +pub struct UnionAddressBook { + pub zkgm: Addr, + pub escrow_vault: Addr, +} + +pub struct ZkgmCtx { + pub union_address: UnionAddressBook, + pub ctx: TestContext, +} -async fn init_ctx<'a>() -> Arc>> { +async fn init_ctx() -> Arc { CTX.get_or_init(|| async { - let cosmos_cfg = cosmos::Config { - chain_id: ChainId::new("union-devnet-1"), - ibc_host_contract_address: Bech32::from_str( - "union1nk3nes4ef6vcjan5tz6stf9g8p08q2kgqysx6q5exxh89zakp0msq5z79t", + let cfg: Config = serde_json::from_str(include_str!("./config.json")).unwrap(); + + let src = cosmos::Module::new(cfg.union).await.unwrap(); + let dst = evm::Module::new(cfg.evm).await.unwrap(); + + let ctx = ZkgmCtx { + ctx: TestContext::new( + src, + dst, + cfg.needed_channel_count as usize, + &cfg.voyager_config_file_path, ) + .await .unwrap(), - privileged_acc_keyring: KeyringConfig { - name: "privileged_acc".into(), - keys: vec![KeyringConfigEntry::Raw { - name: "privileged_acc".into(), - key: hex!("aa820fa947beb242032a41b6dc9a8b9c37d8f5fbcda0966b1ec80335b10a7d6f") - .to_vec(), - }], - }, - keyring: KeyringConfig { - name: "alice".into(), - keys: vec![ - KeyringConfigEntry::Raw { - name: "bob".into(), - key: hex_literal::hex!( - "f562d20f0a4ffd8814d262f7023f33971cbcd14a96d60027585777f174b9cdeb" - ) - .to_vec(), - }, - KeyringConfigEntry::Raw { - name: "dave".into(), - key: hex_literal::hex!( - "edc165ff1ebc27044ddc284c9cf5da656dcbff324f6ecbb9d3203cf5f4738d6d" - ) - .to_vec(), - }, - KeyringConfigEntry::Raw { - name: "charlie".into(), - key: hex_literal::hex!( - "a1f713e0f36404586085a599a45ca8233e23709e23cd54bc8d5452ef8f7bc1e6" - ) - .to_vec(), - }, - ], - }, - rpc_url: "http://0.0.0.0:26657".into(), - gas_config: GasFillerConfig::Feemarket(FeemarketConfig { - max_gas: 10000000, - gas_multiplier: Some(1.4), - denom: None, - }), - fee_recipient: None, - }; - let evm_cfg = evm::Config { - chain_id: ChainId::new("32382"), - ibc_handler_address: hex!("ed2af2aD7FE0D92011b26A2e5D1B4dC7D12A47C5").into(), - multicall_address: hex!("84c4c2ee43ccfd523af9f78740256e0f60d38068").into(), - rpc_url: "http://0.0.0.0:8545".into(), - ws_url: "ws://0.0.0.0:8546".into(), - privileged_acc_keyring: KeyringConfig { - name: "zkgm-deployer".into(), - keys: vec![KeyringConfigEntry::Raw { - name: "zkgm-deployer-key".into(), - key: hex!("4e9444a6efd6d42725a250b650a781da2737ea308c839eaccb0f7f3dbd2fea77") - .to_vec(), - }], - }, - keyring: KeyringConfig { - name: "evm-keyring".into(), - keys: vec![ - KeyringConfigEntry::Raw { - name: "dev-key0.prv".into(), - key: hex!( - "4e9444a6efd6d42725a250b650a781da2737ea308c839eaccb0f7f3dbd2fea77" - ) - .to_vec(), - }, - // KeyringConfigEntry::Raw { - // name: "dev-key1.prv".into(), - // key: hex!( - // "d9c5dc47ed678fc3e63249953866d79e5cf48418e79d8eec1a985be7393ef3b9" - // ) - // .to_vec(), - // }, - // KeyringConfigEntry::Raw { - // name: "dev-key2.prv".into(), - // key: hex!( - // "eadf66c84a1c2768a14e883512724d6023a54d500bf91d910a7dace376a97d6b" - // ) - // .to_vec(), - // }, - // KeyringConfigEntry::Raw { - // name: "dev-key3.prv".into(), - // key: hex!( - // "d56f932b298ba86341037f3871141a707330316f6f9493641a2cd59ba4a53710" - // ) - // .to_vec(), - // }, - // KeyringConfigEntry::Raw { - // name: "dev-key4.prv".into(), - // key: hex!( - // "084494a1ff88a1319e493d32aa6e127ab0eaaaf74b8714edfd670a9ddc4a060d" - // ) - // .to_vec(), - // }, - // KeyringConfigEntry::Raw { - // name: "dev-key5.prv".into(), - // key: hex!( - // "f977996449841b13ce9bbb99873006e04590ddbe28d9cd449dd33505851e74ba" - // ) - // .to_vec(), - // }, - // KeyringConfigEntry::Raw { - // name: "dev-key6.prv".into(), - // key: hex!( - // "523776c0e15a5826c85f08e0dd20d70190b0001e87f6ff9f25854d10f24db63c" - // ) - // .to_vec(), - // }, - // KeyringConfigEntry::Raw { - // name: "dev-key7.prv".into(), - // key: hex!( - // "b7d500ecae3d26deaa9547557822c95208163e230cc04345bd223da99f5bd058" - // ) - // .to_vec(), - // }, - ], + union_address: UnionAddressBook { + zkgm: calculate_cosmos_contract_address(&cfg.union_deployer_addr, SALT_ZKGM) + .unwrap(), + escrow_vault: calculate_cosmos_contract_address( + &cfg.union_deployer_addr, + SALT_ESCROW_VAULT, + ) + .unwrap(), }, - max_gas_price: None, - fixed_gas_price: None, - gas_multiplier: 2.0, }; - let src = cosmos::Module::new(cosmos_cfg).await.unwrap(); - let dst = evm::Module::new(evm_cfg).await.unwrap(); - let needed_channel_count = 1; // TODO: Hardcoded now, it will be specified from config later. - - // TODO(aeryz): move config file into the testing framework's own config file - let ctx = TestContext::new( - src, - dst, - needed_channel_count, - "/home/kaancaglan/dev/union/voyager/config.jsonc", - ) - .await - .unwrap_or_else(|e| panic!("failed to build TestContext: {:#?}", e)); Arc::new(ctx) }) @@ -208,9 +105,10 @@ async fn init_ctx<'a>() -> Arc>> { async fn ensure_channels_opened(channel_count: usize) { CHANNELS_OPENED .get_or_init(|| async move { - let ctx = init_ctx().await; + let t = init_ctx().await; - let (src_client, dst_client) = ctx + let (src_client, dst_client) = t + .ctx .create_clients( Duration::from_secs(60), "ibc-cosmwasm", @@ -224,11 +122,12 @@ async fn ensure_channels_opened(channel_count: usize) { assert!(src_client.client_id > 0); assert!(dst_client.client_id > 0); - let conn = ctx + let conn = t + .ctx .open_connection::( - &ctx.src, + &t.ctx.src, src_client.client_id, - &ctx.dst, + &t.ctx.dst, dst_client.client_id, Duration::from_secs(180), ) @@ -237,13 +136,14 @@ async fn ensure_channels_opened(channel_count: usize) { assert!(conn.connection_id > 0); assert!(conn.counterparty_connection_id > 0); - let current_available_count = ctx.get_available_channel_count().await; + let current_available_count = t.ctx.get_available_channel_count().await; - let opened = ctx + let opened = t + .ctx .open_channels( true, - UNION_ZKGM_ADDRESS.as_bytes().into(), - EVM_ZKGM_BYTES.to_vec().into(), + t.union_address.zkgm.as_bytes().into(), + ETH_ADDRESS_ZKGM.into(), conn.counterparty_connection_id, "ucs03-zkgm-0".into(), channel_count, @@ -253,62 +153,33 @@ async fn ensure_channels_opened(channel_count: usize) { .unwrap(); assert_eq!(opened, channel_count); - let available_count_after_open = ctx.get_available_channel_count().await; + let available_count_after_open = t.ctx.get_available_channel_count().await; assert_eq!( current_available_count + channel_count, available_count_after_open ); - let pair = ctx.get_channel().await.expect("channel available"); - let available_count_after_get = ctx.get_available_channel_count().await; + let pair = t.ctx.get_channel().await.expect("channel available"); + let available_count_after_get = t.ctx.get_available_channel_count().await; assert_eq!(available_count_after_open - 1, available_count_after_get); - ctx.release_channel(pair).await; - let available_count_after_release = ctx.get_available_channel_count().await; + t.ctx.release_channel(pair).await; + let available_count_after_release = t.ctx.get_available_channel_count().await; assert_eq!(available_count_after_open, available_count_after_release); }) .await; } -async fn _open_connection_from_evm_to_union() { - let ctx = init_ctx().await; - let (src_client, dst_client) = ctx - .create_clients( - Duration::from_secs(45), - "ibc-cosmwasm", - "trusted/evm/mpt", - "ibc-solidity", - "cometbls", - ) - .await - .unwrap(); - - assert!(src_client.client_id > 0); - assert!(dst_client.client_id > 0); - - let conn = ctx - .open_connection::( - &ctx.dst, - dst_client.client_id, - &ctx.src, - src_client.client_id, - Duration::from_secs(180), - ) - .await - .unwrap(); - assert!(conn.connection_id > 0); - assert!(conn.counterparty_connection_id > 0); -} - +#[tokio::test] async fn test_send_vault_success() { - let ctx = init_ctx().await; + let t = init_ctx().await; - let (evm_address, evm_provider) = ctx.dst.get_provider().await; - let (cosmos_address, cosmos_provider) = ctx.src.get_signer().await; + let (evm_address, evm_provider) = t.ctx.dst.get_provider().await; + let (cosmos_address, cosmos_provider) = t.ctx.src.get_signer().await; let cosmos_address_bytes = cosmos_address.to_string().into_bytes(); - ensure_channels_opened(ctx.channel_count).await; - let available_channel = ctx.get_available_channel_count().await; + ensure_channels_opened(t.ctx.channel_count).await; + let available_channel = t.ctx.get_available_channel_count().await; assert!(available_channel > 0); - let pair = ctx.get_channel().await.expect("channel available"); + let pair = t.ctx.get_channel().await.expect("channel available"); let dst_channel_id = pair.dest; let src_channel_id = pair.src; @@ -340,8 +211,9 @@ async fn test_send_vault_success() { .into(), }; - let (_, zkgm_deployer_provider) = ctx.dst.get_provider_privileged().await; - ctx.dst + let (_, zkgm_deployer_provider) = t.ctx.dst.get_provider_privileged().await; + t.ctx + .dst .u_register_fungible_counterpart( H160::from(u_on_eth), zkgm_deployer_provider.clone(), @@ -372,9 +244,8 @@ async fn test_send_vault_success() { amount: "10".into(), }]; - let contract: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); - - let initial_u_balance = ctx + let initial_u_balance = t + .ctx .dst .zkgmerc20_balance_of( H160::from(u_on_eth), @@ -384,21 +255,23 @@ async fn test_send_vault_success() { .await .unwrap(); - let initial_vault_balance = ctx + let initial_vault_balance = t + .ctx .src - .native_balance(Bech32::from_str(vault_on_union).unwrap(), "muno") + .native_balance(t.union_address.escrow_vault.clone(), "muno") .await .unwrap(); println!("initial U balance on eth: {initial_u_balance}"); println!("initial U balance on union vault: {initial_vault_balance}"); - let ack_packet_data = ctx + let ack_packet_data = t + .ctx .send_and_recv_and_ack_with_retry::( - &ctx.src, - contract, + &t.ctx.src, + t.union_address.zkgm.clone(), (bin_msg, funds), - &ctx.dst, + &t.ctx.dst, 3, Duration::from_secs(20), Duration::from_secs(720), @@ -411,19 +284,17 @@ async fn test_send_vault_success() { ack_packet_data.err() ); - let new_u_balance = ctx + let new_u_balance = t + .ctx .dst - .zkgmerc20_balance_of( - H160::from(u_on_eth), - evm_address.into(), - evm_provider.clone(), - ) + .zkgmerc20_balance_of(ETH_ADDRESS_U, evm_address.into(), evm_provider.clone()) .await .unwrap(); - let new_vault_balance = ctx + let new_vault_balance = t + .ctx .src - .native_balance(Bech32::from_str(vault_on_union).unwrap(), "muno") + .native_balance(t.union_address.escrow_vault.clone(), "muno") .await .unwrap(); @@ -434,17 +305,18 @@ async fn test_send_vault_success() { assert_eq!(new_vault_balance - initial_vault_balance, 10); } +#[tokio::test] async fn test_send_vault_success_with_fee() { - let ctx = init_ctx().await; + let t = init_ctx().await; - let (evm_address, evm_provider) = ctx.dst.get_provider().await; - let (cosmos_address, cosmos_provider) = ctx.src.get_signer().await; + let (evm_address, evm_provider) = t.ctx.dst.get_provider().await; + let (cosmos_address, cosmos_provider) = t.ctx.src.get_signer().await; let cosmos_address_bytes = cosmos_address.to_string().into_bytes(); - ensure_channels_opened(ctx.channel_count).await; - let available_channel = ctx.get_available_channel_count().await; + ensure_channels_opened(t.ctx.channel_count).await; + let available_channel = t.ctx.get_available_channel_count().await; assert!(available_channel > 0); - let pair = ctx.get_channel().await.expect("channel available"); + let pair = t.ctx.get_channel().await.expect("channel available"); let dst_channel_id = pair.dest; let src_channel_id = pair.src; @@ -477,8 +349,9 @@ async fn test_send_vault_success_with_fee() { .into(), }; - let (_, zkgm_deployer_provider) = ctx.dst.get_provider_privileged().await; - ctx.dst + let (_, zkgm_deployer_provider) = t.ctx.dst.get_provider_privileged().await; + t.ctx + .dst .u_register_fungible_counterpart( H160::from(u_on_eth), zkgm_deployer_provider.clone(), @@ -509,27 +382,24 @@ async fn test_send_vault_success_with_fee() { amount: "15".into(), // So fee will be 5 and will be minted to relayer }]; - let contract: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); - - let initial_u_balance = ctx + let initial_u_balance = t + .ctx .dst - .zkgmerc20_balance_of(H160::from(u_on_eth), recv_addr.into(), evm_provider.clone()) + .zkgmerc20_balance_of(ETH_ADDRESS_U, recv_addr.into(), evm_provider.clone()) .await .unwrap(); - let initial_vault_balance = ctx + let initial_vault_balance = t + .ctx .src - .native_balance(Bech32::from_str(vault_on_union).unwrap(), "muno") + .native_balance(t.union_address.escrow_vault.clone(), "muno") .await .unwrap(); - let initial_balance_of_relayer = ctx + let initial_balance_of_relayer = t + .ctx .dst - .zkgmerc20_balance_of( - H160::from(u_on_eth), - evm_address.into(), - evm_provider.clone(), - ) + .zkgmerc20_balance_of(ETH_ADDRESS_U, evm_address.into(), evm_provider.clone()) .await .unwrap(); @@ -537,12 +407,13 @@ async fn test_send_vault_success_with_fee() { println!("initial U balance on union vault: {initial_vault_balance}"); println!("initial balance of relayer: {initial_balance_of_relayer}"); - let ack_packet_data = ctx + let ack_packet_data = t + .ctx .send_and_recv_and_ack_with_retry::( - &ctx.src, - contract, + &t.ctx.src, + t.union_address.zkgm.clone(), (bin_msg, funds), - &ctx.dst, + &t.ctx.dst, 3, Duration::from_secs(20), Duration::from_secs(720), @@ -555,19 +426,22 @@ async fn test_send_vault_success_with_fee() { ack_packet_data.err() ); - let new_u_balance = ctx + let new_u_balance = t + .ctx .dst - .zkgmerc20_balance_of(H160::from(u_on_eth), recv_addr.into(), evm_provider.clone()) + .zkgmerc20_balance_of(ETH_ADDRESS_U, recv_addr.into(), evm_provider.clone()) .await .unwrap(); - let new_vault_balance = ctx + let new_vault_balance = t + .ctx .src - .native_balance(Bech32::from_str(vault_on_union).unwrap(), "muno") + .native_balance(t.union_address.escrow_vault.clone(), "muno") .await .unwrap(); - let new_balance_of_relayer = ctx + let new_balance_of_relayer = t + .ctx .dst .zkgmerc20_balance_of( H160::from(u_on_eth), @@ -589,25 +463,27 @@ async fn test_send_vault_success_with_fee() { ); } +#[tokio::test] async fn test_send_packet_from_union_to_evm_and_send_back_unwrap() { - let ctx = init_ctx().await; - ensure_channels_opened(ctx.channel_count).await; + let t = init_ctx().await; + ensure_channels_opened(t.ctx.channel_count).await; - let (evm_address, evm_provider) = ctx.dst.get_provider().await; - let (cosmos_address, cosmos_provider) = ctx.src.get_signer().await; + let (evm_address, evm_provider) = t.ctx.dst.get_provider().await; + let (cosmos_address, cosmos_provider) = t.ctx.src.get_signer().await; let cosmos_address_bytes = cosmos_address.to_string().into_bytes(); - let available_channel = ctx.get_available_channel_count().await; + let available_channel = t.ctx.get_available_channel_count().await; assert!(available_channel > 0); - let pair = ctx.get_channel().await.expect("channel available"); + let pair = t.ctx.get_channel().await.expect("channel available"); let dst_chain_id = pair.dest; let src_chain_id = pair.src; - let quote_token_addr = ctx + let quote_token_addr = t + .ctx .predict_wrapped_token::( - &ctx.dst, - EVM_ZKGM_BYTES.into(), + &t.ctx.dst, + ETH_ADDRESS_ZKGM.into(), ChannelId::new(NonZero::new(dst_chain_id).unwrap()), "muno".into(), &evm_provider, @@ -617,7 +493,6 @@ async fn test_send_packet_from_union_to_evm_and_send_back_unwrap() { let mut salt_bytes = [0u8; 32]; rand::thread_rng().fill_bytes(&mut salt_bytes); - let contract: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); let instruction_cosmos = Instruction { version: INSTR_VERSION_1, @@ -652,12 +527,13 @@ async fn test_send_packet_from_union_to_evm_and_send_back_unwrap() { amount: "10".into(), }]; - let recv_packet_data = ctx + let recv_packet_data = t + .ctx .send_and_recv_with_retry::( - &ctx.src, - contract, + &t.ctx.src, + t.union_address.zkgm.clone(), (bin_msg, funds), - &ctx.dst, + &t.ctx.dst, 3, Duration::from_secs(20), Duration::from_secs(720), @@ -693,7 +569,7 @@ async fn test_send_packet_from_union_to_evm_and_send_back_unwrap() { println!("quote_token: {:?}", quote_token_addr); - let ucs03_zkgm = UCS03Zkgm::new(EVM_ZKGM_BYTES.into(), evm_provider.clone()); + let ucs03_zkgm = UCS03Zkgm::new(ETH_ADDRESS_ZKGM.into(), evm_provider.clone()); let call = ucs03_zkgm .send( @@ -703,14 +579,16 @@ async fn test_send_packet_from_union_to_evm_and_send_back_unwrap() { salt_bytes.into(), instruction_from_evm_to_union.clone(), ) - .clear_decoder(); + .clear_decoder() + .with_cloned_provider(); - let recv_packet_data = ctx + let recv_packet_data = t + .ctx .send_and_recv_with_retry::( - &ctx.dst, - EVM_ZKGM_BYTES.into(), + &t.ctx.dst, + ETH_ADDRESS_ZKGM.into(), call, - &ctx.src, + &t.ctx.src, 3, Duration::from_secs(20), Duration::from_secs(720), @@ -727,37 +605,38 @@ async fn test_send_packet_from_union_to_evm_and_send_back_unwrap() { ); } +#[tokio::test] async fn test_send_packet_from_evm_to_union_and_send_back_unwrap() { - let ctx = init_ctx().await; - let (evm_address, evm_provider) = ctx.dst.get_provider().await; - let (cosmos_address, cosmos_signer) = ctx.src.get_signer().await; + let t = init_ctx().await; + let (evm_address, evm_provider) = t.ctx.dst.get_provider().await; + let (cosmos_address, cosmos_signer) = t.ctx.src.get_signer().await; let cosmos_address_bytes = cosmos_address.to_string().into_bytes(); println!("EVM Address: {:?}", evm_address); println!("Cosmos Address: {:?}", cosmos_address); - ensure_channels_opened(ctx.channel_count).await; - let available_channel = ctx.get_available_channel_count().await; + ensure_channels_opened(t.ctx.channel_count).await; + let available_channel = t.ctx.get_available_channel_count().await; assert!(available_channel > 0); - let pair = ctx.get_channel().await.expect("channel available"); + let pair = t.ctx.get_channel().await.expect("channel available"); let dst_chain_id = pair.dest; let src_chain_id = pair.src; // let deployed_erc20 = ensure_erc20(EVM_ZKGM_BYTES.into()).await; - let deployed_erc20 = ctx + let deployed_erc20 = t + .ctx .dst - .deploy_basic_erc20(EVM_ZKGM_BYTES.into(), evm_provider.clone()) + .deploy_basic_erc20(ETH_ADDRESS_ZKGM.into(), evm_provider.clone()) .await .expect("failed to deploy ERC20"); - let union_zkgm_contract: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); - - let quote_token_addr = ctx + let quote_token_addr = t + .ctx .predict_wrapped_token::( - &ctx.src, - union_zkgm_contract, + &t.ctx.src, + t.union_address.zkgm.clone(), ChannelId::new(NonZero::new(src_chain_id).unwrap()), deployed_erc20.as_ref().to_vec(), cosmos_signer, @@ -792,7 +671,7 @@ async fn test_send_packet_from_evm_to_union_and_send_back_unwrap() { .into(), }; - let ucs03_zkgm = UCS03Zkgm::new(EVM_ZKGM_BYTES.into(), evm_provider.clone()); + let ucs03_zkgm = UCS03Zkgm::new(ETH_ADDRESS_ZKGM.into(), evm_provider.clone()); let call = ucs03_zkgm .send( @@ -802,14 +681,16 @@ async fn test_send_packet_from_evm_to_union_and_send_back_unwrap() { salt_bytes.into(), instruction_from_evm_to_union.clone(), ) - .clear_decoder(); + .clear_decoder() + .with_cloned_provider(); - let recv_packet_data: Result = ctx + let recv_packet_data: Result = t + .ctx .send_and_recv_with_retry::( - &ctx.dst, - EVM_ZKGM_BYTES.into(), + &t.ctx.dst, + ETH_ADDRESS_ZKGM.into(), call, - &ctx.src, + &t.ctx.src, 3, Duration::from_secs(20), Duration::from_secs(720), @@ -827,9 +708,10 @@ async fn test_send_packet_from_evm_to_union_and_send_back_unwrap() { recv_packet_data ); - let get_minter_result = ctx + let get_minter_result = t + .ctx .src - .get_minter(Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap()) + .get_minter(t.union_address.zkgm.clone()) .await .expect("failed to get minter address"); @@ -843,14 +725,18 @@ async fn test_send_packet_from_evm_to_union_and_send_back_unwrap() { let quote_token_bytes = hex_decode(quote_token_addr.trim_start_matches("0x")) .expect("invalid quote‐token address hex"); - let approve_contract: Bech32> = - Bech32::from_str(std::str::from_utf8("e_token_bytes).unwrap()).unwrap(); + let approve_contract = Addr::unchecked(str::from_utf8("e_token_bytes).unwrap()); println!("Calling approve on quote tokenbytes: {:?}, quote_token:{:?} -> from account: {:?}. Approve contract: {:?}", quote_token_addr, quote_token_bytes, cosmos_address, approve_contract); - let approve_recv_packet_data = ctx + let approve_recv_packet_data = t + .ctx .src - .send_transaction_with_retry(approve_contract, (approve_msg_bin, vec![]), cosmos_signer) + .send_cosmwasm_transaction_with_retry( + approve_contract, + (approve_msg_bin, vec![]), + cosmos_signer, + ) .await; // println!("Approve transaction data: {:?}", approve_recv_packet_data); @@ -889,14 +775,14 @@ async fn test_send_packet_from_evm_to_union_and_send_back_unwrap() { let bin_msg: Vec = Encode::::encode(&cw_msg); let funds = vec![]; - let union_zkgm_contract: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); - let recv_packet_data = ctx + let recv_packet_data = t + .ctx .send_and_recv_with_retry::( - &ctx.src, - union_zkgm_contract, + &t.ctx.src, + t.union_address.zkgm.clone(), (bin_msg, funds), - &ctx.dst, + &t.ctx.dst, 3, Duration::from_secs(20), Duration::from_secs(720), @@ -913,25 +799,27 @@ async fn test_send_packet_from_evm_to_union_and_send_back_unwrap() { ); } +#[tokio::test] async fn test_send_packet_from_union_to_evm_get_refund() { - let ctx = init_ctx().await; + let t = init_ctx().await; - let (evm_address, evm_provider) = ctx.dst.get_provider().await; - let (cosmos_address, cosmos_provider) = ctx.src.get_signer().await; + let (evm_address, evm_provider) = t.ctx.dst.get_provider().await; + let (cosmos_address, cosmos_provider) = t.ctx.src.get_signer().await; let cosmos_address_bytes = cosmos_address.to_string().into_bytes(); - ensure_channels_opened(ctx.channel_count).await; - let available_channel = ctx.get_available_channel_count().await; + ensure_channels_opened(t.ctx.channel_count).await; + let available_channel = t.ctx.get_available_channel_count().await; assert!(available_channel > 0); - let pair = ctx.get_channel().await.expect("channel available"); + let pair = t.ctx.get_channel().await.expect("channel available"); let dst_chain_id = pair.dest; let src_chain_id = pair.src; - let quote_token_addr = ctx + let quote_token_addr = t + .ctx .predict_wrapped_token::( - &ctx.dst, - EVM_ZKGM_BYTES.into(), + &t.ctx.dst, + ETH_ADDRESS_ZKGM.into(), ChannelId::new(NonZero::new(dst_chain_id).unwrap()), "muno".into(), &evm_provider, @@ -943,7 +831,6 @@ async fn test_send_packet_from_union_to_evm_get_refund() { let mut salt_bytes = [0u8; 32]; rand::thread_rng().fill_bytes(&mut salt_bytes); - let contract: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); let sending_amount = "9999999999999999999999"; let instruction_cosmos = Instruction { version: INSTR_VERSION_1, @@ -989,7 +876,8 @@ async fn test_send_packet_from_union_to_evm_get_refund() { amount: sending_amount.into(), }]; - let muno_balance_before_send = ctx + let muno_balance_before_send = t + .ctx .src .get_balance(&cosmos_address.clone().to_string(), "muno") .await; @@ -1005,12 +893,13 @@ async fn test_send_packet_from_union_to_evm_get_refund() { old_balance ); - let recv_packet_data = ctx + let recv_packet_data = t + .ctx .send_and_recv_refund_with_timeout::( - &ctx.src, - contract, + &t.ctx.src, + t.union_address.zkgm.clone(), (bin_msg, funds), - &ctx.dst, + &t.ctx.dst, Duration::from_secs(1720), cosmos_provider, ) @@ -1026,7 +915,8 @@ async fn test_send_packet_from_union_to_evm_get_refund() { recv_packet_data ); - let muno_balance_after_send = ctx + let muno_balance_after_send = t + .ctx .src .get_balance(&cosmos_address.clone().to_string(), "muno") .await; @@ -1049,37 +939,38 @@ async fn test_send_packet_from_union_to_evm_get_refund() { // new_balance, old_balance - sending_amount.into()); } +#[tokio::test] async fn test_send_packet_from_evm_to_union_get_refund() { - let ctx = init_ctx().await; - let (evm_address, evm_provider) = ctx.dst.get_provider().await; - let (cosmos_address, cosmos_signer) = ctx.src.get_signer().await; + let t = init_ctx().await; + let (evm_address, evm_provider) = t.ctx.dst.get_provider().await; + let (cosmos_address, cosmos_signer) = t.ctx.src.get_signer().await; println!("EVM Address: {:?}", evm_address); println!("Cosmos Address: {:?}", cosmos_address); - ensure_channels_opened(ctx.channel_count).await; + ensure_channels_opened(t.ctx.channel_count).await; - let available_channel = ctx.get_available_channel_count().await; + let available_channel = t.ctx.get_available_channel_count().await; assert!(available_channel > 0); - let pair = ctx.get_channel().await.expect("channel available"); + let pair = t.ctx.get_channel().await.expect("channel available"); let dst_chain_id = pair.dest; let src_chain_id = pair.src; // let deployed_erc20 = ensure_erc20(EVM_ZKGM_BYTES.into()).await; - let deployed_erc20 = ctx + let deployed_erc20 = t + .ctx .dst - .deploy_basic_erc20(EVM_ZKGM_BYTES.into(), evm_provider.clone()) + .deploy_basic_erc20(ETH_ADDRESS_ZKGM.into(), evm_provider.clone()) .await .expect("failed to deploy ERC20"); - let union_zkgm_contract: Bech32> = Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(); - - let quote_token_addr = ctx + let quote_token_addr = t + .ctx .predict_wrapped_token::( - &ctx.src, - union_zkgm_contract, + &t.ctx.src, + t.union_address.zkgm.clone(), ChannelId::new(NonZero::new(src_chain_id).unwrap()), deployed_erc20.as_ref().to_vec(), cosmos_signer, @@ -1115,7 +1006,8 @@ async fn test_send_packet_from_evm_to_union_get_refund() { .into(), }; - let erc20_balance_before_send = ctx + let erc20_balance_before_send = t + .ctx .dst .zkgmerc20_balance_of(deployed_erc20, evm_address.into(), evm_provider.clone()) .await; @@ -1130,7 +1022,7 @@ async fn test_send_packet_from_evm_to_union_get_refund() { evm_address, erc20_balance_before_send ); - let ucs03_zkgm = UCS03Zkgm::new(EVM_ZKGM_BYTES.into(), evm_provider.clone()); + let ucs03_zkgm = UCS03Zkgm::new(ETH_ADDRESS_ZKGM.into(), evm_provider.clone()); let call = ucs03_zkgm .send( @@ -1140,14 +1032,16 @@ async fn test_send_packet_from_evm_to_union_get_refund() { salt_bytes.into(), instruction_from_evm_to_union.clone(), ) - .clear_decoder(); + .clear_decoder() + .with_cloned_provider(); - let recv_packet_data = ctx + let recv_packet_data = t + .ctx .send_and_recv_refund::( - &ctx.dst, - EVM_ZKGM_BYTES.into(), + &t.ctx.dst, + ETH_ADDRESS_ZKGM.into(), call, - &ctx.src, + &t.ctx.src, Duration::from_secs(720), &evm_provider, ) @@ -1163,7 +1057,8 @@ async fn test_send_packet_from_evm_to_union_get_refund() { recv_packet_data ); - let erc20_balance_after_send = ctx + let erc20_balance_after_send = t + .ctx .dst .zkgmerc20_balance_of(deployed_erc20, evm_address.into(), evm_provider.clone()) .await; @@ -1185,18 +1080,19 @@ async fn test_send_packet_from_evm_to_union_get_refund() { ); } +#[tokio::test] async fn test_from_evm_to_union_tokenv2_unhappy_only_maker_err() { - let ctx = init_ctx().await; + let t = init_ctx().await; - let (evm_address, _evm_provider) = ctx.dst.get_provider().await; - let (cosmos_address, cosmos_provider) = ctx.src.get_signer().await; + let (evm_address, _evm_provider) = t.ctx.dst.get_provider().await; + let (cosmos_address, cosmos_provider) = t.ctx.src.get_signer().await; let cosmos_address_bytes = cosmos_address.to_string().into_bytes(); println!("EVM Address: {:?}", evm_address); - ensure_channels_opened(ctx.channel_count).await; - let available_channel = ctx.get_available_channel_count().await; + ensure_channels_opened(t.ctx.channel_count).await; + let available_channel = t.ctx.get_available_channel_count().await; assert!(available_channel > 0); - let pair = ctx.get_channel().await.expect("channel available"); + let pair = t.ctx.get_channel().await.expect("channel available"); let img_metadata = ucs03_zkgm::com::TokenMetadata { implementation: hex!("999709eB04e8A30C7aceD9fd920f7e04EE6B97bA") @@ -1204,7 +1100,7 @@ async fn test_from_evm_to_union_tokenv2_unhappy_only_maker_err() { .into(), initializer: ZkgmERC20::initializeCall { _authority: hex!("6C1D11bE06908656D16EBFf5667F1C45372B7c89").into(), - _minter: EVM_ZKGM_BYTES.into(), + _minter: ETH_ADDRESS_ZKGM.into(), _name: "muno".into(), _symbol: "muno".into(), _decimals: 6u8, @@ -1214,7 +1110,7 @@ async fn test_from_evm_to_union_tokenv2_unhappy_only_maker_err() { } .abi_encode_params(); - let (zkgm_deployer_address, zkgm_deployer_provider) = ctx.dst.get_provider_privileged().await; + let (zkgm_deployer_address, zkgm_deployer_provider) = t.ctx.dst.get_provider_privileged().await; let mut salt_bytes = [0u8; 32]; rand::thread_rng().fill_bytes(&mut salt_bytes); @@ -1267,12 +1163,13 @@ async fn test_from_evm_to_union_tokenv2_unhappy_only_maker_err() { amount: "10".into(), }]; - let height = ctx + let height = t + .ctx .send_and_get_height::( - &ctx.src, - Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(), + &t.ctx.src, + t.union_address.zkgm.clone(), (bin_msg, funds), - &ctx.dst, + &t.ctx.dst, Duration::from_secs(720), cosmos_provider, ) @@ -1303,9 +1200,10 @@ async fn test_from_evm_to_union_tokenv2_unhappy_only_maker_err() { timeoutTimestamp: 4294967295000000000, }]; - let proof = ctx + let proof = t + .ctx .calculate_proof::( - &ctx.dst, + &t.ctx.dst, pair.src, pair.dest, encoded_packet, @@ -1330,15 +1228,18 @@ async fn test_from_evm_to_union_tokenv2_unhappy_only_maker_err() { proofHeight: height, }; - let ibc = IBC::new(EVM_IBC_BYTES.into(), zkgm_deployer_provider.clone()); - - let call = ibc.recvPacket(recv_packet_msg).clear_decoder(); + let ibc = IBC::new(ETH_ADDRESS_IBC.into(), zkgm_deployer_provider.clone()); + let call = ibc + .recvPacket(recv_packet_msg) + .clear_decoder() + .with_cloned_provider(); let expected_revert_code = 0x3717ba2c; // Only maker - let recv_packet_data = ctx + let recv_packet_data = t + .ctx .send_and_expect_revert::( - &ctx.dst, - EVM_IBC_BYTES.into(), + &t.ctx.dst, + ETH_ADDRESS_IBC.into(), call, expected_revert_code, &zkgm_deployer_provider, @@ -1352,18 +1253,19 @@ async fn test_from_evm_to_union_tokenv2_unhappy_only_maker_err() { ); } +#[tokio::test] async fn test_from_evm_to_union_tokenv2_unhappy_err_invalid_unescrow() { - let ctx = init_ctx().await; + let t = init_ctx().await; - let (evm_address, evm_provider) = ctx.dst.get_provider().await; - let (cosmos_address, cosmos_provider) = ctx.src.get_signer().await; + let (evm_address, evm_provider) = t.ctx.dst.get_provider().await; + let (cosmos_address, cosmos_provider) = t.ctx.src.get_signer().await; let cosmos_address_bytes = cosmos_address.to_string().into_bytes(); println!("EVM Address: {:?}", evm_address); - ensure_channels_opened(ctx.channel_count).await; - let available_channel = ctx.get_available_channel_count().await; + ensure_channels_opened(t.ctx.channel_count).await; + let available_channel = t.ctx.get_available_channel_count().await; assert!(available_channel > 0); - let pair = ctx.get_channel().await.expect("channel available"); + let pair = t.ctx.get_channel().await.expect("channel available"); let img_metadata = ucs03_zkgm::com::TokenMetadata { implementation: hex!("999709eB04e8A30C7aceD9fd920f7e04EE6B97bA") @@ -1371,7 +1273,7 @@ async fn test_from_evm_to_union_tokenv2_unhappy_err_invalid_unescrow() { .into(), initializer: ZkgmERC20::initializeCall { _authority: hex!("6C1D11bE06908656D16EBFf5667F1C45372B7c89").into(), - _minter: EVM_ZKGM_BYTES.into(), + _minter: ETH_ADDRESS_ZKGM.into(), _name: "muno".into(), _symbol: "muno".into(), _decimals: 6u8, @@ -1381,10 +1283,11 @@ async fn test_from_evm_to_union_tokenv2_unhappy_err_invalid_unescrow() { } .abi_encode_params(); - let (_zkgm_deployer_address, _zkgm_deployer_provider) = ctx.dst.get_provider_privileged().await; + let (_zkgm_deployer_address, _zkgm_deployer_provider) = + t.ctx.dst.get_provider_privileged().await; let img = keccak256(&img_metadata); - let (_, zkgm_deployer_provider) = ctx.dst.get_provider_privileged().await; + let (_, zkgm_deployer_provider) = t.ctx.dst.get_provider_privileged().await; // let governance_token = ctx // .dst // .setup_governance_token( @@ -1403,10 +1306,11 @@ async fn test_from_evm_to_union_tokenv2_unhappy_err_invalid_unescrow() { let mut salt_bytes = [0u8; 32]; rand::thread_rng().fill_bytes(&mut salt_bytes); - let quote_token_addr = ctx + let quote_token_addr = t + .ctx .predict_wrapped_token_from_metadata_image_v2::( - &ctx.dst, - EVM_ZKGM_BYTES.into(), + &t.ctx.dst, + ETH_ADDRESS_ZKGM.into(), ChannelId::new(NonZero::new(pair.dest).unwrap()), "muno".into(), img, @@ -1449,12 +1353,13 @@ async fn test_from_evm_to_union_tokenv2_unhappy_err_invalid_unescrow() { amount: "10".into(), }]; - let recv_packet_data = ctx + let recv_packet_data = t + .ctx .send_and_recv_with_retry::( - &ctx.src, - Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(), + &t.ctx.src, + t.union_address.zkgm.clone(), (bin_msg, funds), - &ctx.dst, + &t.ctx.dst, 3, Duration::from_secs(20), Duration::from_secs(720), @@ -1474,11 +1379,12 @@ async fn test_from_evm_to_union_tokenv2_unhappy_err_invalid_unescrow() { quote_token_addr, evm_address ); - let approve_tx_hash = ctx + let approve_tx_hash = t + .ctx .dst .zkgmerc20_approve( quote_token_addr, - EVM_ZKGM_BYTES.into(), + ETH_ADDRESS_ZKGM.into(), U256::from(100000000000u64), evm_provider.clone(), ) @@ -1514,7 +1420,7 @@ async fn test_from_evm_to_union_tokenv2_unhappy_err_invalid_unescrow() { .into(), }; - let ucs03_zkgm = UCS03Zkgm::new(EVM_ZKGM_BYTES.into(), evm_provider.clone()); + let ucs03_zkgm = UCS03Zkgm::new(ETH_ADDRESS_ZKGM.into(), evm_provider.clone()); rand::thread_rng().fill_bytes(&mut salt_bytes); let call = ucs03_zkgm @@ -1525,13 +1431,15 @@ async fn test_from_evm_to_union_tokenv2_unhappy_err_invalid_unescrow() { salt_bytes.into(), instruction_from_evm_to_union.clone(), ) - .clear_decoder(); + .clear_decoder() + .with_cloned_provider(); let expected_revert_code = 0x96c99a39; // ErrChannelGovernanceTokenNotSet - let recv_packet_data = ctx + let recv_packet_data = t + .ctx .send_and_expect_revert::( - &ctx.dst, - EVM_ZKGM_BYTES.into(), + &t.ctx.dst, + ETH_ADDRESS_ZKGM.into(), call, expected_revert_code, &zkgm_deployer_provider, @@ -1545,18 +1453,19 @@ async fn test_from_evm_to_union_tokenv2_unhappy_err_invalid_unescrow() { ); } +#[tokio::test] async fn test_from_evm_to_union_tokenv2_unhappy_err_cannot_deploy() { - let ctx = init_ctx().await; + let t = init_ctx().await; - let (evm_address, evm_provider) = ctx.dst.get_provider().await; - let (cosmos_address, cosmos_provider) = ctx.src.get_signer().await; + let (evm_address, evm_provider) = t.ctx.dst.get_provider().await; + let (cosmos_address, cosmos_provider) = t.ctx.src.get_signer().await; let cosmos_address_bytes = cosmos_address.to_string().into_bytes(); println!("EVM Address: {:?}", evm_address); - ensure_channels_opened(ctx.channel_count).await; - let available_channel = ctx.get_available_channel_count().await; + ensure_channels_opened(t.ctx.channel_count).await; + let available_channel = t.ctx.get_available_channel_count().await; assert!(available_channel > 0); - let pair = ctx.get_channel().await.expect("channel available"); + let pair = t.ctx.get_channel().await.expect("channel available"); let img_metadata = ucs03_zkgm::com::TokenMetadata { implementation: hex!("999709eB04e8A30C7aceD9fd920f7e04EE6B97bA") @@ -1564,7 +1473,7 @@ async fn test_from_evm_to_union_tokenv2_unhappy_err_cannot_deploy() { .into(), initializer: ZkgmERC20::initializeCall { _authority: hex!("6C1D11bE06908656D16EBFf5667F1C45372B7c89").into(), - _minter: EVM_ZKGM_BYTES.into(), + _minter: ETH_ADDRESS_ZKGM.into(), _name: "muno".into(), _symbol: "muno".into(), _decimals: 6u8, @@ -1577,10 +1486,11 @@ async fn test_from_evm_to_union_tokenv2_unhappy_err_cannot_deploy() { let mut salt_bytes = [0u8; 32]; rand::thread_rng().fill_bytes(&mut salt_bytes); - let quote_token_addr = ctx + let quote_token_addr = t + .ctx .predict_wrapped_token::( - &ctx.dst, - EVM_ZKGM_BYTES.into(), + &t.ctx.dst, + ETH_ADDRESS_ZKGM.into(), ChannelId::new(NonZero::new(pair.dest).unwrap()), "muno".into(), &evm_provider, @@ -1619,12 +1529,13 @@ async fn test_from_evm_to_union_tokenv2_unhappy_err_cannot_deploy() { amount: "10".into(), }]; - let acked_packet = ctx + let acked_packet = t + .ctx .send_and_recv_ack::( - &ctx.src, - Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(), + &t.ctx.src, + t.union_address.zkgm.clone(), (bin_msg, funds), - &ctx.dst, + &t.ctx.dst, Duration::from_secs(720), cosmos_provider, ) @@ -1637,34 +1548,36 @@ async fn test_from_evm_to_union_tokenv2_unhappy_err_cannot_deploy() { ); let acked_packet = acked_packet.unwrap(); assert!( - acked_packet.tag == 0, + acked_packet.tag == alloy::primitives::U256::ZERO, "Packet is acked successfully, but it should not be. Tag: {:?}", acked_packet.tag ); } +#[tokio::test] async fn test_from_evm_to_union_batch_err_invalid_batch_instruction() { - let ctx = init_ctx().await; - let (evm_address, evm_provider) = ctx.dst.get_provider().await; - let (cosmos_address, _cosmos_signer) = ctx.src.get_signer().await; + let t = init_ctx().await; + let (evm_address, evm_provider) = t.ctx.dst.get_provider().await; + let (cosmos_address, _cosmos_signer) = t.ctx.src.get_signer().await; let cosmos_address_bytes = cosmos_address.to_string().into_bytes(); println!("EVM Address: {:?}", evm_address); println!("Cosmos Address: {:?}", cosmos_address); - ensure_channels_opened(ctx.channel_count).await; - let available_channel = ctx.get_available_channel_count().await; + ensure_channels_opened(t.ctx.channel_count).await; + let available_channel = t.ctx.get_available_channel_count().await; assert!(available_channel > 0); - let pair = ctx.get_channel().await.expect("channel available"); + let pair = t.ctx.get_channel().await.expect("channel available"); let dst_chain_id = pair.dest; let _src_chain_id = pair.src; // let deployed_erc20 = ensure_erc20(EVM_ZKGM_BYTES.into()).await; - let deployed_erc20 = ctx + let deployed_erc20 = t + .ctx .dst - .deploy_basic_erc20(EVM_ZKGM_BYTES.into(), evm_provider.clone()) + .deploy_basic_erc20(ETH_ADDRESS_ZKGM.into(), evm_provider.clone()) .await .expect("failed to deploy ERC20"); @@ -1701,7 +1614,7 @@ async fn test_from_evm_to_union_batch_err_invalid_batch_instruction() { operand: batch_operand.into(), }; - let ucs03_zkgm = UCS03Zkgm::new(EVM_ZKGM_BYTES.into(), evm_provider.clone()); + let ucs03_zkgm = UCS03Zkgm::new(ETH_ADDRESS_ZKGM.into(), evm_provider.clone()); let call = ucs03_zkgm .send( @@ -1711,14 +1624,16 @@ async fn test_from_evm_to_union_batch_err_invalid_batch_instruction() { salt_bytes.into(), instruction_from_evm_to_union.clone(), ) - .clear_decoder(); + .clear_decoder() + .with_cloned_provider(); - let (_, zkgm_deployer_provider) = ctx.dst.get_provider_privileged().await; + let (_, zkgm_deployer_provider) = t.ctx.dst.get_provider_privileged().await; let expected_revert_code = 0x746a20f8; // ErrInvalidBatchInstruction - let recv_packet_data = ctx + let recv_packet_data = t + .ctx .send_and_expect_revert::( - &ctx.dst, - EVM_ZKGM_BYTES.into(), + &t.ctx.dst, + ETH_ADDRESS_ZKGM.into(), call, expected_revert_code, &zkgm_deployer_provider, @@ -1732,26 +1647,28 @@ async fn test_from_evm_to_union_batch_err_invalid_batch_instruction() { ); } +#[tokio::test] async fn test_from_evm_to_union_batch_err_invalid_forward_instruction() { - let ctx = init_ctx().await; - let (evm_address, evm_provider) = ctx.dst.get_provider().await; - let (cosmos_address, _cosmos_signer) = ctx.src.get_signer().await; + let t = init_ctx().await; + let (evm_address, evm_provider) = t.ctx.dst.get_provider().await; + let (cosmos_address, _cosmos_signer) = t.ctx.src.get_signer().await; let cosmos_address_bytes = cosmos_address.to_string().into_bytes(); println!("EVM Address: {:?}", evm_address); println!("Cosmos Address: {:?}", cosmos_address); - ensure_channels_opened(ctx.channel_count).await; - let available_channel = ctx.get_available_channel_count().await; + ensure_channels_opened(t.ctx.channel_count).await; + let available_channel = t.ctx.get_available_channel_count().await; assert!(available_channel > 0); - let pair = ctx.get_channel().await.expect("channel available"); + let pair = t.ctx.get_channel().await.expect("channel available"); let dst_chain_id = pair.dest; let _src_chain_id: u32 = pair.src; - let deployed_erc20 = ctx + let deployed_erc20 = t + .ctx .dst - .deploy_basic_erc20(EVM_ZKGM_BYTES.into(), evm_provider.clone()) + .deploy_basic_erc20(ETH_ADDRESS_ZKGM.into(), evm_provider.clone()) .await .expect("failed to deploy ERC20"); @@ -1790,7 +1707,7 @@ async fn test_from_evm_to_union_batch_err_invalid_forward_instruction() { operand: forward_operand.into(), }; - let ucs03_zkgm = UCS03Zkgm::new(EVM_ZKGM_BYTES.into(), evm_provider.clone()); + let ucs03_zkgm = UCS03Zkgm::new(ETH_ADDRESS_ZKGM.into(), evm_provider.clone()); let call = ucs03_zkgm .send( @@ -1800,14 +1717,16 @@ async fn test_from_evm_to_union_batch_err_invalid_forward_instruction() { salt_bytes.into(), instruction_from_evm_to_union.clone(), ) - .clear_decoder(); + .clear_decoder() + .with_cloned_provider(); - let (_, zkgm_deployer_provider) = ctx.dst.get_provider_privileged().await; + let (_, zkgm_deployer_provider) = t.ctx.dst.get_provider_privileged().await; let expected_revert_code = 0x1dbb3218; // ErrInvalidForwardInstruction - let recv_packet_data = ctx + let recv_packet_data = t + .ctx .send_and_expect_revert::( - &ctx.dst, - EVM_ZKGM_BYTES.into(), + &t.ctx.dst, + ETH_ADDRESS_ZKGM.into(), call, expected_revert_code, &zkgm_deployer_provider, @@ -1821,17 +1740,18 @@ async fn test_from_evm_to_union_batch_err_invalid_forward_instruction() { ); } +#[tokio::test] async fn test_send_vault_unhappy_u_counterparty_is_not_fungible() { - let ctx = init_ctx().await; + let t = init_ctx().await; - let (evm_address, _evm_provider) = ctx.dst.get_provider().await; - let (cosmos_address, cosmos_provider) = ctx.src.get_signer().await; + let (evm_address, _evm_provider) = t.ctx.dst.get_provider().await; + let (cosmos_address, cosmos_provider) = t.ctx.src.get_signer().await; let cosmos_address_bytes = cosmos_address.to_string().into_bytes(); - ensure_channels_opened(ctx.channel_count).await; - let available_channel = ctx.get_available_channel_count().await; + ensure_channels_opened(t.ctx.channel_count).await; + let available_channel = t.ctx.get_available_channel_count().await; assert!(available_channel > 0); - let pair = ctx.get_channel().await.expect("channel available"); + let pair = t.ctx.get_channel().await.expect("channel available"); let dst_channel_id = pair.dest; let src_channel_id = pair.src; @@ -1879,9 +1799,10 @@ async fn test_send_vault_unhappy_u_counterparty_is_not_fungible() { .abi_encode_params() .into(), }; - let (zkgm_deployer_address, zkgm_deployer_provider) = ctx.dst.get_provider_privileged().await; + let (zkgm_deployer_address, zkgm_deployer_provider) = t.ctx.dst.get_provider_privileged().await; let empty_beneficiary = "".as_bytes().to_vec().into(); - ctx.dst + t.ctx + .dst .u_register_fungible_counterpart( H160::from(u_on_eth), zkgm_deployer_provider.clone(), @@ -1913,12 +1834,13 @@ async fn test_send_vault_unhappy_u_counterparty_is_not_fungible() { amount: "10".into(), }]; - let height = ctx + let height = t + .ctx .send_and_get_height::( - &ctx.src, - Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(), + &t.ctx.src, + t.union_address.zkgm.clone(), (bin_msg, funds), - &ctx.dst, + &t.ctx.dst, Duration::from_secs(720), cosmos_provider, ) @@ -1948,9 +1870,10 @@ async fn test_send_vault_unhappy_u_counterparty_is_not_fungible() { timeoutTimestamp: 4294967295000000000, }]; - let proof = ctx + let proof = t + .ctx .calculate_proof::( - &ctx.dst, + &t.ctx.dst, pair.src, pair.dest, encoded_packet, @@ -1975,15 +1898,18 @@ async fn test_send_vault_unhappy_u_counterparty_is_not_fungible() { proofHeight: height, }; - let ibc = IBC::new(EVM_IBC_BYTES.into(), zkgm_deployer_provider.clone()); - - let call = ibc.recvPacket(recv_packet_msg).clear_decoder(); + let ibc = IBC::new(ETH_ADDRESS_IBC.into(), zkgm_deployer_provider.clone()); + let call = ibc + .recvPacket(recv_packet_msg) + .clear_decoder() + .with_cloned_provider(); let expected_revert_code = 0x3717ba2c; // Only maker - let recv_packet_data = ctx + let recv_packet_data = t + .ctx .send_and_expect_revert::( - &ctx.dst, - EVM_IBC_BYTES.into(), + &t.ctx.dst, + ETH_ADDRESS_IBC.into(), call, expected_revert_code, &zkgm_deployer_provider, @@ -1997,17 +1923,18 @@ async fn test_send_vault_unhappy_u_counterparty_is_not_fungible() { ); } +#[tokio::test] async fn test_send_vault_unhappy_u_base_amount_must_cover_quote_amount() { - let ctx = init_ctx().await; + let t = init_ctx().await; - let (evm_address, _evm_provider) = ctx.dst.get_provider().await; - let (cosmos_address, cosmos_provider) = ctx.src.get_signer().await; + let (evm_address, _evm_provider) = t.ctx.dst.get_provider().await; + let (cosmos_address, cosmos_provider) = t.ctx.src.get_signer().await; let cosmos_address_bytes = cosmos_address.to_string().into_bytes(); - ensure_channels_opened(ctx.channel_count).await; - let available_channel = ctx.get_available_channel_count().await; + ensure_channels_opened(t.ctx.channel_count).await; + let available_channel = t.ctx.get_available_channel_count().await; assert!(available_channel > 0); - let pair = ctx.get_channel().await.expect("channel available"); + let pair = t.ctx.get_channel().await.expect("channel available"); let dst_channel_id = pair.dest; let src_channel_id = pair.src; @@ -2057,8 +1984,9 @@ async fn test_send_vault_unhappy_u_base_amount_must_cover_quote_amount() { .abi_encode_params() .into(), }; - let (zkgm_deployer_address, zkgm_deployer_provider) = ctx.dst.get_provider_privileged().await; - ctx.dst + let (zkgm_deployer_address, zkgm_deployer_provider) = t.ctx.dst.get_provider_privileged().await; + t.ctx + .dst .u_register_fungible_counterpart( H160::from(u_on_eth), zkgm_deployer_provider.clone(), @@ -2089,12 +2017,13 @@ async fn test_send_vault_unhappy_u_base_amount_must_cover_quote_amount() { amount: "10".into(), }]; - let height = ctx + let height = t + .ctx .send_and_get_height::( - &ctx.src, - Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(), + &t.ctx.src, + t.union_address.zkgm.clone(), (bin_msg, funds), - &ctx.dst, + &t.ctx.dst, Duration::from_secs(720), cosmos_provider, ) @@ -2124,9 +2053,10 @@ async fn test_send_vault_unhappy_u_base_amount_must_cover_quote_amount() { timeoutTimestamp: 4294967295000000000, }]; - let proof = ctx + let proof = t + .ctx .calculate_proof::( - &ctx.dst, + &t.ctx.dst, pair.src, pair.dest, encoded_packet, @@ -2151,15 +2081,19 @@ async fn test_send_vault_unhappy_u_base_amount_must_cover_quote_amount() { proofHeight: height, }; - let ibc = IBC::new(EVM_IBC_BYTES.into(), zkgm_deployer_provider.clone()); + let ibc = IBC::new(ETH_ADDRESS_IBC.into(), zkgm_deployer_provider.clone()); - let call = ibc.recvPacket(recv_packet_msg).clear_decoder(); + let call = ibc + .recvPacket(recv_packet_msg) + .clear_decoder() + .with_cloned_provider(); let expected_revert_code = 0x3717ba2c; // Only maker - let recv_packet_data = ctx + let recv_packet_data = t + .ctx .send_and_expect_revert::( - &ctx.dst, - EVM_IBC_BYTES.into(), + &t.ctx.dst, + ETH_ADDRESS_IBC.into(), call, expected_revert_code, &zkgm_deployer_provider, @@ -2173,17 +2107,18 @@ async fn test_send_vault_unhappy_u_base_amount_must_cover_quote_amount() { ); } +#[tokio::test] async fn test_send_vault_unhappy_u_fool() { - let ctx = init_ctx().await; + let t = init_ctx().await; - let (evm_address, _evm_provider) = ctx.dst.get_provider().await; - let (cosmos_address, cosmos_provider) = ctx.src.get_signer().await; + let (evm_address, _evm_provider) = t.ctx.dst.get_provider().await; + let (cosmos_address, cosmos_provider) = t.ctx.src.get_signer().await; let cosmos_address_bytes = cosmos_address.to_string().into_bytes(); - ensure_channels_opened(ctx.channel_count).await; - let available_channel = ctx.get_available_channel_count().await; + ensure_channels_opened(t.ctx.channel_count).await; + let available_channel = t.ctx.get_available_channel_count().await; assert!(available_channel > 0); - let pair = ctx.get_channel().await.expect("channel available"); + let pair = t.ctx.get_channel().await.expect("channel available"); let dst_channel_id = pair.dest; let src_channel_id = pair.src; @@ -2233,8 +2168,9 @@ async fn test_send_vault_unhappy_u_fool() { .abi_encode_params() .into(), }; - let (zkgm_deployer_address, zkgm_deployer_provider) = ctx.dst.get_provider_privileged().await; - ctx.dst + let (zkgm_deployer_address, zkgm_deployer_provider) = t.ctx.dst.get_provider_privileged().await; + t.ctx + .dst .u_register_fungible_counterpart( H160::from(u_on_eth), zkgm_deployer_provider.clone(), @@ -2265,12 +2201,13 @@ async fn test_send_vault_unhappy_u_fool() { amount: "10".into(), }]; - let height = ctx + let height = t + .ctx .send_and_get_height::( - &ctx.src, - Bech32::from_str(UNION_ZKGM_ADDRESS).unwrap(), + &t.ctx.src, + t.union_address.zkgm.clone(), (bin_msg, funds), - &ctx.dst, + &t.ctx.dst, Duration::from_secs(720), cosmos_provider, ) @@ -2300,9 +2237,10 @@ async fn test_send_vault_unhappy_u_fool() { timeoutTimestamp: 4294967295000000000, }]; - let proof = ctx + let proof = t + .ctx .calculate_proof::( - &ctx.dst, + &t.ctx.dst, pair.src, pair.dest, encoded_packet, @@ -2327,15 +2265,19 @@ async fn test_send_vault_unhappy_u_fool() { proofHeight: height, }; - let ibc = IBC::new(EVM_IBC_BYTES.into(), zkgm_deployer_provider.clone()); + let ibc = IBC::new(ETH_ADDRESS_IBC.into(), zkgm_deployer_provider.clone()); - let call = ibc.recvPacket(recv_packet_msg).clear_decoder(); + let call = ibc + .recvPacket(recv_packet_msg) + .clear_decoder() + .with_cloned_provider(); let expected_revert_code = 0x3717ba2c; // Only maker - let recv_packet_data = ctx + let recv_packet_data = t + .ctx .send_and_expect_revert::( - &ctx.dst, - EVM_IBC_BYTES.into(), + &t.ctx.dst, + ETH_ADDRESS_IBC.into(), call, expected_revert_code, &zkgm_deployer_provider, @@ -2348,74 +2290,3 @@ async fn test_send_vault_unhappy_u_fool() { recv_packet_data.err() ); } - -#[tokio::test] -async fn from_evm_to_union0() { - self::test_send_packet_from_evm_to_union_and_send_back_unwrap().await; -} - -#[tokio::test] -async fn from_evm_to_union_refund() { - self::test_send_packet_from_evm_to_union_get_refund().await; -} - -#[tokio::test] // Note: For this one to work; timeout plugin should be enabled on voyager. -async fn from_union_to_evm_refund() { - self::test_send_packet_from_union_to_evm_get_refund().await; -} - -#[tokio::test] -async fn from_union_to_evm0() { - self::test_send_packet_from_union_to_evm_and_send_back_unwrap().await; -} - -#[tokio::test] -async fn test_vault_works() { - self::test_send_vault_success().await; -} - -#[tokio::test] -async fn test_vault_works_with_fee() { - self::test_send_vault_success_with_fee().await; -} - -// UNHAPPY PATHS -#[tokio::test] -async fn from_evm_to_union_tokenv2_unhappy_path() { - self::test_from_evm_to_union_tokenv2_unhappy_only_maker_err().await; -} - -#[tokio::test] -async fn from_evm_to_union_tokenv2_unhappy_path4() { - self::test_from_evm_to_union_tokenv2_unhappy_err_invalid_unescrow().await; -} - -#[tokio::test] -async fn from_evm_to_union_tokenv2_unhappy_path5() { - self::test_from_evm_to_union_tokenv2_unhappy_err_cannot_deploy().await; -} - -#[tokio::test] -async fn from_evm_to_union_tokenv2_unhappy_path6() { - self::test_from_evm_to_union_batch_err_invalid_batch_instruction().await; -} - -#[tokio::test] -async fn from_evm_to_union_tokenv2_unhappy_path7() { - self::test_from_evm_to_union_batch_err_invalid_forward_instruction().await; -} - -#[tokio::test] -async fn test_send_vault_unhappy_path1() { - self::test_send_vault_unhappy_u_counterparty_is_not_fungible().await; -} - -#[tokio::test] -async fn test_send_vault_unhappy_path2() { - self::test_send_vault_unhappy_u_fool().await; -} - -#[tokio::test] -async fn test_send_vault_unhappy_path3() { - self::test_send_vault_unhappy_u_base_amount_must_cover_quote_amount().await; -} diff --git a/tools/union-test/tests/lst/mod.rs b/tools/union-test/tests/lst/mod.rs index 976e54cdbe..06559c5f43 100644 --- a/tools/union-test/tests/lst/mod.rs +++ b/tools/union-test/tests/lst/mod.rs @@ -9,10 +9,6 @@ use cosmwasm_std::Addr; use hex_literal::hex; use protos::cosmos::base::v1beta1::Coin as ProtoCoin; use rand::RngCore as _; -use rand_chacha::{ - rand_core::{block::BlockRng, SeedableRng}, - ChaChaCore, -}; use serde::Deserialize; use tokio::sync::{Mutex, OnceCell}; use tracing::info; @@ -52,7 +48,6 @@ pub struct UnionAddressBook { pub struct LstContext { pub union_address: UnionAddressBook, - pub staker: LocalSigner, pub ctx: TestContext, } @@ -90,7 +85,7 @@ async fn run_test_in_queue< .finish(); tracing::subscriber::set_global_default(subscriber) .expect("setting default subscriber failed"); - let cfg: Config = serde_json::from_str(include_str!("./config.json")).unwrap(); + let cfg: Config = serde_json::from_str(include_str!("../config.json")).unwrap(); let src = cosmos::Module::new(cfg.union).await.unwrap(); let dst = evm::Module::new(cfg.evm).await.unwrap(); @@ -104,40 +99,6 @@ async fn run_test_in_queue< .await .unwrap(); - let mut rng = - BlockRng::new(ChaChaCore::from_rng(rand_chacha::rand_core::OsRng).unwrap()); - - let staker = LocalSigner::new(SigningKey::random(&mut rng).to_bytes().into(), "union"); - - let k = ctx.src.keyring.with(async |k| k).await.unwrap(); - - if ctx - .src - .native_balance(Addr::unchecked(staker.address().to_string()), "muno") - .await - .unwrap() - < 90_000_000 - { - let outcome = ctx - .src - .send_transaction( - protos::cosmos::bank::v1beta1::MsgSend { - from_address: k.address().to_string(), - to_address: staker.address().to_string(), - amount: vec![ProtoCoin { - denom: "muno".to_string(), - amount: 100_000_000.to_string(), - }], - }, - k, - ) - .await - .unwrap() - .unwrap(); - - assert_eq!(outcome.tx_result.code, Code::Ok); - } - ( Mutex::new(Queue { tests: { @@ -148,7 +109,6 @@ async fn run_test_in_queue< shared_data: SharedData { stakers: vec![] }, }), Arc::new(LstContext { - staker, union_address: UnionAddressBook { zkgm: calculate_cosmos_contract_address( &cfg.union_deployer_addr, @@ -186,141 +146,6 @@ async fn run_test_in_queue< tokio::time::sleep(Duration::from_secs(2)).await; } } -// async fn init_ctx<'a>(key: &str) -> Arc { -// let ctx = CTX -// .get_or_init(|| async { -// let subscriber = FmtSubscriber::builder() -// .with_max_level(tracing::Level::INFO) -// .finish(); -// tracing::subscriber::set_global_default(subscriber) -// .expect("setting default subscriber failed"); -// let cfg: Config = serde_json::from_str(include_str!("./config.json")).unwrap(); - -// let src = cosmos::Module::new(cfg.union).await.unwrap(); -// let dst = evm::Module::new(cfg.evm).await.unwrap(); - -// let ctx = TestContext::new( -// src, -// dst, -// cfg.needed_channel_count as usize, -// &cfg.voyager_config_file_path, -// ) -// .await -// .unwrap(); - -// let mut rng = -// BlockRng::new(ChaChaCore::from_rng(rand_chacha::rand_core::OsRng).unwrap()); - -// ( -// Arc::new(Mutex::new(Queue { -// tests: vec!["first".into(), "second".into(), "third".into()], -// })), -// Arc::new(LstContext { -// staker: LocalSigner::new( -// SigningKey::random(&mut rng).to_bytes().into(), -// "union", -// ), -// union_address: UnionAddressBook { -// zkgm: calculate_cosmos_contract_address( -// &cfg.union_deployer_addr, -// SALT_ZKGM, -// ) -// .unwrap(), -// lst_hub: calculate_cosmos_contract_address( -// &cfg.union_deployer_addr, -// SALT_LST_HUB, -// ) -// .unwrap(), -// eu: calculate_cosmos_contract_address(&cfg.union_deployer_addr, SALT_EU) -// .unwrap(), -// escrow_vault: calculate_cosmos_contract_address( -// &cfg.union_deployer_addr, -// SALT_ESCROW_VAULT, -// ) -// .unwrap(), -// }, -// ctx, -// }), -// ) -// }) -// .await; - -// loop { -// { -// if ctx.0.lock().await.tests[0] == key { -// return ctx.1.clone(); -// } -// } - -// tokio::time::sleep(Duration::from_secs(1)).await -// } -// } - -// pub async fn ensure_channels_opened(channel_count: usize) { -// CHANNELS_OPENED -// .get_or_init(|| async move { -// let t = init_ctx().await; - -// let (src_client, dst_client) = t -// .ctx -// .create_clients( -// Duration::from_secs(60), -// "ibc-cosmwasm", -// "trusted/evm/mpt", -// "ibc-solidity", -// "cometbls", -// ) -// .await -// .unwrap(); - -// assert!(src_client.client_id > 0); -// assert!(dst_client.client_id > 0); - -// let conn = t -// .ctx -// .open_connection::( -// &t.ctx.src, -// src_client.client_id, -// &t.ctx.dst, -// dst_client.client_id, -// Duration::from_secs(180), -// ) -// .await -// .unwrap(); -// assert!(conn.connection_id > 0); -// assert!(conn.counterparty_connection_id > 0); - -// let current_available_count = t.ctx.get_available_channel_count().await; - -// let opened = t -// .ctx -// .open_channels( -// true, -// t.union_address.zkgm.as_bytes().into(), -// ETH_ADDRESS_ZKGM.into_bytes(), -// conn.counterparty_connection_id, -// "ucs03-zkgm-0".into(), -// channel_count, -// Duration::from_secs(360 * channel_count as u64), -// ) -// .await -// .unwrap(); -// assert_eq!(opened, channel_count); - -// let available_count_after_open = t.ctx.get_available_channel_count().await; -// assert_eq!( -// current_available_count + channel_count, -// available_count_after_open -// ); -// let pair = t.ctx.get_channel().await.expect("channel available"); -// let available_count_after_get = t.ctx.get_available_channel_count().await; -// assert_eq!(available_count_after_open - 1, available_count_after_get); -// t.ctx.release_channel(pair).await; -// let available_count_after_release = t.ctx.get_available_channel_count().await; -// assert_eq!(available_count_after_open, available_count_after_release); -// }) -// .await; -// } pub async fn eth_set_fungible_counterparty( module: &evm::Module, From 760b95b5e66e26c312220f631fc63c0c882d8ce2 Mon Sep 17 00:00:00 2001 From: aeryz Date: Thu, 2 Oct 2025 13:00:15 +0300 Subject: [PATCH 17/33] chore: moar Signed-off-by: aeryz --- e2e/all-tests.nix | 4 ++-- e2e/e2e.nix | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/e2e/all-tests.nix b/e2e/all-tests.nix index 3e93f99ccc..349033ae16 100644 --- a/e2e/all-tests.nix +++ b/e2e/all-tests.nix @@ -23,7 +23,7 @@ ... }: let - # full-e2e = import ./full-e2e.nix { inherit e2e pkgs; }; + full-e2e = import ./full-e2e.nix { inherit e2e pkgs; }; epoch-staking = import ./epoch-staking.nix { inherit e2e pkgs dbg; }; upgrades = import ./upgrades.nix { inherit e2e pkgs; @@ -37,7 +37,7 @@ # ensure-blocks = import ./ensure-blocks/ensure-blocks.nix { inherit e2e networks pkgs nixpkgs crane; }; # # Tests from ./full-e2e.nix - # inherit (full-e2e) all-works; + inherit (full-e2e) all-works; # Tests from ./epoch-staking.nix inherit (epoch-staking) epoch-completes; diff --git a/e2e/e2e.nix b/e2e/e2e.nix index 2a9133b657..f43d5f52cf 100644 --- a/e2e/e2e.nix +++ b/e2e/e2e.nix @@ -220,6 +220,15 @@ galois.wait_for_console_text('${galoisNode.wait_for_console_text}') + devnetVoyager.succeed('${voyagerBin} -c ${voyagerNode.voyagerConfig} msg create-client --on union-devnet-1 --tracking 32382 --ibc-interface ibc-cosmwasm --ibc-spec-id ibc-union --client-type trusted/evm/mpt -e') + devnetVoyager.succeed('${voyagerBin} -c ${voyagerNode.voyagerConfig} msg create-client --on 32382 --tracking union-devnet-1 --ibc-interface ibc-solidity --ibc-spec-id ibc-union --client-type cometbls -e') + + devnetVoyager.succeed( + "echo '{\"@type\":\"call\",\"@value\":{\"@type\":\"submit_tx\",\"@value\":{\"chain_id\":\"union-devnet-1\",\"datagrams\":[{\"ibc_spec_id\":\"ibc-union\",\"datagram\":{\"@type\":\"connection_open_init\",\"@value\":{\"client_id\":1,\"counterparty_client_id\":1}}}]}}}' > /tmp/payload.json" + ) + + devnetVoyager.succeed("${voyagerBin} -c ${voyagerNode.voyagerConfig} q e $(cat /tmp/payload.json)") + devnetUnion.wait_until_succeeds('[[ $(curl "http://localhost:26660/block" --fail --silent | ${pkgs.lib.meta.getExe pkgs.jq} ".result.block.header.height | tonumber > 200000") == "true" ]]') ''; From eca4d6c04f761fd5b1687847c1b1a99ac1b9c6f7 Mon Sep 17 00:00:00 2001 From: aeryz Date: Sat, 4 Oct 2025 10:13:03 +0300 Subject: [PATCH 18/33] chore: bunch of stuff Signed-off-by: aeryz --- Cargo.lock | 1114 +++------------------------------ Cargo.toml | 98 +-- e2e/e2e.nix | 35 +- tools/union-test/config.jsonc | 60 +- 4 files changed, 147 insertions(+), 1160 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2b5b6125d1..7075d2b274 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15750,61 +15750,6 @@ dependencies = [ "voyager-vm", ] -[[package]] -name = "voyager-client-bootstrap-module-arbitrum" -version = "0.0.0" -dependencies = [ - "alloy", - "arbitrum-client", - "arbitrum-light-client-types", - "embed-commit", - "ibc-union-spec", - "jsonrpsee 0.25.1", - "serde", - "serde_json", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-bootstrap-module-base" -version = "0.0.0" -dependencies = [ - "alloy", - "base-light-client-types", - "embed-commit", - "ibc-union-spec", - "jsonrpsee 0.25.1", - "serde", - "serde_json", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-bootstrap-module-bob" -version = "0.0.0" -dependencies = [ - "alloy", - "bob-client", - "bob-light-client-types", - "bob-types", - "bob-verifier", - "embed-commit", - "ibc-union-spec", - "jsonrpsee 0.25.1", - "serde", - "serde_json", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - [[package]] name = "voyager-client-bootstrap-module-cometbls" version = "0.0.0" @@ -15813,794 +15758,10 @@ dependencies = [ "cometbls-light-client-types", "embed-commit", "jsonrpsee 0.25.1", - "protos", - "serde", - "serde_json", - "thiserror 2.0.12", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-bootstrap-module-ethereum" -version = "0.0.0" -dependencies = [ - "alloy", - "beacon-api", - "beacon-api-types", - "embed-commit", - "ethereum-light-client-types", - "ethereum-sync-protocol-types", - "jsonrpsee 0.25.1", - "serde", - "serde_json", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-bootstrap-module-ethermint" -version = "0.0.0" -dependencies = [ - "cometbft-rpc", - "embed-commit", - "ethermint-light-client-types", - "ics23", - "jsonrpsee 0.25.1", - "prost 0.12.6", - "protos", - "serde", - "serde_json", - "tendermint-light-client-types", - "thiserror 2.0.12", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-bootstrap-module-parlia" -version = "0.0.0" -dependencies = [ - "alloy", - "embed-commit", - "ibc-union-spec", - "jsonrpsee 0.25.1", - "parlia-light-client-types", - "parlia-types", - "parlia-verifier", - "serde", - "serde_json", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-bootstrap-module-state-lens-ics23-ics23" -version = "0.0.0" -dependencies = [ - "alloy", - "beacon-api", - "beacon-api-types", - "cometbft-rpc", - "embed-commit", - "ibc-union-spec", - "jsonrpsee 0.25.1", - "serde", - "serde_json", - "state-lens-ics23-ics23-light-client-types", - "tendermint-light-client-types", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-bootstrap-module-state-lens-ics23-mpt" -version = "0.0.0" -dependencies = [ - "alloy", - "beacon-api", - "beacon-api-types", - "cometbft-rpc", - "embed-commit", - "ibc-union-spec", - "jsonrpsee 0.25.1", - "serde", - "serde_json", - "state-lens-ics23-mpt-light-client", - "state-lens-ics23-mpt-light-client-types", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-bootstrap-module-state-lens-ics23-smt" -version = "0.0.0" -dependencies = [ - "alloy", - "beacon-api", - "beacon-api-types", - "cometbft-rpc", - "embed-commit", - "ibc-union-spec", - "jsonrpsee 0.25.1", - "movement-light-client-types", - "serde", - "serde_json", - "state-lens-ics23-smt-light-client-types", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-bootstrap-module-sui" -version = "0.0.0" -dependencies = [ - "bcs", - "cosmwasm-std", - "embed-commit", - "hex-literal 0.4.1", - "jsonrpsee 0.25.1", - "reqwest 0.11.27", - "serde", - "serde_json", - "sui-light-client-types", - "sui-sdk", - "thiserror 2.0.12", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-bootstrap-module-tendermint" -version = "0.0.0" -dependencies = [ - "cometbft-rpc", - "embed-commit", - "ics23", - "jsonrpsee 0.25.1", - "protos", - "serde", - "serde_json", - "tendermint-light-client-types", - "thiserror 2.0.12", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-bootstrap-module-trusted-mpt" -version = "0.0.0" -dependencies = [ - "alloy", - "ed25519-dalek", - "embed-commit", - "jsonrpsee 0.25.1", - "serde", - "serde_json", - "tokio", - "tracing", - "trusted-mpt-light-client-types", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-module-arbitrum" -version = "0.0.0" -dependencies = [ - "arbitrum-light-client-types", - "embed-commit", - "ethereum-light-client-types", - "jsonrpsee 0.25.1", - "serde", - "serde_json", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-module-base" -version = "0.0.0" -dependencies = [ - "base-light-client-types", - "embed-commit", - "ethereum-light-client-types", - "jsonrpsee 0.25.1", - "serde", - "serde_json", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-module-bob" -version = "0.0.0" -dependencies = [ - "bob-light-client-types", - "embed-commit", - "ethereum-light-client-types", - "jsonrpsee 0.25.1", - "serde", - "serde_json", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-module-cometbls" -version = "0.0.0" -dependencies = [ - "alloy-sol-types", - "bcs", - "cometbls-light-client-types", - "embed-commit", - "gnark-key-parser", - "hex", - "hex-literal 0.4.1", - "jsonrpsee 0.25.1", - "macros", - "num-bigint 0.4.6", - "protos", - "serde", - "serde_json", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-module-ethereum" -version = "0.0.0" -dependencies = [ - "embed-commit", - "ethereum-light-client-types", - "jsonrpsee 0.25.1", - "serde", - "serde_json", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-module-ethermint" -version = "0.0.0" -dependencies = [ - "embed-commit", - "ethermint-light-client-types", - "jsonrpsee 0.25.1", - "macros", - "serde", - "serde_json", - "tendermint-light-client-types", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-module-parlia" -version = "0.0.0" -dependencies = [ - "embed-commit", - "ethereum-light-client-types", - "jsonrpsee 0.25.1", - "parlia-light-client-types", - "serde", - "serde_json", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-module-state-lens-ics23-ics23" -version = "0.0.0" -dependencies = [ - "alloy-sol-types", - "embed-commit", - "futures", - "jsonrpsee 0.25.1", - "macros", - "protos", - "serde", - "serde_json", - "state-lens-ics23-ics23-light-client-types", - "state-lens-light-client-types", - "thiserror 2.0.12", - "tokio", - "tracing", - "tracing-subscriber", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-module-state-lens-ics23-mpt" -version = "0.0.0" -dependencies = [ - "alloy-sol-types", - "beacon-api-types", - "embed-commit", - "enumorph", - "ethereum-light-client-types", - "futures", - "jsonrpsee 0.25.1", - "macros", - "prost 0.12.6", - "serde", - "serde-utils", - "serde_json", - "state-lens-ics23-mpt-light-client-types", - "state-lens-light-client-types", - "thiserror 2.0.12", - "tokio", - "tracing", - "tracing-subscriber", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-module-state-lens-ics23-smt" -version = "0.0.0" -dependencies = [ - "alloy-sol-types", - "embed-commit", - "enumorph", - "ethereum-light-client-types", - "futures", - "jsonrpsee 0.25.1", - "macros", - "prost 0.12.6", - "serde", - "serde-utils", - "serde_json", - "state-lens-ics23-smt-light-client-types", - "state-lens-light-client-types", - "thiserror 2.0.12", - "tokio", - "tracing", - "tracing-subscriber", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-module-sui" -version = "0.0.0" -dependencies = [ - "embed-commit", - "jsonrpsee 0.25.1", - "serde", - "serde_json", - "sui-light-client-types", - "thiserror 2.0.12", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-module-tendermint" -version = "0.0.0" -dependencies = [ - "embed-commit", - "jsonrpsee 0.25.1", - "macros", - "serde", - "serde_json", - "tendermint-light-client-types", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-module-trusted-mpt" -version = "0.0.0" -dependencies = [ - "embed-commit", - "ethereum-light-client-types", - "jsonrpsee 0.25.1", - "serde", - "serde_json", - "tokio", - "tracing", - "trusted-mpt-light-client-types", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-update-plugin-arbitrum" -version = "0.0.0" -dependencies = [ - "alloy", - "arbitrum-client", - "arbitrum-light-client-types", - "arbitrum-types", - "embed-commit", - "enumorph", - "ethereum-light-client-types", - "ibc-union-spec", - "jsonrpsee 0.25.1", - "macros", - "serde", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-update-plugin-base" -version = "0.0.0" -dependencies = [ - "alloy", - "base-client", - "base-light-client-types", - "base-verifier", - "bob-types", - "embed-commit", - "enumorph", - "ethereum-light-client-types", - "futures", - "ibc-union-spec", - "jsonrpsee 0.25.1", - "macros", - "serde", - "serde_json", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-update-plugin-berachain" -version = "0.0.0" -dependencies = [ - "alloy", - "beacon-api-types", - "berachain-light-client-types", - "cometbft-rpc", - "cometbft-types", - "dashmap 5.5.3", - "embed-commit", - "enumorph", - "ethereum-light-client-types", - "futures", - "ics23", - "jsonrpsee 0.25.1", - "macros", - "num-bigint 0.4.6", - "prost 0.12.6", - "protos", - "serde", - "serde_json", - "ssz", - "thiserror 2.0.12", - "tokio", - "tracing", - "tracing-subscriber", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-update-plugin-bob" -version = "0.0.0" -dependencies = [ - "alloy", - "bob-client", - "bob-light-client-types", - "bob-types", - "bob-verifier", - "embed-commit", - "enumorph", - "ethereum-light-client-types", - "futures", - "ibc-union-spec", - "jsonrpsee 0.25.1", - "macros", - "serde", - "serde_json", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-update-plugin-cometbls" -version = "0.0.0" -dependencies = [ - "cometbft-rpc", - "cometbft-types", - "cometbls-light-client-types", - "embed-commit", - "enumorph", - "galois-rpc", - "jsonrpsee 0.25.1", - "macros", - "num-bigint 0.4.6", - "serde", - "serde_json", - "subset-of", - "thiserror 2.0.12", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-update-plugin-ethereum" -version = "0.0.0" -dependencies = [ - "alloy", - "beacon-api", - "beacon-api-types", - "bitvec 1.0.1", - "embed-commit", - "enumorph", - "ethereum-light-client-types", - "ethereum-sync-protocol-types", - "futures", - "jsonrpsee 0.25.1", - "macros", - "serde", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-update-plugin-ethermint" -version = "0.0.0" -dependencies = [ - "cometbft-rpc", - "cometbft-types", - "embed-commit", - "enumorph", - "ethermint-light-client-types", - "jsonrpsee 0.25.1", - "macros", - "serde", - "serde_json", - "tendermint-light-client-types", - "thiserror 2.0.12", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-update-plugin-parlia" -version = "0.0.0" -dependencies = [ - "alloy", - "embed-commit", - "enumorph", - "ethereum-light-client-types", - "futures", - "ibc-union-spec", - "jsonrpsee 0.25.1", - "macros", - "parlia-light-client-types", - "parlia-types", - "parlia-verifier", - "serde", - "serde_json", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-update-plugin-state-lens" -version = "0.0.0" -dependencies = [ - "alloy", - "embed-commit", - "enumorph", - "ibc-union-spec", - "ics23", - "jsonrpsee 0.25.1", - "macros", - "protos", - "serde", - "serde_json", - "state-lens-light-client-types", - "tokio", - "tracing", - "tracing-subscriber", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-update-plugin-sui" -version = "0.0.0" -dependencies = [ - "bcs", - "embed-commit", - "enumorph", - "hex-literal 0.4.1", - "jsonrpsee 0.25.1", - "macros", - "reqwest 0.11.27", - "serde", - "serde_json", - "subset-of", - "sui-light-client-types", - "sui-sdk", - "thiserror 2.0.12", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-update-plugin-tendermint" -version = "0.0.0" -dependencies = [ - "cometbft-rpc", - "cometbft-types", - "embed-commit", - "enumorph", - "jsonrpsee 0.25.1", - "macros", - "serde", - "serde_json", - "tendermint-light-client-types", - "thiserror 2.0.12", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-client-update-plugin-trusted-mpt" -version = "0.0.0" -dependencies = [ - "alloy", - "beacon-api", - "beacon-api-types", - "bitvec 1.0.1", - "ed25519-dalek", - "embed-commit", - "enumorph", - "ethereum-light-client-types", - "ethereum-sync-protocol-types", - "futures", - "jsonrpsee 0.25.1", - "macros", - "serde", - "tokio", - "tracing", - "trusted-mpt-light-client-types", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-core" -version = "0.0.0" -dependencies = [ - "anyhow", - "axum 0.8.3", - "derive_builder", - "futures", - "indexmap 2.9.0", - "itertools 0.13.0", - "jaq-core", - "jaq-json", - "jaq-std", - "jsonrpsee 0.25.1", - "moka", - "opentelemetry", - "opentelemetry-otlp", - "opentelemetry_sdk", - "pin-utils", - "schemars", - "serde", - "serde_json", - "thiserror 2.0.12", - "tokio", - "tokio-util", - "tower 0.5.2", - "tower-http 0.6.4", - "tracing", - "unionlabs", - "voyager-message", - "voyager-plugin", - "voyager-plugin-protocol", - "voyager-primitives", - "voyager-rpc", - "voyager-types", - "voyager-vm", -] - -[[package]] -name = "voyager-event-source-plugin-cosmos-sdk" -version = "0.0.0" -dependencies = [ - "bincode 2.0.1", - "clap", - "cometbft-rpc", - "cosmos-sdk-event", - "dashmap 5.5.3", - "embed-commit", - "enumorph", - "ibc-classic-spec", - "ibc-solidity", - "ibc-union-spec", - "jsonrpsee 0.25.1", - "macros", - "prost 0.12.6", - "protos", - "serde", - "serde-utils", - "serde_json", - "sha2 0.10.9", - "thiserror 2.0.12", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", - "wasm-client-type", -] - -[[package]] -name = "voyager-event-source-plugin-ethereum" -version = "0.0.0" -dependencies = [ - "alloy", - "embed-commit", - "enumorph", - "ibc-solidity", - "ibc-union-spec", - "jsonrpsee 0.25.1", - "macros", + "protos", "serde", - "subset-of", + "serde_json", + "thiserror 2.0.12", "tokio", "tracing", "unionlabs", @@ -16608,39 +15769,39 @@ dependencies = [ ] [[package]] -name = "voyager-event-source-plugin-sui" +name = "voyager-client-bootstrap-module-trusted-mpt" version = "0.0.0" dependencies = [ - "anyhow", - "bcs", - "clap", + "alloy", + "ed25519-dalek", "embed-commit", - "enumorph", - "ibc-solidity", - "ibc-union-spec", "jsonrpsee 0.25.1", - "macros", "serde", "serde_json", - "sui-light-client-types", - "sui-sdk", "tokio", "tracing", + "trusted-mpt-light-client-types", "unionlabs", "voyager-sdk", ] [[package]] -name = "voyager-finality-module-arbitrum" +name = "voyager-client-module-cometbls" version = "0.0.0" dependencies = [ - "alloy", - "arbitrum-client", - "arbitrum-types", + "alloy-sol-types", + "bcs", + "cometbls-light-client-types", "embed-commit", - "ibc-union-spec", + "gnark-key-parser", + "hex", + "hex-literal 0.4.1", "jsonrpsee 0.25.1", + "macros", + "num-bigint 0.4.6", + "protos", "serde", + "serde_json", "tokio", "tracing", "unionlabs", @@ -16648,125 +15809,149 @@ dependencies = [ ] [[package]] -name = "voyager-finality-module-base" +name = "voyager-client-module-trusted-mpt" version = "0.0.0" dependencies = [ - "alloy", - "base-client", "embed-commit", - "ibc-union-spec", + "ethereum-light-client-types", "jsonrpsee 0.25.1", "serde", + "serde_json", "tokio", "tracing", + "trusted-mpt-light-client-types", "unionlabs", "voyager-sdk", ] [[package]] -name = "voyager-finality-module-berachain" +name = "voyager-client-update-plugin-cometbls" version = "0.0.0" dependencies = [ - "alloy", - "beacon-api-types", - "berachain-light-client-types", "cometbft-rpc", - "dashmap 5.5.3", + "cometbft-types", + "cometbls-light-client-types", "embed-commit", "enumorph", - "futures", - "ics23", + "galois-rpc", "jsonrpsee 0.25.1", "macros", "num-bigint 0.4.6", - "prost 0.12.6", - "protos", "serde", "serde_json", - "tendermint-light-client-types", + "subset-of", "thiserror 2.0.12", "tokio", "tracing", - "tracing-subscriber", "unionlabs", "voyager-sdk", ] [[package]] -name = "voyager-finality-module-bob" +name = "voyager-client-update-plugin-trusted-mpt" version = "0.0.0" dependencies = [ "alloy", - "bob-client", + "beacon-api", + "beacon-api-types", + "bitvec 1.0.1", + "ed25519-dalek", "embed-commit", - "ibc-union-spec", + "enumorph", + "ethereum-light-client-types", + "ethereum-sync-protocol-types", + "futures", "jsonrpsee 0.25.1", + "macros", "serde", "tokio", "tracing", + "trusted-mpt-light-client-types", "unionlabs", "voyager-sdk", ] [[package]] -name = "voyager-finality-module-cometbls" +name = "voyager-core" version = "0.0.0" dependencies = [ - "cometbft-rpc", - "embed-commit", + "anyhow", + "axum 0.8.3", + "derive_builder", + "futures", + "indexmap 2.9.0", + "itertools 0.13.0", + "jaq-core", + "jaq-json", + "jaq-std", "jsonrpsee 0.25.1", + "moka", + "opentelemetry", + "opentelemetry-otlp", + "opentelemetry_sdk", + "pin-utils", + "schemars", "serde", + "serde_json", "thiserror 2.0.12", "tokio", + "tokio-util", + "tower 0.5.2", + "tower-http 0.6.4", "tracing", "unionlabs", - "voyager-sdk", + "voyager-message", + "voyager-plugin", + "voyager-plugin-protocol", + "voyager-primitives", + "voyager-rpc", + "voyager-types", + "voyager-vm", ] [[package]] -name = "voyager-finality-module-ethereum" +name = "voyager-event-source-plugin-cosmos-sdk" version = "0.0.0" dependencies = [ - "alloy", - "beacon-api", - "beacon-api-types", + "bincode 2.0.1", + "clap", + "cometbft-rpc", + "cosmos-sdk-event", + "dashmap 5.5.3", "embed-commit", + "enumorph", + "ibc-classic-spec", + "ibc-solidity", + "ibc-union-spec", "jsonrpsee 0.25.1", - "moka", + "macros", + "prost 0.12.6", + "protos", "serde", + "serde-utils", + "serde_json", + "sha2 0.10.9", + "thiserror 2.0.12", "tokio", "tracing", "unionlabs", "voyager-sdk", + "wasm-client-type", ] [[package]] -name = "voyager-finality-module-parlia" +name = "voyager-event-source-plugin-ethereum" version = "0.0.0" dependencies = [ "alloy", "embed-commit", + "enumorph", + "ibc-solidity", "ibc-union-spec", "jsonrpsee 0.25.1", - "parlia-light-client-types", - "parlia-types", - "parlia-verifier", - "serde", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-finality-module-sui" -version = "0.0.0" -dependencies = [ - "embed-commit", - "jsonrpsee 0.25.1", + "macros", "serde", - "sui-sdk", - "thiserror 2.0.12", + "subset-of", "tokio", "tracing", "unionlabs", @@ -16774,7 +15959,7 @@ dependencies = [ ] [[package]] -name = "voyager-finality-module-tendermint" +name = "voyager-finality-module-cometbls" version = "0.0.0" dependencies = [ "cometbft-rpc", @@ -16821,21 +16006,6 @@ dependencies = [ "voyager-vm", ] -[[package]] -name = "voyager-periodic-client-update-plugin" -version = "0.0.0" -dependencies = [ - "clap", - "embed-commit", - "jsonrpsee 0.25.1", - "macros", - "serde", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - [[package]] name = "voyager-plugin" version = "0.0.0" @@ -17034,26 +16204,6 @@ dependencies = [ "unionlabs", ] -[[package]] -name = "voyager-proof-module-cosmos-sdk" -version = "0.0.0" -dependencies = [ - "clap", - "cometbft-rpc", - "embed-commit", - "ibc-classic-spec", - "jsonrpsee 0.25.1", - "prost 0.12.6", - "protos", - "serde", - "serde_json", - "thiserror 2.0.12", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - [[package]] name = "voyager-proof-module-cosmos-sdk-union" version = "0.0.0" @@ -17091,49 +16241,6 @@ dependencies = [ "voyager-sdk", ] -[[package]] -name = "voyager-proof-module-ethermint" -version = "0.0.0" -dependencies = [ - "clap", - "cometbft-rpc", - "embed-commit", - "ibc-union-spec", - "jsonrpsee 0.25.1", - "prost 0.12.6", - "protos", - "serde", - "serde_json", - "thiserror 2.0.12", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - -[[package]] -name = "voyager-proof-module-sui" -version = "0.0.0" -dependencies = [ - "bcs", - "clap", - "embed-commit", - "ibc-union-spec", - "jsonrpsee 0.25.1", - "move-core-types", - "reqwest 0.11.27", - "serde", - "serde_json", - "sui-light-client-types", - "sui-sdk", - "sui-verifier", - "tokio", - "tracing", - "unionlabs", - "voyager-message", - "voyager-sdk", -] - [[package]] name = "voyager-rpc" version = "0.0.0" @@ -17188,26 +16295,6 @@ dependencies = [ "voyager-vm", ] -[[package]] -name = "voyager-state-module-cosmos-sdk" -version = "0.0.0" -dependencies = [ - "clap", - "cometbft-rpc", - "embed-commit", - "ibc-classic-spec", - "jsonrpsee 0.25.1", - "protos", - "serde", - "serde-utils", - "serde_json", - "thiserror 2.0.12", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - [[package]] name = "voyager-state-module-cosmos-sdk-union" version = "0.0.0" @@ -17250,29 +16337,6 @@ dependencies = [ "voyager-sdk", ] -[[package]] -name = "voyager-state-module-sui" -version = "0.0.0" -dependencies = [ - "bcs", - "clap", - "embed-commit", - "enumorph", - "hex-literal 0.4.1", - "ibc-solidity", - "ibc-union-spec", - "jsonrpsee 0.25.1", - "macros", - "reqwest 0.11.27", - "serde", - "serde_json", - "sui-sdk", - "tokio", - "tracing", - "unionlabs", - "voyager-sdk", -] - [[package]] name = "voyager-sui-ibc-app-plugin-zkgm" version = "0.0.0" diff --git a/Cargo.toml b/Cargo.toml index 5e79b0b1fd..96d26deff2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -138,86 +138,86 @@ members = [ "lib/voyager-core", "lib/voyager-primitives", - "voyager/modules/state/cosmos-sdk", + # "voyager/modules/state/cosmos-sdk", "voyager/modules/state/cosmos-sdk-union", "voyager/modules/state/ethereum", # "voyager/modules/state/movement", - "voyager/modules/state/sui", + # "voyager/modules/state/sui", - "voyager/modules/proof/cosmos-sdk", + # "voyager/modules/proof/cosmos-sdk", "voyager/modules/proof/cosmos-sdk-union", - "voyager/modules/proof/ethermint", + # "voyager/modules/proof/ethermint", "voyager/modules/proof/ethereum", # "voyager/modules/proof/movement", - "voyager/modules/proof/sui", + # "voyager/modules/proof/sui", - "voyager/modules/client/base", - "voyager/modules/client/bob", - "voyager/modules/client/arbitrum", + # "voyager/modules/client/base", + # "voyager/modules/client/bob", + # "voyager/modules/client/arbitrum", "voyager/modules/client/cometbls", - "voyager/modules/client/ethereum", + # "voyager/modules/client/ethereum", # "voyager/modules/client/movement", - "voyager/modules/client/parlia", - "voyager/modules/client/tendermint", - "voyager/modules/client/ethermint", - "voyager/modules/client/state-lens/ics23-mpt", - "voyager/modules/client/state-lens/ics23-ics23", - "voyager/modules/client/state-lens/ics23-smt", - "voyager/modules/client/sui", + # "voyager/modules/client/parlia", + # "voyager/modules/client/tendermint", + # "voyager/modules/client/ethermint", + # "voyager/modules/client/state-lens/ics23-mpt", + # "voyager/modules/client/state-lens/ics23-ics23", + # "voyager/modules/client/state-lens/ics23-smt", + # "voyager/modules/client/sui", "voyager/modules/client/trusted-mpt", - "voyager/modules/client-bootstrap/base", - "voyager/modules/client-bootstrap/bob", - "voyager/modules/client-bootstrap/arbitrum", + # "voyager/modules/client-bootstrap/base", + # "voyager/modules/client-bootstrap/bob", + # "voyager/modules/client-bootstrap/arbitrum", "voyager/modules/client-bootstrap/cometbls", - "voyager/modules/client-bootstrap/ethereum", + # "voyager/modules/client-bootstrap/ethereum", # "voyager/modules/client-bootstrap/movement", - "voyager/modules/client-bootstrap/parlia", - "voyager/modules/client-bootstrap/tendermint", - "voyager/modules/client-bootstrap/ethermint", + # "voyager/modules/client-bootstrap/parlia", + # "voyager/modules/client-bootstrap/tendermint", + # "voyager/modules/client-bootstrap/ethermint", "voyager/modules/client-bootstrap/trusted-mpt", - "voyager/modules/client-bootstrap/state-lens/ics23-mpt", - "voyager/modules/client-bootstrap/state-lens/ics23-smt", - "voyager/modules/client-bootstrap/state-lens/ics23-ics23", - "voyager/modules/client-bootstrap/sui", - - "voyager/modules/finality/base", - "voyager/modules/finality/bob", - "voyager/modules/finality/arbitrum", - "voyager/modules/finality/berachain", + # "voyager/modules/client-bootstrap/state-lens/ics23-mpt", + # "voyager/modules/client-bootstrap/state-lens/ics23-smt", + # "voyager/modules/client-bootstrap/state-lens/ics23-ics23", + # "voyager/modules/client-bootstrap/sui", + + # "voyager/modules/finality/base", + # "voyager/modules/finality/bob", + # "voyager/modules/finality/arbitrum", + # "voyager/modules/finality/berachain", "voyager/modules/finality/cometbls", - "voyager/modules/finality/ethereum", + # "voyager/modules/finality/ethereum", # "voyager/modules/finality/movement", - "voyager/modules/finality/parlia", - "voyager/modules/finality/tendermint", + # "voyager/modules/finality/parlia", + # "voyager/modules/finality/tendermint", "voyager/modules/finality/trusted-evm", - "voyager/modules/finality/sui", + # "voyager/modules/finality/sui", - "voyager/plugins/client-update/base", - "voyager/plugins/client-update/bob", - "voyager/plugins/client-update/arbitrum", - "voyager/plugins/client-update/berachain", + # "voyager/plugins/client-update/base", + # "voyager/plugins/client-update/bob", + # "voyager/plugins/client-update/arbitrum", + # "voyager/plugins/client-update/berachain", "voyager/plugins/client-update/cometbls", - "voyager/plugins/client-update/ethereum", + # "voyager/plugins/client-update/ethereum", # "voyager/plugins/client-update/movement", - "voyager/plugins/client-update/parlia", - "voyager/plugins/client-update/tendermint", - "voyager/plugins/client-update/ethermint", - "voyager/plugins/client-update/state-lens", - "voyager/plugins/client-update/sui", + # "voyager/plugins/client-update/parlia", + # "voyager/plugins/client-update/tendermint", + # "voyager/plugins/client-update/ethermint", + # "voyager/plugins/client-update/state-lens", + # "voyager/plugins/client-update/sui", "voyager/plugins/client-update/trusted-mpt", - "voyager/plugins/periodic-client-update", + # "voyager/plugins/periodic-client-update", "voyager/plugins/event-source/cosmos-sdk", "voyager/plugins/event-source/ethereum", # "voyager/plugins/event-source/movement", - "voyager/plugins/event-source/sui", + # "voyager/plugins/event-source/sui", "voyager/plugins/transaction/cosmos-sdk", "voyager/plugins/transaction/ethereum", # "voyager/plugins/transaction/aptos", - "voyager/plugins/transaction/sui", + # "voyager/plugins/transaction/sui", "voyager/plugins/packet-filter", "voyager/plugins/packet-index", diff --git a/e2e/e2e.nix b/e2e/e2e.nix index f43d5f52cf..4434c3519d 100644 --- a/e2e/e2e.nix +++ b/e2e/e2e.nix @@ -121,29 +121,6 @@ networking.hostName = "devnetUnion"; }; }; - - galoisNode = { - wait_for_console_text = "Serving..."; - wait_for_open_port = 9999; - node = _: { - imports = [ - inputs.arion.nixosModules.arion - ]; - virtualisation = { - diskSize = 16 * 1024; - memorySize = 32 * 1024; - # TODO(aeryz): remove this - cores = 32; - arion = { - backend = "docker"; - projects.galois.settings = galois-arion-project; - }; - vlans = [ 1 ]; - }; - networking.hostName = "galois"; - }; - }; - in { _module.args.e2e = { @@ -205,7 +182,6 @@ inherit name; testScript = '' - galois.start() devnetUnion.wait_for_open_port(${toString unionNode.wait_for_open_port}) devnetEth.wait_for_open_port(${toString devnetEthNode.wait_for_open_port}) @@ -218,16 +194,17 @@ devnetVoyager.wait_for_open_port(${toString voyagerNode.wait_for_open_port}) devnetVoyager.wait_until_succeeds('${voyagerBin} rpc info') - galois.wait_for_console_text('${galoisNode.wait_for_console_text}') + devnetVoyager.wait_until_succeeds('${voyagerBin} -c ${voyagerNode.voyagerConfig} index union-devnet-1 -e') + devnetVoyager.wait_until_succeeds('${voyagerBin} -c ${voyagerNode.voyagerConfig} index 32382 -e') - devnetVoyager.succeed('${voyagerBin} -c ${voyagerNode.voyagerConfig} msg create-client --on union-devnet-1 --tracking 32382 --ibc-interface ibc-cosmwasm --ibc-spec-id ibc-union --client-type trusted/evm/mpt -e') - devnetVoyager.succeed('${voyagerBin} -c ${voyagerNode.voyagerConfig} msg create-client --on 32382 --tracking union-devnet-1 --ibc-interface ibc-solidity --ibc-spec-id ibc-union --client-type cometbls -e') + devnetVoyager.wait_until_succeeds('${voyagerBin} -c ${voyagerNode.voyagerConfig} msg create-client --on union-devnet-1 --tracking 32382 --ibc-interface ibc-cosmwasm --ibc-spec-id ibc-union --client-type trusted/evm/mpt -e') + devnetVoyager.wait_until_succeeds('${voyagerBin} -c ${voyagerNode.voyagerConfig} msg create-client --on 32382 --tracking union-devnet-1 --ibc-interface ibc-solidity --ibc-spec-id ibc-union --client-type cometbls -e') devnetVoyager.succeed( "echo '{\"@type\":\"call\",\"@value\":{\"@type\":\"submit_tx\",\"@value\":{\"chain_id\":\"union-devnet-1\",\"datagrams\":[{\"ibc_spec_id\":\"ibc-union\",\"datagram\":{\"@type\":\"connection_open_init\",\"@value\":{\"client_id\":1,\"counterparty_client_id\":1}}}]}}}' > /tmp/payload.json" ) - devnetVoyager.succeed("${voyagerBin} -c ${voyagerNode.voyagerConfig} q e $(cat /tmp/payload.json)") + devnetVoyager.wait_until_succeeds("${voyagerBin} -c ${voyagerNode.voyagerConfig} q e $(cat /tmp/payload.json)") devnetUnion.wait_until_succeeds('[[ $(curl "http://localhost:26660/block" --fail --silent | ${pkgs.lib.meta.getExe pkgs.jq} ".result.block.header.height | tonumber > 200000") == "true" ]]') ''; @@ -236,13 +213,11 @@ (pkgs.lib.throwIf (builtins.hasAttr "devnetUnion" nodes) "union node already exists; use a different name") (pkgs.lib.throwIf (builtins.hasAttr "devnetEth" nodes) "devnetEth node already exists; use a different name") (pkgs.lib.throwIf (builtins.hasAttr "voyager" nodes) "voyager node already exists; use a different name") - (pkgs.lib.throwIf (builtins.hasAttr "galois" nodes) "galois node already exists; use a different name") ( { devnetUnion = unionNode.node; devnetEth = devnetEthNode.node; devnetVoyager = voyagerNode.node; - galois = galoisNode.node; } // nodes ); diff --git a/tools/union-test/config.jsonc b/tools/union-test/config.jsonc index 47dcf915a7..6f546a82be 100644 --- a/tools/union-test/config.jsonc +++ b/tools/union-test/config.jsonc @@ -1,17 +1,6 @@ { "modules": { "state": [ - { - "enabled": true, - "path": "/bin/voyager-state-module-cosmos-sdk", - "info": { - "chain_id": "union-devnet-1", - "ibc_spec_id": "1.0.0" - }, - "config": { - "rpc_url": "http://devnetUnion:26657" - } - }, { "enabled": true, "path": "/bin/voyager-state-module-cosmos-sdk-union", @@ -87,19 +76,6 @@ "finality_lag": 1 } } - // { - // "enabled": true, - // "path": "/bin/voyager-consensus-module-ethereum", - // "info": { - // "chain_id": "32382", - // "consensus_type": "ethereum" - // }, - // "config": { - // "chain_spec": "minimal", - // "rpc_url": "http://devnetEth:8545", - // "beacon_rpc_url": "http://localhost:9596" - // } - // } ], "client": [ { @@ -121,36 +97,6 @@ "ibc_interface": "ibc-cosmwasm", "ibc_spec_id": "ibc-union" } - }, - { - "enabled": true, - "path": "/bin/voyager-client-module-cometbls", - "info": { - "client_type": "cometbls", - "consensus_type": "cometbls", - "ibc_interface": "ibc-move/aptos", - "ibc_spec_id": "ibc-union" - } - }, - { - "enabled": true, - "path": "/bin/voyager-client-module-cometbls", - "info": { - "client_type": "cometbls", - "consensus_type": "cometbls", - "ibc_interface": "ibc-go-v8/08-wasm", - "ibc_spec_id": "ibc-union" - } - }, - { - "enabled": true, - "path": "/bin/voyager-client-module-ethereum", - "info": { - "client_type": "ethereum", - "consensus_type": "ethereum", - "ibc_interface": "ibc-cosmwasm", - "ibc_spec_id": "ibc-union" - } } ], "client_bootstrap": [ @@ -300,7 +246,9 @@ "config": { "chain_id": "union-devnet-1", "rpc_url": "http://devnetUnion:26657", - "prover_endpoints": ["https://galois.testnet-9.union.build:443"] + "prover_endpoints": [ + "https://galois.testnet-9.union.build:443" + ] } }, { @@ -349,4 +297,4 @@ }, "optimizer_delay_milliseconds": 100 } -} +} \ No newline at end of file From cabb6ec32aa20671861134d81c4d8399686693a3 Mon Sep 17 00:00:00 2001 From: aeryz Date: Mon, 6 Oct 2025 13:43:04 +0300 Subject: [PATCH 19/33] chore: more e2e stuff Signed-off-by: aeryz --- e2e/all-tests.nix | 2 +- e2e/e2e.nix | 20 ++++++++++++++++---- e2e/full-e2e.nix | 7 ++++++- networks/services/lodestar.nix | 4 ++-- networks/services/voyager.nix | 2 +- tools/union-test/tests/lst/bond.rs | 12 +----------- 6 files changed, 27 insertions(+), 20 deletions(-) diff --git a/e2e/all-tests.nix b/e2e/all-tests.nix index 349033ae16..af58184ca6 100644 --- a/e2e/all-tests.nix +++ b/e2e/all-tests.nix @@ -23,7 +23,7 @@ ... }: let - full-e2e = import ./full-e2e.nix { inherit e2e pkgs; }; + full-e2e = import ./full-e2e.nix { inherit e2e pkgs self'; }; epoch-staking = import ./epoch-staking.nix { inherit e2e pkgs dbg; }; upgrades = import ./upgrades.nix { inherit e2e pkgs; diff --git a/e2e/e2e.nix b/e2e/e2e.nix index 4434c3519d..4bce19f2de 100644 --- a/e2e/e2e.nix +++ b/e2e/e2e.nix @@ -78,9 +78,9 @@ }; vlans = [ 1 ]; }; - networking.hostName = "devnetVoyager"; - environment.systemPackages = with pkgs; [ jq ]; + services.resolved.enable = true; + nix.settings.sandbox = false; }; }; @@ -189,7 +189,7 @@ # match non-zero blocks devnetUnion.wait_until_succeeds('[[ $(curl "http://localhost:26657/block" --fail --silent | ${pkgs.lib.meta.getExe pkgs.jq} ".result.block.header.height | tonumber > 1") == "true" ]]') - devnetEth.wait_until_succeeds('[[ $(curl http://localhost:9596/eth/v2/beacon/blocks/head --fail --silent | ${pkgs.lib.meta.getExe pkgs.jq} \'.data.message.slot | tonumber > 1\') == "true" ]]') + devnetEth.wait_until_succeeds('[[ $(curl http://localhost:9596/eth/v2/beacon/blocks/head --fail --silent | ${pkgs.lib.meta.getExe pkgs.jq} \'.data.message.slot | tonumber > 30\') == "true" ]]') devnetVoyager.wait_for_open_port(${toString voyagerNode.wait_for_open_port}) devnetVoyager.wait_until_succeeds('${voyagerBin} rpc info') @@ -206,7 +206,19 @@ devnetVoyager.wait_until_succeeds("${voyagerBin} -c ${voyagerNode.voyagerConfig} q e $(cat /tmp/payload.json)") - devnetUnion.wait_until_succeeds('[[ $(curl "http://localhost:26660/block" --fail --silent | ${pkgs.lib.meta.getExe pkgs.jq} ".result.block.header.height | tonumber > 200000") == "true" ]]') + # wait until the connection is opened + devnetVoyager.wait_until_succeeds("[[ $(${voyagerBin} rpc ibc-state 32382 '{ \"connection\": { \"connection_id\": 1 } }' | jq '.state.state == \"open\"') == true ]]") + + devnetVoyager.succeed( + "echo '{\"@type\":\"call\",\"@value\":{\"@type\":\"submit_tx\",\"@value\":{\"chain_id\":\"32382\",\"datagrams\":[{\"ibc_spec_id\":\"ibc-union\",\"datagram\":{\"@type\":\"channel_open_init\",\"@value\":{\"counterparty_port_id\":\"0x756e696f6e3172667a33797467366c363077786b357278736b32376a766e32393037637961763034737a386b64653378686d6d66396e706c7871723879303563\",\"port_id\":\"0x05FD55C1AbE31D3ED09A76216cA8F0372f4B2eC5\",\"connection_id\":1,\"version\":\"ucs03-zkgm-0\"}}}]}}}' > /tmp/payload.json" + ) + + devnetVoyager.wait_until_succeeds("${voyagerBin} -c ${voyagerNode.voyagerConfig} q e $(cat /tmp/payload.json)") + + # wait until the channel is opened + devnetVoyager.wait_until_succeeds("[[ $({voyagerBin} rpc ibc-state 32382 '{ \"channel\": { \"channel_id\": 1 } }' | jq '.state.state == \"open\"') == true ]]") + + ${testScript} ''; nodes = diff --git a/e2e/full-e2e.nix b/e2e/full-e2e.nix index 063780b632..b901b96858 100644 --- a/e2e/full-e2e.nix +++ b/e2e/full-e2e.nix @@ -1,13 +1,18 @@ { e2e, pkgs, + self', ... }: { all-works = e2e.mkE2eTestEthUnion { name = "all-works"; - testScript = ''''; + testScript = '' + devnetUnion.wait_until_succeeds("${self'.packages.cosmwasm-deployer}/bin/cosmwasm-deployer deploy-contract --rpc-url http://devnetUnion:26657 --private-key 0xaa820fa947beb242032a41b6dc9a8b9c37d8f5fbcda0966b1ec80335b10a7d6f --bytecode ${self'.packages.lst} --init-msg '{ \"native_token_denom\": \"muno\", \"minimum_liquid_stake_amount\": \"10\", \"staker_address\": \"union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2\", \"protocol_fee_config\": {\"fee_rate\": \"10000\", \"fee_recipient\": \"union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2\" }, \"lst_address\": \"union1nluwd0qfymmdwfczezvgrmvz43n4xwdyfvshxj82sj7smuk9m42stgfwcz\", \"batch_period_seconds\": \"20\", \"monitors\": [], \"admin\": \"union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2\", \"unbonding_period_seconds\": \"100\" }' --salt apps/lst --gas feemarket --max-gas 100000000 --gas-multiplier 1.4") + + devnetUnion.wait_until_succeeds("${self'.packages.cosmwasm-deployer}/bin/cosmwasm-deployer deploy-contract --rpc-url http://devnetUnion:26657 --private-key 0xaa820fa947beb242032a41b6dc9a8b9c37d8f5fbcda0966b1ec80335b10a7d6f --bytecode ${self'.packages.cw-unionversal-token} --init-msg '{ \"zkgm\": \"union1rfz3ytg6l60wxk5rxsk27jvn2907cyav04sz8kde3xhmmf9nplxqr8y05c\", \"admin\": \"union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2\", \"cw20_init\": { \"cw20\": { \"name\": \"eU\", \"symbol\": \"eU\", \"decimals\": 6, \"initial_balances\": [], \"mint\": {\"minter\": \"union1qg3gm3f87w6al9u9ldkqhjdeaxrd0tae5w70les88egql8nzp95qs5rrz0\"} } }, \"extra_minters\": [] }' --salt tokens/eu --gas feemarket --max-gas 100000000 --gas-multiplier 1.4") + ''; nodes = { }; diff --git a/networks/services/lodestar.nix b/networks/services/lodestar.nix index 59650c7731..922ccbc95d 100644 --- a/networks/services/lodestar.nix +++ b/networks/services/lodestar.nix @@ -95,11 +95,11 @@ in ]; healthcheck = { interval = "5s"; - retries = 6; + retries = 15; test = [ "CMD-SHELL" '' - curl -f http://localhost:9596/eth/v2/beacon/blocks/2 || exit 1 + curl -f http://localhost:9596/eth/v2/beacon/blocks/3 || exit 1 '' ]; }; diff --git a/networks/services/voyager.nix b/networks/services/voyager.nix index 6efcc673a8..f09b4bc156 100644 --- a/networks/services/voyager.nix +++ b/networks/services/voyager.nix @@ -16,7 +16,7 @@ _: { pkgs.jq self'.packages.voyager voyagerConfig - self'.packages.voyager-modules-plugins + self'.packages.voyager-modules-plugins-single-build ]; }; diff --git a/tools/union-test/tests/lst/bond.rs b/tools/union-test/tests/lst/bond.rs index bc31c2e42e..33d32e3c67 100644 --- a/tools/union-test/tests/lst/bond.rs +++ b/tools/union-test/tests/lst/bond.rs @@ -6,7 +6,7 @@ use cosmwasm_std::{ }; use cw20::Cw20ExecuteMsg; use lst::{ - msg::{AccountingStateResponse, Batch, BatchesResponse, ExecuteMsg as LstExecuteMsg}, + msg::{AccountingStateResponse, Batch, ExecuteMsg as LstExecuteMsg}, types::{BatchId, PendingBatch}, }; use rand::RngCore; @@ -26,11 +26,6 @@ use voyager_sdk::serde_json; use crate::lst::*; -// static ERC20: OnceCell = OnceCell::const_new(); - -// u: union1pntx7gm7shsp6slef74ae7wvcc35t3wdmanh7wrg4xkq95m24qds5atmcp -// lst: union1fdg764zzxwvwyqkx3fuj0236l9ddh5xmutgvj2mv9cduffy82z9sp62ygc - fn make_proxy_call(funded_msgs: &[(&str, Binary, Vec)]) -> Vec { let wasm_msgs: Vec = funded_msgs .into_iter() @@ -347,11 +342,6 @@ async fn get_accounting_state(t: &LstContext) -> anyhow::Result 0); - // let pair = ctx.get_channel().await.expect("channel available"); - let dst_channel_id = 1; let src_channel_id = 1; From adb1d7e91c1dd6ac101ecd5fd6e98de9ddfe396b Mon Sep 17 00:00:00 2001 From: aeryz Date: Tue, 7 Oct 2025 02:33:17 +0300 Subject: [PATCH 20/33] chore: moar e2e Signed-off-by: aeryz --- e2e/e2e.nix | 7 ++--- e2e/full-e2e.nix | 4 ++- flake.nix | 1 + tools/union-test/Cargo.toml | 6 ++++- tools/union-test/tests/config.json | 6 ++--- tools/union-test/tests/e2e.nix | 26 +++++++++++++++++++ tools/union-test/tests/lib.rs | 1 - .../union-test/tests/{lst/bond.rs => lst.rs} | 9 +++++-- .../tests/{lst => lst_common}/mod.rs | 16 +++++------- 9 files changed, 56 insertions(+), 20 deletions(-) create mode 100644 tools/union-test/tests/e2e.nix delete mode 100644 tools/union-test/tests/lib.rs rename tools/union-test/tests/{lst/bond.rs => lst.rs} (99%) rename tools/union-test/tests/{lst => lst_common}/mod.rs (96%) diff --git a/e2e/e2e.nix b/e2e/e2e.nix index 4bce19f2de..c967db2de2 100644 --- a/e2e/e2e.nix +++ b/e2e/e2e.nix @@ -167,7 +167,6 @@ ); }; - # TODO: This is poorly named, it only starts devnet-union and devnet-eth mkE2eTestEthUnion = { name, @@ -189,7 +188,7 @@ # match non-zero blocks devnetUnion.wait_until_succeeds('[[ $(curl "http://localhost:26657/block" --fail --silent | ${pkgs.lib.meta.getExe pkgs.jq} ".result.block.header.height | tonumber > 1") == "true" ]]') - devnetEth.wait_until_succeeds('[[ $(curl http://localhost:9596/eth/v2/beacon/blocks/head --fail --silent | ${pkgs.lib.meta.getExe pkgs.jq} \'.data.message.slot | tonumber > 30\') == "true" ]]') + devnetEth.wait_until_succeeds('[[ $(curl http://localhost:9596/eth/v2/beacon/blocks/head --fail --silent | ${pkgs.lib.meta.getExe pkgs.jq} \'.data.message.slot | tonumber > 20\') == "true" ]]') devnetVoyager.wait_for_open_port(${toString voyagerNode.wait_for_open_port}) devnetVoyager.wait_until_succeeds('${voyagerBin} rpc info') @@ -200,6 +199,8 @@ devnetVoyager.wait_until_succeeds('${voyagerBin} -c ${voyagerNode.voyagerConfig} msg create-client --on union-devnet-1 --tracking 32382 --ibc-interface ibc-cosmwasm --ibc-spec-id ibc-union --client-type trusted/evm/mpt -e') devnetVoyager.wait_until_succeeds('${voyagerBin} -c ${voyagerNode.voyagerConfig} msg create-client --on 32382 --tracking union-devnet-1 --ibc-interface ibc-solidity --ibc-spec-id ibc-union --client-type cometbls -e') + devnetVoyager.wait_until_succeeds('sleep 10') + devnetVoyager.succeed( "echo '{\"@type\":\"call\",\"@value\":{\"@type\":\"submit_tx\",\"@value\":{\"chain_id\":\"union-devnet-1\",\"datagrams\":[{\"ibc_spec_id\":\"ibc-union\",\"datagram\":{\"@type\":\"connection_open_init\",\"@value\":{\"client_id\":1,\"counterparty_client_id\":1}}}]}}}' > /tmp/payload.json" ) @@ -216,7 +217,7 @@ devnetVoyager.wait_until_succeeds("${voyagerBin} -c ${voyagerNode.voyagerConfig} q e $(cat /tmp/payload.json)") # wait until the channel is opened - devnetVoyager.wait_until_succeeds("[[ $({voyagerBin} rpc ibc-state 32382 '{ \"channel\": { \"channel_id\": 1 } }' | jq '.state.state == \"open\"') == true ]]") + devnetVoyager.wait_until_succeeds("[[ $(${voyagerBin} rpc ibc-state 32382 '{ \"channel\": { \"channel_id\": 1 } }' | jq '.state.state == \"open\"') == true ]]") ${testScript} ''; diff --git a/e2e/full-e2e.nix b/e2e/full-e2e.nix index b901b96858..0dc10ea353 100644 --- a/e2e/full-e2e.nix +++ b/e2e/full-e2e.nix @@ -1,6 +1,5 @@ { e2e, - pkgs, self', ... }: @@ -12,6 +11,9 @@ devnetUnion.wait_until_succeeds("${self'.packages.cosmwasm-deployer}/bin/cosmwasm-deployer deploy-contract --rpc-url http://devnetUnion:26657 --private-key 0xaa820fa947beb242032a41b6dc9a8b9c37d8f5fbcda0966b1ec80335b10a7d6f --bytecode ${self'.packages.lst} --init-msg '{ \"native_token_denom\": \"muno\", \"minimum_liquid_stake_amount\": \"10\", \"staker_address\": \"union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2\", \"protocol_fee_config\": {\"fee_rate\": \"10000\", \"fee_recipient\": \"union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2\" }, \"lst_address\": \"union1nluwd0qfymmdwfczezvgrmvz43n4xwdyfvshxj82sj7smuk9m42stgfwcz\", \"batch_period_seconds\": \"20\", \"monitors\": [], \"admin\": \"union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2\", \"unbonding_period_seconds\": \"100\" }' --salt apps/lst --gas feemarket --max-gas 100000000 --gas-multiplier 1.4") devnetUnion.wait_until_succeeds("${self'.packages.cosmwasm-deployer}/bin/cosmwasm-deployer deploy-contract --rpc-url http://devnetUnion:26657 --private-key 0xaa820fa947beb242032a41b6dc9a8b9c37d8f5fbcda0966b1ec80335b10a7d6f --bytecode ${self'.packages.cw-unionversal-token} --init-msg '{ \"zkgm\": \"union1rfz3ytg6l60wxk5rxsk27jvn2907cyav04sz8kde3xhmmf9nplxqr8y05c\", \"admin\": \"union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2\", \"cw20_init\": { \"cw20\": { \"name\": \"eU\", \"symbol\": \"eU\", \"decimals\": 6, \"initial_balances\": [], \"mint\": {\"minter\": \"union1qg3gm3f87w6al9u9ldkqhjdeaxrd0tae5w70les88egql8nzp95qs5rrz0\"} } }, \"extra_minters\": [] }' --salt tokens/eu --gas feemarket --max-gas 100000000 --gas-multiplier 1.4") + + devnetUnion.wait_until_succeeds("ls -la ${self'.packages.e2e-lst-tests}/lst") + devnetUnion.wait_until_succeeds("RUST_LOG=info ${self'.packages.e2e-lst-tests}/lst --nocapture 1>2") ''; nodes = { diff --git a/flake.nix b/flake.nix index 73cb7b4b22..57d34d7dbb 100644 --- a/flake.nix +++ b/flake.nix @@ -229,6 +229,7 @@ ./sentinel2/sentinel.nix ./lib/embed-commit ./networks/services/voyager.nix + ./tools/union-test/tests/e2e.nix treefmt-nix.flakeModule ]; diff --git a/tools/union-test/Cargo.toml b/tools/union-test/Cargo.toml index a376f07169..5a71e5a586 100644 --- a/tools/union-test/Cargo.toml +++ b/tools/union-test/Cargo.toml @@ -9,6 +9,9 @@ publish = { workspace = true } repository = { workspace = true } +[package.metadata.crane] +test-include = [ "tools/union-test/config.jsonc", "tools/union-test/tests/config.json" ] + [dependencies] alloy = { workspace = true, features = ["contract", "network", "providers", "signers", "signer-local", "rpc", "rpc-types", "transports", "transport-http", "transport-ws", "reqwest", "provider-ws"] } alloy-sol-types = { workspace = true } @@ -20,6 +23,7 @@ cosmos-client = { workspace = true } cosmos-sdk-event = { workspace = true } cosmwasm-std = { workspace = true } cw20 = { workspace = true } +embed-commit = { workspace = true } hex-literal = { workspace = true } ibc-solidity = { workspace = true, features = ["serde", "rpc"] } ibc-union-msg = { workspace = true } @@ -41,10 +45,10 @@ voyager-sdk = { workspace = true } [dev-dependencies] once_cell = "1.17" +rand = "0.6" serial_test = "0.5" tokio = { version = "1", features = ["macros", "rt"] } tracing-subscriber = "0.3" -rand = "0.6" [lints] diff --git a/tools/union-test/tests/config.json b/tools/union-test/tests/config.json index 1ff41c4dda..7b47ca79e8 100644 --- a/tools/union-test/tests/config.json +++ b/tools/union-test/tests/config.json @@ -32,7 +32,7 @@ } ] }, - "rpc_url": "http://0.0.0.0:26657", + "rpc_url": "http://devnetUnion:26657", "gas_config": { "type": "feemarket", "config": { @@ -47,8 +47,8 @@ "chain_id": "32382", "ibc_handler_address": "0xed2af2ad7fe0d92011b26a2e5d1b4dc7d12a47c5", "multicall_address": "0x84c4c2ee43ccfd523af9f78740256e0f60d38068", - "rpc_url": "http://0.0.0.0:8545", - "ws_url": "ws://0.0.0.0:8546", + "rpc_url": "http://devnetEth:8545", + "ws_url": "ws://devnetEth:8546", "keyring": { "name": "evm-keyring", "keys": [ diff --git a/tools/union-test/tests/e2e.nix b/tools/union-test/tests/e2e.nix new file mode 100644 index 0000000000..8e1f8fea3d --- /dev/null +++ b/tools/union-test/tests/e2e.nix @@ -0,0 +1,26 @@ +{ + ... +}: +{ + perSystem = + { + crane, + ... + }: + let + mkTest = + name: + (crane.buildWorkspaceMember "tools/union-test" { + dontRemoveDevDeps = true; + cargoBuildExtraArgs = "--tests"; + cargoBuildInstallPhase = '' + mkdir -p $out + FNAME=$(printf `ls -f -I '.*d' target/release/deps/${name}-*`) + mv "$FNAME" $out/${name} + ''; + }).union-test; + in + { + packages.e2e-lst-tests = mkTest "lst"; + }; +} diff --git a/tools/union-test/tests/lib.rs b/tools/union-test/tests/lib.rs deleted file mode 100644 index b39d7f9cbe..0000000000 --- a/tools/union-test/tests/lib.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod lst; diff --git a/tools/union-test/tests/lst/bond.rs b/tools/union-test/tests/lst.rs similarity index 99% rename from tools/union-test/tests/lst/bond.rs rename to tools/union-test/tests/lst.rs index 33d32e3c67..33d44b6556 100644 --- a/tools/union-test/tests/lst/bond.rs +++ b/tools/union-test/tests/lst.rs @@ -1,6 +1,7 @@ use std::time::Duration; use alloy::{network::AnyNetwork, primitives::Address, providers::DynProvider}; +use cometbft_rpc::types::code::Code; use cosmwasm_std::{ to_json_binary, Addr, Binary, Coin as CwCoin, CosmosMsg, Decimal, Uint128, WasmMsg, }; @@ -9,9 +10,11 @@ use lst::{ msg::{AccountingStateResponse, Batch, ExecuteMsg as LstExecuteMsg}, types::{BatchId, PendingBatch}, }; +use protos::cosmos::base::v1beta1::Coin as ProtoCoin; use rand::RngCore; use serde::{de::DeserializeOwned, Serialize}; use tracing::{info, warn}; +use ucs03_zkgm::com::TAG_ACK_SUCCESS; use union_test::{ cosmos::{self}, cosmos_helpers::calculate_proxy_address, @@ -22,9 +25,11 @@ use union_test::{ zkgm_helper, }; use unionlabs::primitives::U256; -use voyager_sdk::serde_json; +use voyager_sdk::{anyhow, serde_json}; -use crate::lst::*; +mod lst_common; + +use lst_common::*; fn make_proxy_call(funded_msgs: &[(&str, Binary, Vec)]) -> Vec { let wasm_msgs: Vec = funded_msgs diff --git a/tools/union-test/tests/lst/mod.rs b/tools/union-test/tests/lst_common/mod.rs similarity index 96% rename from tools/union-test/tests/lst/mod.rs rename to tools/union-test/tests/lst_common/mod.rs index 06559c5f43..ac0fa1f7c0 100644 --- a/tools/union-test/tests/lst/mod.rs +++ b/tools/union-test/tests/lst_common/mod.rs @@ -2,9 +2,6 @@ use std::{future::Future, sync::Arc, time::Duration}; use alloy::{network::AnyNetwork, providers::DynProvider}; use alloy_sol_types::SolValue as _; -use bip32::secp256k1::ecdsa::SigningKey; -use cometbft_rpc::types::code::Code; -use cosmos_client::wallet::{LocalSigner, WalletT as _}; use cosmwasm_std::Addr; use hex_literal::hex; use protos::cosmos::base::v1beta1::Coin as ProtoCoin; @@ -30,12 +27,8 @@ use unionlabs::{ }; use voyager_sdk::{anyhow, serde_json}; -pub mod bond; - pub static CTX: OnceCell<(Mutex, Arc)> = OnceCell::const_new(); -pub static CHANNELS_OPENED: OnceCell<()> = OnceCell::const_new(); - pub const ETH_ADDRESS_U: H160 = H160::new(hex!("0c8C6f58156D10d18193A8fFdD853e1b9F8D8836")); pub const ETH_ADDRESS_ZKGM: H160 = H160::new(hex!("05FD55C1AbE31D3ED09A76216cA8F0372f4B2eC5")); @@ -62,7 +55,7 @@ pub struct Config { #[derive(Clone)] pub struct SharedData { - stakers: Vec<(alloy::primitives::Address, DynProvider)>, + pub stakers: Vec<(alloy::primitives::Address, DynProvider)>, } pub struct Queue { @@ -70,7 +63,7 @@ pub struct Queue { shared_data: SharedData, } -async fn run_test_in_queue< +pub async fn run_test_in_queue< 'a, Fut: Future, F: Fn(Arc, SharedData) -> Fut, @@ -78,6 +71,7 @@ async fn run_test_in_queue< key: &str, test_fn: F, ) { + println!("[1] LST: BEFORE ANYTHING"); let ctx = CTX .get_or_init(|| async { let subscriber = FmtSubscriber::builder() @@ -87,8 +81,10 @@ async fn run_test_in_queue< .expect("setting default subscriber failed"); let cfg: Config = serde_json::from_str(include_str!("../config.json")).unwrap(); + println!("[1] LST: BEFORE PARSING CONFIG"); let src = cosmos::Module::new(cfg.union).await.unwrap(); let dst = evm::Module::new(cfg.evm).await.unwrap(); + println!("[2] LST: AFTER PARSING CONFIG"); let ctx = TestContext::new( src, @@ -136,8 +132,10 @@ async fn run_test_in_queue< loop { { + println!("LST RUNNING TEST BRO????"); let mut lock = ctx.0.lock().await; if lock.tests.last().unwrap() == key { + println!("LST RUNNING SPECIFIC TEST: {key}"); lock.shared_data = test_fn(ctx.1.clone(), lock.shared_data.clone()).await; let _ = lock.tests.pop(); return; From 5d73825eddb531003a6f00fc9d1eb42675d96b34 Mon Sep 17 00:00:00 2001 From: aeryz Date: Tue, 7 Oct 2025 14:04:35 +0300 Subject: [PATCH 21/33] chore: final changes hopefully Signed-off-by: aeryz --- e2e/full-e2e.nix | 50 ++++++- tools/union-test/src/cosmos.rs | 4 +- tools/union-test/src/cosmos_helpers.rs | 1 + tools/union-test/src/evm.rs | 2 +- tools/union-test/tests/config.json | 6 +- tools/union-test/tests/e2e.rs | 106 +++++++------- tools/union-test/tests/lst.rs | 174 +++++++++-------------- tools/union-test/tests/lst_common/mod.rs | 16 ++- 8 files changed, 185 insertions(+), 174 deletions(-) diff --git a/e2e/full-e2e.nix b/e2e/full-e2e.nix index 0dc10ea353..1a81dd1db6 100644 --- a/e2e/full-e2e.nix +++ b/e2e/full-e2e.nix @@ -8,11 +8,57 @@ name = "all-works"; testScript = '' - devnetUnion.wait_until_succeeds("${self'.packages.cosmwasm-deployer}/bin/cosmwasm-deployer deploy-contract --rpc-url http://devnetUnion:26657 --private-key 0xaa820fa947beb242032a41b6dc9a8b9c37d8f5fbcda0966b1ec80335b10a7d6f --bytecode ${self'.packages.lst} --init-msg '{ \"native_token_denom\": \"muno\", \"minimum_liquid_stake_amount\": \"10\", \"staker_address\": \"union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2\", \"protocol_fee_config\": {\"fee_rate\": \"10000\", \"fee_recipient\": \"union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2\" }, \"lst_address\": \"union1nluwd0qfymmdwfczezvgrmvz43n4xwdyfvshxj82sj7smuk9m42stgfwcz\", \"batch_period_seconds\": \"20\", \"monitors\": [], \"admin\": \"union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2\", \"unbonding_period_seconds\": \"100\" }' --salt apps/lst --gas feemarket --max-gas 100000000 --gas-multiplier 1.4") + devnetUnion.wait_until_succeeds("${self'.packages.cosmwasm-deployer}/bin/cosmwasm-deployer deploy-contract --rpc-url http://devnetUnion:26657 --private-key 0xaa820fa947beb242032a41b6dc9a8b9c37d8f5fbcda0966b1ec80335b10a7d6f --bytecode ${self'.packages.lst-staker} --init-msg '{ \"local\": { \"admin\": \"union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2\" } }' --salt apps/lst-staker --gas feemarket --max-gas 100000000 --gas-multiplier 1.4") + + devnetUnion.wait_until_succeeds("${self'.packages.cosmwasm-deployer}/bin/cosmwasm-deployer deploy-contract --rpc-url http://devnetUnion:26657 --private-key 0xaa820fa947beb242032a41b6dc9a8b9c37d8f5fbcda0966b1ec80335b10a7d6f --bytecode ${self'.packages.lst} --init-msg '{ \"native_token_denom\": \"au\", \"minimum_liquid_stake_amount\": \"10\", \"staker_address\": \"union160a75a608j6w80x5ykckvd9cavs2xk8yfjzy2eqhpq0nprxg05qqf067nj\", \"protocol_fee_config\": {\"fee_rate\": \"10000\", \"fee_recipient\": \"union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2\" }, \"lst_address\": \"union1nluwd0qfymmdwfczezvgrmvz43n4xwdyfvshxj82sj7smuk9m42stgfwcz\", \"batch_period_seconds\": \"20\", \"monitors\": [], \"admin\": \"union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2\", \"unbonding_period_seconds\": \"100\" }' --salt apps/lst --gas feemarket --max-gas 100000000 --gas-multiplier 1.4") devnetUnion.wait_until_succeeds("${self'.packages.cosmwasm-deployer}/bin/cosmwasm-deployer deploy-contract --rpc-url http://devnetUnion:26657 --private-key 0xaa820fa947beb242032a41b6dc9a8b9c37d8f5fbcda0966b1ec80335b10a7d6f --bytecode ${self'.packages.cw-unionversal-token} --init-msg '{ \"zkgm\": \"union1rfz3ytg6l60wxk5rxsk27jvn2907cyav04sz8kde3xhmmf9nplxqr8y05c\", \"admin\": \"union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2\", \"cw20_init\": { \"cw20\": { \"name\": \"eU\", \"symbol\": \"eU\", \"decimals\": 6, \"initial_balances\": [], \"mint\": {\"minter\": \"union1qg3gm3f87w6al9u9ldkqhjdeaxrd0tae5w70les88egql8nzp95qs5rrz0\"} } }, \"extra_minters\": [] }' --salt tokens/eu --gas feemarket --max-gas 100000000 --gas-multiplier 1.4") - devnetUnion.wait_until_succeeds("ls -la ${self'.packages.e2e-lst-tests}/lst") + devnetUnion.wait_until_succeeds("\ + ${self'.packages.uniond}/bin/uniond tx \ + wasm execute \ + union1skg5244hpkad603zz77kdekzw6ffgpfrde3ldk8rpdz06n62k4hqct0w4j \ + '{\"set_fungible_counterparty\": {\"path\": \"0\", \"channel_id\": 1, \"base_token\": \"0x0c8C6f58156D10d18193A8fFdD853e1b9F8D8836\", \"counterparty_beneficiary\": \"0x0000000000000000000000000000000000000000000000000000000000000000\", \"escrowed_denom\": \"au\"}}' \ + --from alice \ + --gas auto \ + --gas-adjustment 10.0 \ + --node http://devnetUnion:26657 \ + --chain-id union-devnet-1 -y \ + --home ${self'.packages.devnet-union-home} \ + --keyring-backend test \ + --gas-prices 1au\ + ") + + devnetUnion.wait_until_succeeds("\ + ${self'.packages.uniond}/bin/uniond tx \ + wasm execute \ + union160a75a608j6w80x5ykckvd9cavs2xk8yfjzy2eqhpq0nprxg05qqf067nj \ + '{\"set_validators\": { \"unionvaloper1qp4uzhet2sd9mrs46kemse5dt9ncz4k3xuz7ej\": \"100\" }}' \ + --from alice \ + --gas auto \ + --gas-adjustment 10.0 \ + --node http://devnetUnion:26657 \ + --chain-id union-devnet-1 -y \ + --home ${self'.packages.devnet-union-home} \ + --keyring-backend test \ + --gas-prices 1au\ + ") + + devnetUnion.wait_until_succeeds("\ + ${self'.packages.uniond}/bin/uniond tx \ + wasm execute \ + union160a75a608j6w80x5ykckvd9cavs2xk8yfjzy2eqhpq0nprxg05qqf067nj \ + '{\"set_lst_hub_address\": \"union1qg3gm3f87w6al9u9ldkqhjdeaxrd0tae5w70les88egql8nzp95qs5rrz0\"}' \ + --from alice \ + --gas auto \ + --gas-adjustment 10.0 \ + --node http://devnetUnion:26657 \ + --chain-id union-devnet-1 -y \ + --home ${self'.packages.devnet-union-home} \ + --keyring-backend test \ + --gas-prices 1au\ + ") + devnetUnion.wait_until_succeeds("RUST_LOG=info ${self'.packages.e2e-lst-tests}/lst --nocapture 1>2") ''; diff --git a/tools/union-test/src/cosmos.rs b/tools/union-test/src/cosmos.rs index a2d1214920..f8eb341e67 100644 --- a/tools/union-test/src/cosmos.rs +++ b/tools/union-test/src/cosmos.rs @@ -706,7 +706,7 @@ impl Module { delegator_address: signer_address.to_string(), validator_address, amount: Some(Coin { - denom: "muno".to_string(), + denom: "au".to_string(), amount: amount.to_string(), }), })], @@ -733,7 +733,7 @@ impl Module { delegator_address: signer_address.to_string(), validator_address, amount: Some(Coin { - denom: "muno".to_string(), + denom: "au".to_string(), amount: amount.to_string(), }), })], diff --git a/tools/union-test/src/cosmos_helpers.rs b/tools/union-test/src/cosmos_helpers.rs index 69a293bc37..186846d37a 100644 --- a/tools/union-test/src/cosmos_helpers.rs +++ b/tools/union-test/src/cosmos_helpers.rs @@ -18,6 +18,7 @@ pub const SALT_ESCROW_VAULT: &[u8] = &hex!("50bbead29d10abe51a7c32bbc02a9b00ff4a7db57c050b7a0ff61d6173c33965"); pub const SALT_LST_HUB: &[u8] = b"apps/lst"; pub const SALT_EU: &[u8] = b"tokens/eu"; +pub const SALT_LST_STAKER: &[u8] = b"apps/lst-staker"; pub fn calculate_cosmos_contract_address(creator: &str, salt: &[u8]) -> anyhow::Result { let bech_addr: Bech32 = Bech32::from_str(creator).unwrap(); diff --git a/tools/union-test/src/evm.rs b/tools/union-test/src/evm.rs index 2907759df4..68669a672b 100644 --- a/tools/union-test/src/evm.rs +++ b/tools/union-test/src/evm.rs @@ -932,7 +932,7 @@ impl Module { .registerGovernanceToken( channel_id, zkgm::GovernanceToken { - unwrappedToken: b"muno".into(), + unwrappedToken: b"au".into(), metadataImage: metadata_image.into(), }, ) diff --git a/tools/union-test/tests/config.json b/tools/union-test/tests/config.json index 7b47ca79e8..1ff41c4dda 100644 --- a/tools/union-test/tests/config.json +++ b/tools/union-test/tests/config.json @@ -32,7 +32,7 @@ } ] }, - "rpc_url": "http://devnetUnion:26657", + "rpc_url": "http://0.0.0.0:26657", "gas_config": { "type": "feemarket", "config": { @@ -47,8 +47,8 @@ "chain_id": "32382", "ibc_handler_address": "0xed2af2ad7fe0d92011b26a2e5d1b4dc7d12a47c5", "multicall_address": "0x84c4c2ee43ccfd523af9f78740256e0f60d38068", - "rpc_url": "http://devnetEth:8545", - "ws_url": "ws://devnetEth:8546", + "rpc_url": "http://0.0.0.0:8545", + "ws_url": "ws://0.0.0.0:8546", "keyring": { "name": "evm-keyring", "keys": [ diff --git a/tools/union-test/tests/e2e.rs b/tools/union-test/tests/e2e.rs index d532391b18..da7146e5be 100644 --- a/tools/union-test/tests/e2e.rs +++ b/tools/union-test/tests/e2e.rs @@ -200,7 +200,7 @@ async fn test_send_vault_success() { operand: TokenOrderV2 { sender: cosmos_address_bytes.clone().into(), receiver: evm_address.to_vec().into(), - base_token: "muno".as_bytes().into(), + base_token: "au".as_bytes().into(), base_amount: "10".parse().unwrap(), kind: TOKEN_ORDER_KIND_SOLVE, metadata: metadata.into(), @@ -219,7 +219,7 @@ async fn test_send_vault_success() { zkgm_deployer_provider.clone(), alloy::primitives::U256::ZERO, dst_channel_id, - b"muno".to_vec().into(), + b"au".to_vec().into(), evm::u::U::FungibleCounterparty { beneficiary: vault_on_union.as_bytes().to_vec().into(), }, @@ -240,7 +240,7 @@ async fn test_send_vault_success() { let bin_msg: Vec = Encode::::encode(&cw_msg); let funds = vec![Coin { - denom: "muno".into(), + denom: "au".into(), amount: "10".into(), }]; @@ -258,7 +258,7 @@ async fn test_send_vault_success() { let initial_vault_balance = t .ctx .src - .native_balance(t.union_address.escrow_vault.clone(), "muno") + .native_balance(t.union_address.escrow_vault.clone(), "au") .await .unwrap(); @@ -294,7 +294,7 @@ async fn test_send_vault_success() { let new_vault_balance = t .ctx .src - .native_balance(t.union_address.escrow_vault.clone(), "muno") + .native_balance(t.union_address.escrow_vault.clone(), "au") .await .unwrap(); @@ -338,7 +338,7 @@ async fn test_send_vault_success_with_fee() { operand: TokenOrderV2 { sender: cosmos_address_bytes.clone().into(), receiver: recv_addr.to_vec().into(), - base_token: "muno".as_bytes().into(), + base_token: "au".as_bytes().into(), base_amount: "15".parse().unwrap(), // So fee will be 5 and will be minted to relayer kind: TOKEN_ORDER_KIND_SOLVE, metadata: metadata.into(), @@ -357,7 +357,7 @@ async fn test_send_vault_success_with_fee() { zkgm_deployer_provider.clone(), alloy::primitives::U256::ZERO, dst_channel_id, - b"muno".to_vec().into(), + b"au".to_vec().into(), evm::u::U::FungibleCounterparty { beneficiary: vault_on_union.as_bytes().to_vec().into(), }, @@ -378,7 +378,7 @@ async fn test_send_vault_success_with_fee() { let bin_msg: Vec = Encode::::encode(&cw_msg); let funds = vec![Coin { - denom: "muno".into(), + denom: "au".into(), amount: "15".into(), // So fee will be 5 and will be minted to relayer }]; @@ -392,7 +392,7 @@ async fn test_send_vault_success_with_fee() { let initial_vault_balance = t .ctx .src - .native_balance(t.union_address.escrow_vault.clone(), "muno") + .native_balance(t.union_address.escrow_vault.clone(), "au") .await .unwrap(); @@ -436,7 +436,7 @@ async fn test_send_vault_success_with_fee() { let new_vault_balance = t .ctx .src - .native_balance(t.union_address.escrow_vault.clone(), "muno") + .native_balance(t.union_address.escrow_vault.clone(), "au") .await .unwrap(); @@ -485,7 +485,7 @@ async fn test_send_packet_from_union_to_evm_and_send_back_unwrap() { &t.ctx.dst, ETH_ADDRESS_ZKGM.into(), ChannelId::new(NonZero::new(dst_chain_id).unwrap()), - "muno".into(), + "au".into(), &evm_provider, ) .await @@ -500,10 +500,10 @@ async fn test_send_packet_from_union_to_evm_and_send_back_unwrap() { operand: TokenOrderV1 { sender: cosmos_address_bytes.clone().into(), receiver: evm_address.to_vec().into(), - base_token: "muno".as_bytes().into(), + base_token: "au".as_bytes().into(), base_amount: "10".parse().unwrap(), - base_token_symbol: "muno".into(), - base_token_name: "muno".into(), + base_token_symbol: "au".into(), + base_token_name: "au".into(), base_token_decimals: 6, base_token_path: "0".parse().unwrap(), quote_token: quote_token_addr.as_ref().to_vec().into(), @@ -523,7 +523,7 @@ async fn test_send_packet_from_union_to_evm_and_send_back_unwrap() { let bin_msg: Vec = Encode::::encode(&cw_msg); let funds = vec![Coin { - denom: "muno".into(), + denom: "au".into(), amount: "10".into(), }]; @@ -556,11 +556,11 @@ async fn test_send_packet_from_union_to_evm_and_send_back_unwrap() { receiver: cosmos_address_bytes.clone().into(), base_token: quote_token_addr.as_ref().to_vec().into(), base_amount: "1".parse().unwrap(), - base_token_symbol: "muno".into(), - base_token_name: "muno".into(), + base_token_symbol: "au".into(), + base_token_name: "au".into(), base_token_decimals: 6, base_token_path: dst_chain_id.try_into().unwrap(), - quote_token: "muno".into(), + quote_token: "au".into(), quote_amount: "1".parse().unwrap(), } .abi_encode_params() @@ -821,7 +821,7 @@ async fn test_send_packet_from_union_to_evm_get_refund() { &t.ctx.dst, ETH_ADDRESS_ZKGM.into(), ChannelId::new(NonZero::new(dst_chain_id).unwrap()), - "muno".into(), + "au".into(), &evm_provider, ) .await @@ -838,10 +838,10 @@ async fn test_send_packet_from_union_to_evm_get_refund() { operand: TokenOrderV1 { sender: cosmos_address_bytes.clone().into(), receiver: evm_address.to_vec().into(), - base_token: "muno".as_bytes().into(), + base_token: "au".as_bytes().into(), base_amount: sending_amount.parse().unwrap(), - base_token_symbol: "muno".into(), - base_token_name: "muno".into(), + base_token_symbol: "au".into(), + base_token_name: "au".into(), base_token_decimals: 6, base_token_path: "0".parse().unwrap(), quote_token: cosmos_address_bytes.clone().into(), // it will revert @@ -872,14 +872,14 @@ async fn test_send_packet_from_union_to_evm_get_refund() { let bin_msg: Vec = Encode::::encode(&cw_msg); let funds = vec![Coin { - denom: "muno".into(), + denom: "au".into(), amount: sending_amount.into(), }]; let muno_balance_before_send = t .ctx .src - .get_balance(&cosmos_address.clone().to_string(), "muno") + .get_balance(&cosmos_address.clone().to_string(), "au") .await; assert!( muno_balance_before_send.is_ok(), @@ -918,7 +918,7 @@ async fn test_send_packet_from_union_to_evm_get_refund() { let muno_balance_after_send = t .ctx .src - .get_balance(&cosmos_address.clone().to_string(), "muno") + .get_balance(&cosmos_address.clone().to_string(), "au") .await; assert!( muno_balance_after_send.is_ok(), @@ -1101,8 +1101,8 @@ async fn test_from_evm_to_union_tokenv2_unhappy_only_maker_err() { initializer: ZkgmERC20::initializeCall { _authority: hex!("6C1D11bE06908656D16EBFf5667F1C45372B7c89").into(), _minter: ETH_ADDRESS_ZKGM.into(), - _name: "muno".into(), - _symbol: "muno".into(), + _name: "au".into(), + _symbol: "au".into(), _decimals: 6u8, } .abi_encode() @@ -1121,7 +1121,7 @@ async fn test_from_evm_to_union_tokenv2_unhappy_only_maker_err() { operand: TokenOrderV2 { sender: cosmos_address_bytes.clone().into(), receiver: evm_address.to_vec().into(), - base_token: "muno".as_bytes().into(), + base_token: "au".as_bytes().into(), base_amount: "10".parse().unwrap(), kind: TOKEN_ORDER_KIND_INITIALIZE, metadata: img_metadata.clone().into(), @@ -1138,7 +1138,7 @@ async fn test_from_evm_to_union_tokenv2_unhappy_only_maker_err() { operand: TokenOrderV2 { sender: cosmos_address_bytes.clone().into(), receiver: evm_address.to_vec().into(), - base_token: "muno".as_bytes().into(), + base_token: "au".as_bytes().into(), base_amount: "10".parse().unwrap(), kind: TOKEN_ORDER_KIND_INITIALIZE, metadata: img_metadata.into(), @@ -1159,7 +1159,7 @@ async fn test_from_evm_to_union_tokenv2_unhappy_only_maker_err() { let bin_msg: Vec = Encode::::encode(&cw_msg); let funds = vec![Coin { - denom: "muno".into(), + denom: "au".into(), amount: "10".into(), }]; @@ -1274,8 +1274,8 @@ async fn test_from_evm_to_union_tokenv2_unhappy_err_invalid_unescrow() { initializer: ZkgmERC20::initializeCall { _authority: hex!("6C1D11bE06908656D16EBFf5667F1C45372B7c89").into(), _minter: ETH_ADDRESS_ZKGM.into(), - _name: "muno".into(), - _symbol: "muno".into(), + _name: "au".into(), + _symbol: "au".into(), _decimals: 6u8, } .abi_encode() @@ -1312,7 +1312,7 @@ async fn test_from_evm_to_union_tokenv2_unhappy_err_invalid_unescrow() { &t.ctx.dst, ETH_ADDRESS_ZKGM.into(), ChannelId::new(NonZero::new(pair.dest).unwrap()), - "muno".into(), + "au".into(), img, &evm_provider, ) @@ -1327,7 +1327,7 @@ async fn test_from_evm_to_union_tokenv2_unhappy_err_invalid_unescrow() { operand: TokenOrderV2 { sender: cosmos_address_bytes.clone().into(), receiver: evm_address.to_vec().into(), - base_token: "muno".as_bytes().into(), + base_token: "au".as_bytes().into(), base_amount: "10".parse().unwrap(), kind: TOKEN_ORDER_KIND_INITIALIZE, metadata: img_metadata.clone().into(), @@ -1349,7 +1349,7 @@ async fn test_from_evm_to_union_tokenv2_unhappy_err_invalid_unescrow() { let bin_msg: Vec = Encode::::encode(&cw_msg); let funds = vec![Coin { - denom: "muno".into(), + denom: "au".into(), amount: "10".into(), }]; @@ -1409,7 +1409,7 @@ async fn test_from_evm_to_union_tokenv2_unhappy_err_invalid_unescrow() { operand: TokenOrderV2 { sender: cosmos_address_bytes.clone().into(), receiver: evm_address.to_vec().into(), - base_token: "munooo".as_bytes().into(), // Which is wrong, so it will revert ErrInvalidUnescrow + base_token: "au".as_bytes().into(), // Which is wrong, so it will revert ErrInvalidUnescrow base_amount: "10".parse().unwrap(), kind: TOKEN_ORDER_KIND_UNESCROW, metadata: img_metadata.into(), @@ -1474,8 +1474,8 @@ async fn test_from_evm_to_union_tokenv2_unhappy_err_cannot_deploy() { initializer: ZkgmERC20::initializeCall { _authority: hex!("6C1D11bE06908656D16EBFf5667F1C45372B7c89").into(), _minter: ETH_ADDRESS_ZKGM.into(), - _name: "muno".into(), - _symbol: "muno".into(), + _name: "au".into(), + _symbol: "au".into(), _decimals: 6u8, } .abi_encode() @@ -1492,7 +1492,7 @@ async fn test_from_evm_to_union_tokenv2_unhappy_err_cannot_deploy() { &t.ctx.dst, ETH_ADDRESS_ZKGM.into(), ChannelId::new(NonZero::new(pair.dest).unwrap()), - "muno".into(), + "au".into(), &evm_provider, ) .await @@ -1504,7 +1504,7 @@ async fn test_from_evm_to_union_tokenv2_unhappy_err_cannot_deploy() { operand: TokenOrderV2 { sender: cosmos_address_bytes.clone().into(), receiver: evm_address.to_vec().into(), - base_token: "muno".as_bytes().into(), + base_token: "au".as_bytes().into(), base_amount: "10".parse().unwrap(), kind: TOKEN_ORDER_KIND_ESCROW, // Which is wrong, so it will revert CANNOT_DEPLOY metadata: img_metadata.clone().into(), @@ -1525,7 +1525,7 @@ async fn test_from_evm_to_union_tokenv2_unhappy_err_cannot_deploy() { let bin_msg: Vec = Encode::::encode(&cw_msg); let funds = vec![Coin { - denom: "muno".into(), + denom: "au".into(), amount: "10".into(), }]; @@ -1772,7 +1772,7 @@ async fn test_send_vault_unhappy_u_counterparty_is_not_fungible() { operand: TokenOrderV2 { sender: cosmos_address_bytes.clone().into(), receiver: evm_address.to_vec().into(), - base_token: "muno".as_bytes().into(), + base_token: "au".as_bytes().into(), base_amount: "10".parse().unwrap(), kind: TOKEN_ORDER_KIND_SOLVE, metadata: metadata.clone().into(), @@ -1789,7 +1789,7 @@ async fn test_send_vault_unhappy_u_counterparty_is_not_fungible() { operand: TokenOrderV2 { sender: cosmos_address_bytes.clone().into(), receiver: evm_address.to_vec().into(), - base_token: "muno".as_bytes().into(), + base_token: "au".as_bytes().into(), base_amount: "10".parse().unwrap(), kind: TOKEN_ORDER_KIND_SOLVE, metadata: metadata.into(), @@ -1808,7 +1808,7 @@ async fn test_send_vault_unhappy_u_counterparty_is_not_fungible() { zkgm_deployer_provider.clone(), alloy::primitives::U256::ZERO, dst_channel_id, - b"muno".to_vec().into(), + b"au".to_vec().into(), evm::u::U::FungibleCounterparty { beneficiary: empty_beneficiary, // Sending it empty to make this // test revert due to U_CounterpartyIsNotFungible and get ErrOnlyMaker @@ -1830,7 +1830,7 @@ async fn test_send_vault_unhappy_u_counterparty_is_not_fungible() { let bin_msg: Vec = Encode::::encode(&cw_msg); let funds = vec![Coin { - denom: "muno".into(), + denom: "au".into(), amount: "10".into(), }]; @@ -1955,7 +1955,7 @@ async fn test_send_vault_unhappy_u_base_amount_must_cover_quote_amount() { operand: TokenOrderV2 { sender: cosmos_address_bytes.clone().into(), receiver: evm_address.to_vec().into(), - base_token: "muno".as_bytes().into(), + base_token: "au".as_bytes().into(), base_amount: "10".parse().unwrap(), kind: TOKEN_ORDER_KIND_SOLVE, metadata: metadata.clone().into(), @@ -1973,7 +1973,7 @@ async fn test_send_vault_unhappy_u_base_amount_must_cover_quote_amount() { operand: TokenOrderV2 { sender: cosmos_address_bytes.clone().into(), receiver: evm_address.to_vec().into(), - base_token: "muno".as_bytes().into(), + base_token: "au".as_bytes().into(), base_amount: "10".parse().unwrap(), kind: TOKEN_ORDER_KIND_SOLVE, metadata: metadata.into(), @@ -1992,7 +1992,7 @@ async fn test_send_vault_unhappy_u_base_amount_must_cover_quote_amount() { zkgm_deployer_provider.clone(), alloy::primitives::U256::ZERO, dst_channel_id, - b"muno".to_vec().into(), + b"au".to_vec().into(), evm::u::U::FungibleCounterparty { beneficiary: vault_on_union.as_bytes().to_vec().into(), }, @@ -2013,7 +2013,7 @@ async fn test_send_vault_unhappy_u_base_amount_must_cover_quote_amount() { let bin_msg: Vec = Encode::::encode(&cw_msg); let funds = vec![Coin { - denom: "muno".into(), + denom: "au".into(), amount: "10".into(), }]; @@ -2139,7 +2139,7 @@ async fn test_send_vault_unhappy_u_fool() { operand: TokenOrderV2 { sender: cosmos_address_bytes.clone().into(), receiver: evm_address.to_vec().into(), - base_token: "muno".as_bytes().into(), + base_token: "au".as_bytes().into(), base_amount: "10".parse().unwrap(), kind: TOKEN_ORDER_KIND_SOLVE, metadata: metadata.clone().into(), @@ -2157,7 +2157,7 @@ async fn test_send_vault_unhappy_u_fool() { operand: TokenOrderV2 { sender: cosmos_address_bytes.clone().into(), receiver: evm_address.to_vec().into(), - base_token: "muno".as_bytes().into(), + base_token: "au".as_bytes().into(), base_amount: "10".parse().unwrap(), kind: TOKEN_ORDER_KIND_SOLVE, metadata: metadata.into(), @@ -2176,7 +2176,7 @@ async fn test_send_vault_unhappy_u_fool() { zkgm_deployer_provider.clone(), alloy::primitives::U256::ZERO, dst_channel_id, - b"muno".to_vec().into(), + b"au".to_vec().into(), evm::u::U::FungibleCounterparty { beneficiary: vault_on_union.as_bytes().to_vec().into(), }, @@ -2197,7 +2197,7 @@ async fn test_send_vault_unhappy_u_fool() { let bin_msg: Vec = Encode::::encode(&cw_msg); let funds = vec![Coin { - denom: "muno".into(), + denom: "au".into(), amount: "10".into(), }]; diff --git a/tools/union-test/tests/lst.rs b/tools/union-test/tests/lst.rs index 33d44b6556..405063e02b 100644 --- a/tools/union-test/tests/lst.rs +++ b/tools/union-test/tests/lst.rs @@ -122,7 +122,7 @@ async fn bond( sender_on_evm.as_ref(), ); - // funding the eth address that we execute bond with, with muno + // funding the eth address that we execute bond with, with au eth_fund_u(&t, src_channel_id, sender_on_evm.into(), 100_000, 500_000) .await .unwrap(); @@ -164,7 +164,7 @@ async fn bond( t.union_address.lst_hub.as_str(), &proxy_address_on_union.to_string(), min_mint_amount, - "muno", + "au", bond_amount, ) .into(), @@ -350,11 +350,11 @@ async fn test_bond_success() { let dst_channel_id = 1; let src_channel_id = 1; - // setting "muno" as the fungible counterparty + // setting "au" as the fungible counterparty eth_set_fungible_counterparty( &t.ctx.dst, src_channel_id, - b"muno", + b"au", t.union_address.escrow_vault.as_bytes(), ) .await @@ -412,29 +412,6 @@ async fn test_bond_success() { eu_balance_after_stake - eu_balance_before, new_state.total_shares.u128() - state.total_shares.u128() ); - - let k = t - .ctx - .src - .privileged_acc_keyring - .with(async |k| k) - .await - .unwrap(); - - let outcome = t - .ctx - .src - .stake( - "unionvaloper1qp4uzhet2sd9mrs46kemse5dt9ncz4k3xuz7ej".to_string(), - bond_amount, - // &t.staker, - k, - ) - .await - .unwrap() - .unwrap(); - - assert_eq!(outcome.tx_result.code, Code::Ok); } // we are making sure that the 2 mins ubonding time passes, while making sure that the @@ -493,50 +470,36 @@ async fn test_unbond_success() { total_unbond_amount += amount * 2; } - let k = t - .ctx - .src - .privileged_acc_keyring - .with(async |k| k) - .await - .unwrap(); - - let outcome = t - .ctx - .src - .unstake( - "unionvaloper1qp4uzhet2sd9mrs46kemse5dt9ncz4k3xuz7ej".to_string(), - total_unbond_amount, - k, - ) - .await - .unwrap() - .unwrap(); - - assert_eq!(outcome.tx_result.code, Code::Ok); - let (_, signer) = t.ctx.src.get_signer().await; let state = get_accounting_state(&t).await.unwrap(); - let outcome = t - .ctx - .src - .send_cosmwasm_transaction( - t.union_address.lst_hub.clone(), - ( - to_json_binary(&LstExecuteMsg::SubmitBatch {}) - .unwrap() - .into(), - vec![], - ), - &signer, - ) - .await - .unwrap() - .unwrap(); - - assert_eq!(outcome.tx_result.code, Code::Ok); - + let mut worked = false; + for _ in 1..6 { + if let Ok(outcome) = t + .ctx + .src + .send_cosmwasm_transaction( + t.union_address.lst_hub.clone(), + ( + to_json_binary(&LstExecuteMsg::SubmitBatch {}) + .unwrap() + .into(), + vec![], + ), + &signer, + ) + .await + .unwrap() + { + assert_eq!(outcome.tx_result.code, Code::Ok); + worked = true; + break; + } else { + info!("waiting 20 seconds before submitting batch"); + tokio::time::sleep(Duration::from_secs(20)).await; + } + } + assert!(worked); let new_state = get_accounting_state(&t).await.unwrap(); // We burned exactly the `total_unbond_amount` of eU's @@ -583,7 +546,7 @@ async fn test_withdraw_success() { .unwrap() .into(), vec![ProtoCoin { - denom: "muno".to_string(), + denom: "au".to_string(), amount: fund_amount.to_string(), }], ), @@ -612,7 +575,7 @@ async fn test_withdraw_success() { let u_balance_before = t .ctx .src - .native_balance(proxy_address.clone(), "muno") + .native_balance(proxy_address.clone(), "au") .await .unwrap(); @@ -626,12 +589,7 @@ async fn test_withdraw_success() { ) .await; - let u_balance_after = t - .ctx - .src - .native_balance(proxy_address, "muno") - .await - .unwrap(); + let u_balance_after = t.ctx.src.native_balance(proxy_address, "au").await.unwrap(); assert_eq!( u_balance_after - u_balance_before, @@ -668,7 +626,7 @@ async fn test_withdraw_success() { // eth_set_fungible_counterparty( // &t.ctx.dst, // dst_channel_id, -// b"muno", +// b"au, // t.union_address.escrow_vault.as_bytes(), // ) // .await @@ -702,7 +660,7 @@ async fn test_withdraw_success() { // let new_vault_balance = t // .ctx // .src -// .native_balance(Bech32::from_str(vault_on_union).unwrap(), "muno") +// .native_balance(Bech32::from_str(vault_on_union).unwrap(), "au") // .await // .unwrap(); @@ -759,7 +717,7 @@ async fn test_withdraw_success() { // // let zkgm_message = json!({ // // "contract": lst_hub, // // "msg": bond_message.to_string(), -// // "funds": [{ "denom": "muno", "amount": "3" }], +// // "funds": [{ "denom": "au", "amount": "3" }], // // "call_action": "call_proxy" // // }) // // .to_string(); @@ -768,14 +726,14 @@ async fn test_withdraw_success() { // lst_hub, // "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", // 1000000u128.into(), -// "muno", +// "au", // 1000000, // ); // let proxy_balance = t // .ctx // .src -// .native_balance(zkgm_proxy_calculated.clone(), "muno") +// .native_balance(zkgm_proxy_calculated.clone(), "au") // .await // .unwrap(); @@ -805,7 +763,7 @@ async fn test_withdraw_success() { // } // .abi_encode_params() // .into(), -// quote_token: "muno".as_bytes().into(), +// quote_token: "au".as_bytes().into(), // // giving 150 but expecting 1000000 so it will fail. // quote_amount: "150".parse().unwrap(), // } @@ -889,7 +847,7 @@ async fn test_withdraw_success() { // let proxy_balance = t // .ctx // .src -// .native_balance(zkgm_proxy_calculated, "muno") +// .native_balance(zkgm_proxy_calculated, "au") // .await // .unwrap(); @@ -928,7 +886,7 @@ async fn test_withdraw_success() { // operand: TokenOrderV2 { // sender: cosmos_address_bytes.clone().into(), // receiver: evm_address.to_vec().into(), -// base_token: "muno".as_bytes().into(), +// base_token: "au".as_bytes().into(), // base_amount: "100000".parse().unwrap(), // kind: TOKEN_ORDER_KIND_SOLVE, // metadata: metadata.into(), @@ -948,7 +906,7 @@ async fn test_withdraw_success() { // zkgm_deployer_provider.clone(), // alloy::primitives::U256::ZERO, // dst_channel_id, -// b"muno".to_vec().into(), +// b"au.to_vec().into(), // evm::u::U::FungibleCounterparty { // beneficiary: vault_on_union.as_bytes().to_vec().into(), // }, @@ -970,7 +928,7 @@ async fn test_withdraw_success() { // let bin_msg: Vec = Encode::::encode(&cw_msg); // let funds = vec![Coin { -// denom: "muno".into(), +// denom: "au".into(), // amount: "100000".into(), // }]; @@ -1010,7 +968,7 @@ async fn test_withdraw_success() { // let new_vault_balance = t // .ctx // .src -// .native_balance(Bech32::from_str(vault_on_union).unwrap(), "muno") +// .native_balance(Bech32::from_str(vault_on_union).unwrap(), "au") // .await // .unwrap(); @@ -1067,7 +1025,7 @@ async fn test_withdraw_success() { // // let zkgm_message = json!({ // // "contract": lst_hub, // // "msg": bond_message.to_string(), -// // "funds": [{ "denom": "muno", "amount": "3" }], +// // "funds": [{ "denom": "au", "amount": "3" }], // // "call_action": "call_proxy" // // }) // // .to_string(); @@ -1083,7 +1041,7 @@ async fn test_withdraw_success() { // let proxy_balance = t // .ctx // .src -// .native_balance(zkgm_proxy_calculated.clone(), "muno") +// .native_balance(zkgm_proxy_calculated.clone(), "au") // .await // .unwrap(); @@ -1112,7 +1070,7 @@ async fn test_withdraw_success() { // } // .abi_encode_params() // .into(), -// quote_token: "muno".as_bytes().into(), +// quote_token: "au".as_bytes().into(), // quote_amount: "150".parse().unwrap(), // } // .abi_encode_params() @@ -1195,7 +1153,7 @@ async fn test_withdraw_success() { // let proxy_balance = t // .ctx // .src -// .native_balance(zkgm_proxy_calculated, "muno") +// .native_balance(zkgm_proxy_calculated, "au") // .await // .unwrap(); @@ -1234,7 +1192,7 @@ async fn test_withdraw_success() { // operand: TokenOrderV2 { // sender: cosmos_address_bytes.clone().into(), // receiver: evm_address.to_vec().into(), -// base_token: "muno".as_bytes().into(), +// base_token: "au".as_bytes().into(), // base_amount: "100000".parse().unwrap(), // kind: TOKEN_ORDER_KIND_SOLVE, // metadata: metadata.into(), @@ -1254,7 +1212,7 @@ async fn test_withdraw_success() { // zkgm_deployer_provider.clone(), // alloy::primitives::U256::ZERO, // dst_channel_id, -// b"muno".to_vec().into(), +// b"au.to_vec().into(), // evm::u::U::FungibleCounterparty { // beneficiary: vault_on_union.as_bytes().to_vec().into(), // }, @@ -1276,7 +1234,7 @@ async fn test_withdraw_success() { // let bin_msg: Vec = Encode::::encode(&cw_msg); // let funds = vec![Coin { -// denom: "muno".into(), +// denom: "au".into(), // amount: "100000".into(), // }]; @@ -1316,7 +1274,7 @@ async fn test_withdraw_success() { // let new_vault_balance = t // .ctx // .src -// .native_balance(Bech32::from_str(vault_on_union).unwrap(), "muno") +// .native_balance(Bech32::from_str(vault_on_union).unwrap(), "au") // .await // .unwrap(); @@ -1373,7 +1331,7 @@ async fn test_withdraw_success() { // // let zkgm_message = json!({ // // "contract": lst_hub, // // "msg": bond_message.to_string(), -// // "funds": [{ "denom": "muno", "amount": "3" }], +// // "funds": [{ "denom": "au", "amount": "3" }], // // "call_action": "call_proxy" // // }) // // .to_string(); @@ -1382,14 +1340,14 @@ async fn test_withdraw_success() { // lst_hub, // "union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2", // 0u128.into(), -// "muno", +// "au", // 0, // under minimum amount to make it fail // ); // let proxy_balance = t // .ctx // .src -// .native_balance(zkgm_proxy_calculated.clone(), "muno") +// .native_balance(zkgm_proxy_calculated.clone(), "au") // .await // .unwrap(); @@ -1418,7 +1376,7 @@ async fn test_withdraw_success() { // } // .abi_encode_params() // .into(), -// quote_token: "muno".as_bytes().into(), +// quote_token: "au".as_bytes().into(), // quote_amount: "150".parse().unwrap(), // } // .abi_encode_params() @@ -1501,7 +1459,7 @@ async fn test_withdraw_success() { // let proxy_balance = t // .ctx // .src -// .native_balance(zkgm_proxy_calculated, "muno") +// .native_balance(zkgm_proxy_calculated, "au") // .await // .unwrap(); @@ -1540,7 +1498,7 @@ async fn test_withdraw_success() { // operand: TokenOrderV2 { // sender: cosmos_address_bytes.clone().into(), // receiver: evm_address.to_vec().into(), -// base_token: "muno".as_bytes().into(), +// base_token: "au".as_bytes().into(), // base_amount: "100000".parse().unwrap(), // kind: TOKEN_ORDER_KIND_SOLVE, // metadata: metadata.into(), @@ -1560,7 +1518,7 @@ async fn test_withdraw_success() { // zkgm_deployer_provider.clone(), // alloy::primitives::U256::ZERO, // dst_channel_id, -// b"muno".to_vec().into(), +// b"au.to_vec().into(), // evm::u::U::FungibleCounterparty { // beneficiary: vault_on_union.as_bytes().to_vec().into(), // }, @@ -1582,7 +1540,7 @@ async fn test_withdraw_success() { // let bin_msg: Vec = Encode::::encode(&cw_msg); // let funds = vec![Coin { -// denom: "muno".into(), +// denom: "au".into(), // amount: "100000".into(), // }]; @@ -1622,7 +1580,7 @@ async fn test_withdraw_success() { // let new_vault_balance = t // .ctx // .src -// .native_balance(Bech32::from_str(vault_on_union).unwrap(), "muno") +// .native_balance(Bech32::from_str(vault_on_union).unwrap(), "au") // .await // .unwrap(); @@ -1679,7 +1637,7 @@ async fn test_withdraw_success() { // // let zkgm_message = json!({ // // "contract": lst_hub, // // "msg": bond_message.to_string(), -// // "funds": [{ "denom": "muno", "amount": "3" }], +// // "funds": [{ "denom": "au", "amount": "3" }], // // "call_action": "call_proxy" // // }) // // .to_string(); @@ -1701,7 +1659,7 @@ async fn test_withdraw_success() { // let proxy_balance = t // .ctx // .src -// .native_balance(zkgm_proxy_calculated.clone(), "muno") +// .native_balance(zkgm_proxy_calculated.clone(), "au") // .await // .unwrap(); @@ -1730,7 +1688,7 @@ async fn test_withdraw_success() { // } // .abi_encode_params() // .into(), -// quote_token: "muno".as_bytes().into(), +// quote_token: "au".as_bytes().into(), // quote_amount: "150".parse().unwrap(), //giving 150 but expecting 1000000 so it will fail. // } // .abi_encode_params() @@ -1813,7 +1771,7 @@ async fn test_withdraw_success() { // let proxy_balance = t // .ctx // .src -// .native_balance(zkgm_proxy_calculated, "muno") +// .native_balance(zkgm_proxy_calculated, "au") // .await // .unwrap(); diff --git a/tools/union-test/tests/lst_common/mod.rs b/tools/union-test/tests/lst_common/mod.rs index ac0fa1f7c0..8d5461c7db 100644 --- a/tools/union-test/tests/lst_common/mod.rs +++ b/tools/union-test/tests/lst_common/mod.rs @@ -17,7 +17,8 @@ use ucs03_zkgm::com::{ use union_test::{ cosmos::{self}, cosmos_helpers::{ - calculate_cosmos_contract_address, SALT_ESCROW_VAULT, SALT_EU, SALT_LST_HUB, SALT_ZKGM, + calculate_cosmos_contract_address, SALT_ESCROW_VAULT, SALT_EU, SALT_LST_HUB, + SALT_LST_STAKER, SALT_ZKGM, }, evm, TestContext, }; @@ -37,6 +38,7 @@ pub struct UnionAddressBook { pub lst_hub: Addr, pub eu: Addr, pub escrow_vault: Addr, + pub lst_staker: Addr, } pub struct LstContext { @@ -71,7 +73,6 @@ pub async fn run_test_in_queue< key: &str, test_fn: F, ) { - println!("[1] LST: BEFORE ANYTHING"); let ctx = CTX .get_or_init(|| async { let subscriber = FmtSubscriber::builder() @@ -123,6 +124,11 @@ pub async fn run_test_in_queue< SALT_ESCROW_VAULT, ) .unwrap(), + lst_staker: calculate_cosmos_contract_address( + &cfg.union_deployer_addr, + SALT_LST_STAKER, + ) + .unwrap(), }, ctx, }), @@ -211,7 +217,7 @@ pub async fn eth_fund_u( operand: TokenOrderV2 { sender: cosmos_address.to_string().into_bytes().into(), receiver: receiver.into_bytes().into(), - base_token: "muno".as_bytes().into(), + base_token: "au".as_bytes().into(), base_amount: amount, kind: TOKEN_ORDER_KIND_SOLVE, metadata: metadata.into(), @@ -242,7 +248,7 @@ pub async fn eth_fund_u( } .encode_as::(), vec![ProtoCoin { - denom: "muno".into(), + denom: "au".into(), amount: amount.to_string(), }], ), @@ -280,7 +286,7 @@ pub mod evm_helper { receiver: receiver.as_bytes().to_vec().into(), base_token: ETH_ADDRESS_U.into_bytes().into(), base_amount: amount, - quote_token: b"muno".into(), + quote_token: b"au".into(), quote_amount: amount, kind: TOKEN_ORDER_KIND_SOLVE, metadata: SolverMetadata { From d189d37a4387f7dda6dc447aa44561caf73d666d Mon Sep 17 00:00:00 2001 From: poisonphang <17688291+PoisonPhang@users.noreply.github.com> Date: Tue, 7 Oct 2025 12:58:49 -0500 Subject: [PATCH 22/33] chore: fmt --- tools/union-test/Cargo.toml | 2 +- tools/union-test/config.jsonc | 6 ++---- tools/union-test/tests/e2e.nix | 4 +--- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/tools/union-test/Cargo.toml b/tools/union-test/Cargo.toml index 5a71e5a586..4b4b72c69e 100644 --- a/tools/union-test/Cargo.toml +++ b/tools/union-test/Cargo.toml @@ -10,7 +10,7 @@ repository = { workspace = true } [package.metadata.crane] -test-include = [ "tools/union-test/config.jsonc", "tools/union-test/tests/config.json" ] +test-include = ["tools/union-test/config.jsonc", "tools/union-test/tests/config.json"] [dependencies] alloy = { workspace = true, features = ["contract", "network", "providers", "signers", "signer-local", "rpc", "rpc-types", "transports", "transport-http", "transport-ws", "reqwest", "provider-ws"] } diff --git a/tools/union-test/config.jsonc b/tools/union-test/config.jsonc index 6f546a82be..f5708904cb 100644 --- a/tools/union-test/config.jsonc +++ b/tools/union-test/config.jsonc @@ -246,9 +246,7 @@ "config": { "chain_id": "union-devnet-1", "rpc_url": "http://devnetUnion:26657", - "prover_endpoints": [ - "https://galois.testnet-9.union.build:443" - ] + "prover_endpoints": ["https://galois.testnet-9.union.build:443"] } }, { @@ -297,4 +295,4 @@ }, "optimizer_delay_milliseconds": 100 } -} \ No newline at end of file +} diff --git a/tools/union-test/tests/e2e.nix b/tools/union-test/tests/e2e.nix index 8e1f8fea3d..41b842e608 100644 --- a/tools/union-test/tests/e2e.nix +++ b/tools/union-test/tests/e2e.nix @@ -1,6 +1,4 @@ -{ - ... -}: +_: { perSystem = { From 863e3542f95fb107c9f93fceac49cb3b4bc0fa70 Mon Sep 17 00:00:00 2001 From: poisonphang <17688291+PoisonPhang@users.noreply.github.com> Date: Tue, 7 Oct 2025 13:02:33 -0500 Subject: [PATCH 23/33] chore: spelling --- tools/union-test/tests/lst_common/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/union-test/tests/lst_common/mod.rs b/tools/union-test/tests/lst_common/mod.rs index 8d5461c7db..84b8950a00 100644 --- a/tools/union-test/tests/lst_common/mod.rs +++ b/tools/union-test/tests/lst_common/mod.rs @@ -159,11 +159,11 @@ pub async fn eth_set_fungible_counterparty( ) -> anyhow::Result<()> { info!("registering fungible counterparty"); - let (_, priviledged_account) = module.get_provider_privileged().await; + let (_, privileged_account) = module.get_provider_privileged().await; module .u_register_fungible_counterpart( ETH_ADDRESS_U, - priviledged_account.clone(), + privileged_account.clone(), alloy::primitives::U256::ZERO, channel_id, base_token.to_vec().into(), From f1e1b582c31bacb34db85db2149e6507b2bb9795 Mon Sep 17 00:00:00 2001 From: poisonphang <17688291+PoisonPhang@users.noreply.github.com> Date: Tue, 7 Oct 2025 13:23:24 -0500 Subject: [PATCH 24/33] feat(ci): run all-works nightly --- .github/workflows/nightly-all-works.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/workflows/nightly-all-works.yml diff --git a/.github/workflows/nightly-all-works.yml b/.github/workflows/nightly-all-works.yml new file mode 100644 index 0000000000..729e6fff9d --- /dev/null +++ b/.github/workflows/nightly-all-works.yml @@ -0,0 +1,20 @@ +on: + schedule: + - cron: "20 4 * * *" + workflow_dispatch: + +jobs: + deploy-preview: + runs-on: ['ubuntu-latest'] + steps: + - uses: actions/checkout@v4 + with: + lfs: true + - uses: cachix/install-nix-action@v31 + with: + extra_nix_config: | + trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= cache.garnix.io:CTFPyKSLcx5RMJKfLo5EEPUObbA78b0YQ2DTCJXqr9g= union.cachix.org-1:TV9o8jexzNVbM1VNBOq9fu8NK+hL6ZhOyOh0quATy+M= + trusted-substituters = https://cache.nixos.org https://cache.garnix.io https://union.cachix.org + - name: Fetch from Cache + run: | + nix build .#checks.x86_64-linux.all-works -L From 931a2989c2416b098858ccefcb940674030c7804 Mon Sep 17 00:00:00 2001 From: poisonphang <17688291+PoisonPhang@users.noreply.github.com> Date: Tue, 7 Oct 2025 13:25:37 -0500 Subject: [PATCH 25/33] chore(ci): exclude all-works from on-push --- garnix.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/garnix.yaml b/garnix.yaml index 148afe141b..9eb2c2d62a 100644 --- a/garnix.yaml +++ b/garnix.yaml @@ -15,6 +15,7 @@ builds: - 'checks.aarch64-linux.nil' - 'checks.aarch64-linux.ssz-tests-up-to-date' - 'checks.*.all-crates-buildable-individually' + - 'checks.*.all-works' - 'checks.*.devnet-eth-runs' - 'checks.*.ensure-blocks' - 'checks.*.epoch-completes' @@ -72,6 +73,7 @@ builds: - 'nixosConfigurations.*' exclude: - 'checks.*.all-crates-buildable-individually' + - 'checks.*.all-works' - 'checks.*.devnet-eth-runs' - 'checks.*.ensure-blocks' - 'checks.*.epoch-completes' From 02c746af5e20d1ad351ab5caf66911780364e642 Mon Sep 17 00:00:00 2001 From: poisonphang <17688291+PoisonPhang@users.noreply.github.com> Date: Tue, 7 Oct 2025 13:52:18 -0500 Subject: [PATCH 26/33] chore: fmt --- .github/workflows/nightly-all-works.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nightly-all-works.yml b/.github/workflows/nightly-all-works.yml index 729e6fff9d..eabec78e98 100644 --- a/.github/workflows/nightly-all-works.yml +++ b/.github/workflows/nightly-all-works.yml @@ -1,6 +1,6 @@ on: schedule: - - cron: "20 4 * * *" + - cron: "20 4 * * *" workflow_dispatch: jobs: From 8a3bed58bcecfb77a8d85854b21c88cd6de9aaac Mon Sep 17 00:00:00 2001 From: aeryz Date: Wed, 8 Oct 2025 10:48:15 +0300 Subject: [PATCH 27/33] chore: all tests are working Signed-off-by: aeryz --- e2e/full-e2e.nix | 2 +- tools/union-test/tests/config.json | 6 +++--- tools/union-test/tests/lst.rs | 3 +++ tools/union-test/tests/lst_common/mod.rs | 1 - 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/e2e/full-e2e.nix b/e2e/full-e2e.nix index 1a81dd1db6..fb7b9d0620 100644 --- a/e2e/full-e2e.nix +++ b/e2e/full-e2e.nix @@ -59,7 +59,7 @@ --gas-prices 1au\ ") - devnetUnion.wait_until_succeeds("RUST_LOG=info ${self'.packages.e2e-lst-tests}/lst --nocapture 1>2") + devnetUnion.wait_until_succeeds("RUST_LOG=info ${self'.packages.e2e-lst-tests}/lst --nocapture 1>&2") ''; nodes = { diff --git a/tools/union-test/tests/config.json b/tools/union-test/tests/config.json index 1ff41c4dda..7b47ca79e8 100644 --- a/tools/union-test/tests/config.json +++ b/tools/union-test/tests/config.json @@ -32,7 +32,7 @@ } ] }, - "rpc_url": "http://0.0.0.0:26657", + "rpc_url": "http://devnetUnion:26657", "gas_config": { "type": "feemarket", "config": { @@ -47,8 +47,8 @@ "chain_id": "32382", "ibc_handler_address": "0xed2af2ad7fe0d92011b26a2e5d1b4dc7d12a47c5", "multicall_address": "0x84c4c2ee43ccfd523af9f78740256e0f60d38068", - "rpc_url": "http://0.0.0.0:8545", - "ws_url": "ws://0.0.0.0:8546", + "rpc_url": "http://devnetEth:8545", + "ws_url": "ws://devnetEth:8546", "keyring": { "name": "evm-keyring", "keys": [ diff --git a/tools/union-test/tests/lst.rs b/tools/union-test/tests/lst.rs index 405063e02b..6d3f4af7e8 100644 --- a/tools/union-test/tests/lst.rs +++ b/tools/union-test/tests/lst.rs @@ -516,6 +516,9 @@ async fn test_unbond_success() { #[tokio::test] async fn test_withdraw_success() { run_test_in_queue("withdraw", async |t, shared_data| { + // Waiting for at least the unbond amount before receiving the tokens + tokio::time::sleep(Duration::from_secs(120)).await; + let dst_channel_id = 1; let src_channel_id = 1; diff --git a/tools/union-test/tests/lst_common/mod.rs b/tools/union-test/tests/lst_common/mod.rs index 84b8950a00..4ecbd8f18a 100644 --- a/tools/union-test/tests/lst_common/mod.rs +++ b/tools/union-test/tests/lst_common/mod.rs @@ -82,7 +82,6 @@ pub async fn run_test_in_queue< .expect("setting default subscriber failed"); let cfg: Config = serde_json::from_str(include_str!("../config.json")).unwrap(); - println!("[1] LST: BEFORE PARSING CONFIG"); let src = cosmos::Module::new(cfg.union).await.unwrap(); let dst = evm::Module::new(cfg.evm).await.unwrap(); println!("[2] LST: AFTER PARSING CONFIG"); From 47331e2b277163adae39be5f501cd45618366056 Mon Sep 17 00:00:00 2001 From: aeryz Date: Wed, 8 Oct 2025 11:38:49 +0300 Subject: [PATCH 28/33] chore: rebased Signed-off-by: aeryz --- Cargo.lock | 1 + e2e/all-tests.nix | 6 ++-- e2e/e2e.nix | 36 +++++++++++++----------- e2e/{full-e2e.nix => union-test.nix} | 20 ++++++++++--- garnix.yaml | 4 +-- tools/union-test/src/evm.rs | 1 - tools/union-test/tests/e2e.nix | 3 +- tools/union-test/tests/lst_common/mod.rs | 1 + 8 files changed, 44 insertions(+), 28 deletions(-) rename e2e/{full-e2e.nix => union-test.nix} (79%) diff --git a/Cargo.lock b/Cargo.lock index 7075d2b274..33be2fbdfd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15389,6 +15389,7 @@ dependencies = [ "cosmos-sdk-event", "cosmwasm-std", "cw20", + "embed-commit", "hex-literal 0.4.1", "ibc-solidity", "ibc-union-msg", diff --git a/e2e/all-tests.nix b/e2e/all-tests.nix index af58184ca6..628cd89f72 100644 --- a/e2e/all-tests.nix +++ b/e2e/all-tests.nix @@ -23,7 +23,7 @@ ... }: let - full-e2e = import ./full-e2e.nix { inherit e2e pkgs self'; }; + union-test = import ./union-test.nix { inherit e2e pkgs self'; }; epoch-staking = import ./epoch-staking.nix { inherit e2e pkgs dbg; }; upgrades = import ./upgrades.nix { inherit e2e pkgs; @@ -36,8 +36,8 @@ # TODO: Fix Ensure Blocks Workflow unionlabs/union#2067 # ensure-blocks = import ./ensure-blocks/ensure-blocks.nix { inherit e2e networks pkgs nixpkgs crane; }; # - # Tests from ./full-e2e.nix - inherit (full-e2e) all-works; + # Tests from ./union-test.nix + inherit (union-test) lst; # Tests from ./epoch-staking.nix inherit (epoch-staking) epoch-completes; diff --git a/e2e/e2e.nix b/e2e/e2e.nix index c967db2de2..3645004f2d 100644 --- a/e2e/e2e.nix +++ b/e2e/e2e.nix @@ -129,6 +129,7 @@ unionNode unionTestnetGenesisNode devnetEthNode + mkVoyagerNode ; # TODO: This is poorly named, it only starts devnet-union and devnet-eth @@ -168,19 +169,28 @@ }; mkE2eTestEthUnion = + voyagerConfigFile: { name, testScript, nodes ? { }, + openConnection ? false }: let - voyagerNode = mkVoyagerNode ../tools/union-test/config.jsonc; + voyagerNode = mkVoyagerNode voyagerConfigFile; voyagerBin = "${self'.packages.voyager}/bin/voyager"; in mkTest { inherit name; testScript = '' + openConnection = ${if openConnection then "True" else "False"} + + if openConnection: + print("ananabacina") + else: + print("teyzeneamcana...") + devnetUnion.wait_for_open_port(${toString unionNode.wait_for_open_port}) devnetEth.wait_for_open_port(${toString devnetEthNode.wait_for_open_port}) @@ -201,23 +211,17 @@ devnetVoyager.wait_until_succeeds('sleep 10') - devnetVoyager.succeed( - "echo '{\"@type\":\"call\",\"@value\":{\"@type\":\"submit_tx\",\"@value\":{\"chain_id\":\"union-devnet-1\",\"datagrams\":[{\"ibc_spec_id\":\"ibc-union\",\"datagram\":{\"@type\":\"connection_open_init\",\"@value\":{\"client_id\":1,\"counterparty_client_id\":1}}}]}}}' > /tmp/payload.json" - ) - - devnetVoyager.wait_until_succeeds("${voyagerBin} -c ${voyagerNode.voyagerConfig} q e $(cat /tmp/payload.json)") - - # wait until the connection is opened - devnetVoyager.wait_until_succeeds("[[ $(${voyagerBin} rpc ibc-state 32382 '{ \"connection\": { \"connection_id\": 1 } }' | jq '.state.state == \"open\"') == true ]]") - - devnetVoyager.succeed( - "echo '{\"@type\":\"call\",\"@value\":{\"@type\":\"submit_tx\",\"@value\":{\"chain_id\":\"32382\",\"datagrams\":[{\"ibc_spec_id\":\"ibc-union\",\"datagram\":{\"@type\":\"channel_open_init\",\"@value\":{\"counterparty_port_id\":\"0x756e696f6e3172667a33797467366c363077786b357278736b32376a766e32393037637961763034737a386b64653378686d6d66396e706c7871723879303563\",\"port_id\":\"0x05FD55C1AbE31D3ED09A76216cA8F0372f4B2eC5\",\"connection_id\":1,\"version\":\"ucs03-zkgm-0\"}}}]}}}' > /tmp/payload.json" - ) + if openConnection: + devnetVoyager.succeed( + "echo '{\"@type\":\"call\",\"@value\":{\"@type\":\"submit_tx\",\"@value\":{\"chain_id\":\"union-devnet-1\",\"datagrams\":[{\"ibc_spec_id\":\"ibc-union\",\"datagram\":{\"@type\":\"connection_open_init\",\"@value\":{\"client_id\":1,\"counterparty_client_id\":1}}}]}}}' > /tmp/payload.json" + ) - devnetVoyager.wait_until_succeeds("${voyagerBin} -c ${voyagerNode.voyagerConfig} q e $(cat /tmp/payload.json)") + devnetVoyager.wait_until_succeeds("${voyagerBin} -c ${voyagerNode.voyagerConfig} q e $(cat /tmp/payload.json)") - # wait until the channel is opened - devnetVoyager.wait_until_succeeds("[[ $(${voyagerBin} rpc ibc-state 32382 '{ \"channel\": { \"channel_id\": 1 } }' | jq '.state.state == \"open\"') == true ]]") + # wait until the connection is opened + devnetVoyager.wait_until_succeeds("[[ $(${voyagerBin} rpc ibc-state 32382 '{ \"connection\": { \"connection_id\": 1 } }' | jq '.state.state == \"open\"') == true ]]") + else: + print("Skipping connection...") ${testScript} ''; diff --git a/e2e/full-e2e.nix b/e2e/union-test.nix similarity index 79% rename from e2e/full-e2e.nix rename to e2e/union-test.nix index fb7b9d0620..e1ec2d0b69 100644 --- a/e2e/full-e2e.nix +++ b/e2e/union-test.nix @@ -3,11 +3,25 @@ self', ... }: +let + voyagerConfigFile = ../tools/union-test/config.jsonc; + voyagerNode = e2e.mkVoyagerNode voyagerConfigFile; + voyagerBin = "${self'.packages.voyager}/bin/voyager"; +in { - all-works = e2e.mkE2eTestEthUnion { - name = "all-works"; + lst = e2e.mkE2eTestEthUnion voyagerConfigFile { + name = "lst"; testScript = '' + devnetVoyager.succeed( + "echo '{\"@type\":\"call\",\"@value\":{\"@type\":\"submit_tx\",\"@value\":{\"chain_id\":\"32382\",\"datagrams\":[{\"ibc_spec_id\":\"ibc-union\",\"datagram\":{\"@type\":\"channel_open_init\",\"@value\":{\"counterparty_port_id\":\"0x756e696f6e3172667a33797467366c363077786b357278736b32376a766e32393037637961763034737a386b64653378686d6d66396e706c7871723879303563\",\"port_id\":\"0x05FD55C1AbE31D3ED09A76216cA8F0372f4B2eC5\",\"connection_id\":1,\"version\":\"ucs03-zkgm-0\"}}}]}}}' > /tmp/payload.json" + ) + + devnetVoyager.wait_until_succeeds("${voyagerBin} -c ${voyagerNode.voyagerConfig} q e $(cat /tmp/payload.json)") + + # wait until the channel is opened + devnetVoyager.wait_until_succeeds("[[ $(${voyagerBin} rpc ibc-state 32382 '{ \"channel\": { \"channel_id\": 1 } }' | jq '.state.state == \"open\"') == true ]]") + devnetUnion.wait_until_succeeds("${self'.packages.cosmwasm-deployer}/bin/cosmwasm-deployer deploy-contract --rpc-url http://devnetUnion:26657 --private-key 0xaa820fa947beb242032a41b6dc9a8b9c37d8f5fbcda0966b1ec80335b10a7d6f --bytecode ${self'.packages.lst-staker} --init-msg '{ \"local\": { \"admin\": \"union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2\" } }' --salt apps/lst-staker --gas feemarket --max-gas 100000000 --gas-multiplier 1.4") devnetUnion.wait_until_succeeds("${self'.packages.cosmwasm-deployer}/bin/cosmwasm-deployer deploy-contract --rpc-url http://devnetUnion:26657 --private-key 0xaa820fa947beb242032a41b6dc9a8b9c37d8f5fbcda0966b1ec80335b10a7d6f --bytecode ${self'.packages.lst} --init-msg '{ \"native_token_denom\": \"au\", \"minimum_liquid_stake_amount\": \"10\", \"staker_address\": \"union160a75a608j6w80x5ykckvd9cavs2xk8yfjzy2eqhpq0nprxg05qqf067nj\", \"protocol_fee_config\": {\"fee_rate\": \"10000\", \"fee_recipient\": \"union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2\" }, \"lst_address\": \"union1nluwd0qfymmdwfczezvgrmvz43n4xwdyfvshxj82sj7smuk9m42stgfwcz\", \"batch_period_seconds\": \"20\", \"monitors\": [], \"admin\": \"union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2\", \"unbonding_period_seconds\": \"100\" }' --salt apps/lst --gas feemarket --max-gas 100000000 --gas-multiplier 1.4") @@ -62,7 +76,5 @@ devnetUnion.wait_until_succeeds("RUST_LOG=info ${self'.packages.e2e-lst-tests}/lst --nocapture 1>&2") ''; - nodes = { - }; }; } diff --git a/garnix.yaml b/garnix.yaml index 9eb2c2d62a..a0dc76fa94 100644 --- a/garnix.yaml +++ b/garnix.yaml @@ -15,7 +15,7 @@ builds: - 'checks.aarch64-linux.nil' - 'checks.aarch64-linux.ssz-tests-up-to-date' - 'checks.*.all-crates-buildable-individually' - - 'checks.*.all-works' + - 'checks.*.lst' - 'checks.*.devnet-eth-runs' - 'checks.*.ensure-blocks' - 'checks.*.epoch-completes' @@ -73,7 +73,7 @@ builds: - 'nixosConfigurations.*' exclude: - 'checks.*.all-crates-buildable-individually' - - 'checks.*.all-works' + - 'checks.*.lst' - 'checks.*.devnet-eth-runs' - 'checks.*.ensure-blocks' - 'checks.*.epoch-completes' diff --git a/tools/union-test/src/evm.rs b/tools/union-test/src/evm.rs index 68669a672b..842cf7c873 100644 --- a/tools/union-test/src/evm.rs +++ b/tools/union-test/src/evm.rs @@ -784,7 +784,6 @@ impl Module { max: self.max_gas_price.expect("max gas price is set"), price: gas_price, }); - } else { } } diff --git a/tools/union-test/tests/e2e.nix b/tools/union-test/tests/e2e.nix index 41b842e608..92972481f1 100644 --- a/tools/union-test/tests/e2e.nix +++ b/tools/union-test/tests/e2e.nix @@ -1,5 +1,4 @@ -_: -{ +_: { perSystem = { crane, diff --git a/tools/union-test/tests/lst_common/mod.rs b/tools/union-test/tests/lst_common/mod.rs index 4ecbd8f18a..e817b13146 100644 --- a/tools/union-test/tests/lst_common/mod.rs +++ b/tools/union-test/tests/lst_common/mod.rs @@ -33,6 +33,7 @@ pub static CTX: OnceCell<(Mutex, Arc)> = OnceCell::const_new( pub const ETH_ADDRESS_U: H160 = H160::new(hex!("0c8C6f58156D10d18193A8fFdD853e1b9F8D8836")); pub const ETH_ADDRESS_ZKGM: H160 = H160::new(hex!("05FD55C1AbE31D3ED09A76216cA8F0372f4B2eC5")); +#[allow(unused)] pub struct UnionAddressBook { pub zkgm: Addr, pub lst_hub: Addr, From 4e3bfa80ffe0fb20708a7700b0f3e2e37ce9955e Mon Sep 17 00:00:00 2001 From: aeryz Date: Wed, 8 Oct 2025 11:51:06 +0300 Subject: [PATCH 29/33] chore: docs Signed-off-by: aeryz --- e2e/e2e.nix | 13 +++++++------ e2e/union-test.nix | 11 ++++++++++- tools/union-test/tests/lst_common/mod.rs | 3 --- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/e2e/e2e.nix b/e2e/e2e.nix index 3645004f2d..89fd8c89ac 100644 --- a/e2e/e2e.nix +++ b/e2e/e2e.nix @@ -174,7 +174,7 @@ name, testScript, nodes ? { }, - openConnection ? false + openConnection ? false, }: let voyagerNode = mkVoyagerNode voyagerConfigFile; @@ -186,29 +186,30 @@ testScript = '' openConnection = ${if openConnection then "True" else "False"} - if openConnection: - print("ananabacina") - else: - print("teyzeneamcana...") - devnetUnion.wait_for_open_port(${toString unionNode.wait_for_open_port}) devnetEth.wait_for_open_port(${toString devnetEthNode.wait_for_open_port}) + # deploy contract on union devnetUnion.succeed('${self'.packages.cosmwasm-scripts.union-devnet.deploy}/bin/union-devnet-deploy-full') # match non-zero blocks devnetUnion.wait_until_succeeds('[[ $(curl "http://localhost:26657/block" --fail --silent | ${pkgs.lib.meta.getExe pkgs.jq} ".result.block.header.height | tonumber > 1") == "true" ]]') + + # we are waiting until slot 20 so that we are sure that the contracts are deployed devnetEth.wait_until_succeeds('[[ $(curl http://localhost:9596/eth/v2/beacon/blocks/head --fail --silent | ${pkgs.lib.meta.getExe pkgs.jq} \'.data.message.slot | tonumber > 20\') == "true" ]]') devnetVoyager.wait_for_open_port(${toString voyagerNode.wait_for_open_port}) devnetVoyager.wait_until_succeeds('${voyagerBin} rpc info') + # index the chains on voyager devnetVoyager.wait_until_succeeds('${voyagerBin} -c ${voyagerNode.voyagerConfig} index union-devnet-1 -e') devnetVoyager.wait_until_succeeds('${voyagerBin} -c ${voyagerNode.voyagerConfig} index 32382 -e') + # create clients devnetVoyager.wait_until_succeeds('${voyagerBin} -c ${voyagerNode.voyagerConfig} msg create-client --on union-devnet-1 --tracking 32382 --ibc-interface ibc-cosmwasm --ibc-spec-id ibc-union --client-type trusted/evm/mpt -e') devnetVoyager.wait_until_succeeds('${voyagerBin} -c ${voyagerNode.voyagerConfig} msg create-client --on 32382 --tracking union-devnet-1 --ibc-interface ibc-solidity --ibc-spec-id ibc-union --client-type cometbls -e') + # give some time for the clients to be created devnetVoyager.wait_until_succeeds('sleep 10') if openConnection: diff --git a/e2e/union-test.nix b/e2e/union-test.nix index e1ec2d0b69..5a5c478e4a 100644 --- a/e2e/union-test.nix +++ b/e2e/union-test.nix @@ -12,7 +12,10 @@ in lst = e2e.mkE2eTestEthUnion voyagerConfigFile { name = "lst"; + openConnection = true; + testScript = '' + # open a channel since the lst tests require only 1 channel devnetVoyager.succeed( "echo '{\"@type\":\"call\",\"@value\":{\"@type\":\"submit_tx\",\"@value\":{\"chain_id\":\"32382\",\"datagrams\":[{\"ibc_spec_id\":\"ibc-union\",\"datagram\":{\"@type\":\"channel_open_init\",\"@value\":{\"counterparty_port_id\":\"0x756e696f6e3172667a33797467366c363077786b357278736b32376a766e32393037637961763034737a386b64653378686d6d66396e706c7871723879303563\",\"port_id\":\"0x05FD55C1AbE31D3ED09A76216cA8F0372f4B2eC5\",\"connection_id\":1,\"version\":\"ucs03-zkgm-0\"}}}]}}}' > /tmp/payload.json" ) @@ -22,12 +25,16 @@ in # wait until the channel is opened devnetVoyager.wait_until_succeeds("[[ $(${voyagerBin} rpc ibc-state 32382 '{ \"channel\": { \"channel_id\": 1 } }' | jq '.state.state == \"open\"') == true ]]") + # deploy lst staker devnetUnion.wait_until_succeeds("${self'.packages.cosmwasm-deployer}/bin/cosmwasm-deployer deploy-contract --rpc-url http://devnetUnion:26657 --private-key 0xaa820fa947beb242032a41b6dc9a8b9c37d8f5fbcda0966b1ec80335b10a7d6f --bytecode ${self'.packages.lst-staker} --init-msg '{ \"local\": { \"admin\": \"union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2\" } }' --salt apps/lst-staker --gas feemarket --max-gas 100000000 --gas-multiplier 1.4") + # deploy lst devnetUnion.wait_until_succeeds("${self'.packages.cosmwasm-deployer}/bin/cosmwasm-deployer deploy-contract --rpc-url http://devnetUnion:26657 --private-key 0xaa820fa947beb242032a41b6dc9a8b9c37d8f5fbcda0966b1ec80335b10a7d6f --bytecode ${self'.packages.lst} --init-msg '{ \"native_token_denom\": \"au\", \"minimum_liquid_stake_amount\": \"10\", \"staker_address\": \"union160a75a608j6w80x5ykckvd9cavs2xk8yfjzy2eqhpq0nprxg05qqf067nj\", \"protocol_fee_config\": {\"fee_rate\": \"10000\", \"fee_recipient\": \"union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2\" }, \"lst_address\": \"union1nluwd0qfymmdwfczezvgrmvz43n4xwdyfvshxj82sj7smuk9m42stgfwcz\", \"batch_period_seconds\": \"20\", \"monitors\": [], \"admin\": \"union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2\", \"unbonding_period_seconds\": \"100\" }' --salt apps/lst --gas feemarket --max-gas 100000000 --gas-multiplier 1.4") + # deploy eU devnetUnion.wait_until_succeeds("${self'.packages.cosmwasm-deployer}/bin/cosmwasm-deployer deploy-contract --rpc-url http://devnetUnion:26657 --private-key 0xaa820fa947beb242032a41b6dc9a8b9c37d8f5fbcda0966b1ec80335b10a7d6f --bytecode ${self'.packages.cw-unionversal-token} --init-msg '{ \"zkgm\": \"union1rfz3ytg6l60wxk5rxsk27jvn2907cyav04sz8kde3xhmmf9nplxqr8y05c\", \"admin\": \"union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2\", \"cw20_init\": { \"cw20\": { \"name\": \"eU\", \"symbol\": \"eU\", \"decimals\": 6, \"initial_balances\": [], \"mint\": {\"minter\": \"union1qg3gm3f87w6al9u9ldkqhjdeaxrd0tae5w70les88egql8nzp95qs5rrz0\"} } }, \"extra_minters\": [] }' --salt tokens/eu --gas feemarket --max-gas 100000000 --gas-multiplier 1.4") + # set the fungible counterparty for U on union devnetUnion.wait_until_succeeds("\ ${self'.packages.uniond}/bin/uniond tx \ wasm execute \ @@ -43,6 +50,7 @@ in --gas-prices 1au\ ") + # set the validators on the staker devnetUnion.wait_until_succeeds("\ ${self'.packages.uniond}/bin/uniond tx \ wasm execute \ @@ -58,6 +66,7 @@ in --gas-prices 1au\ ") + # set the lst hub address on staker devnetUnion.wait_until_succeeds("\ ${self'.packages.uniond}/bin/uniond tx \ wasm execute \ @@ -73,8 +82,8 @@ in --gas-prices 1au\ ") + # run the tests, note that we do `1>&2` because otherwise we won't get the full prints devnetUnion.wait_until_succeeds("RUST_LOG=info ${self'.packages.e2e-lst-tests}/lst --nocapture 1>&2") ''; - }; } diff --git a/tools/union-test/tests/lst_common/mod.rs b/tools/union-test/tests/lst_common/mod.rs index e817b13146..c0d251d89b 100644 --- a/tools/union-test/tests/lst_common/mod.rs +++ b/tools/union-test/tests/lst_common/mod.rs @@ -85,7 +85,6 @@ pub async fn run_test_in_queue< let src = cosmos::Module::new(cfg.union).await.unwrap(); let dst = evm::Module::new(cfg.evm).await.unwrap(); - println!("[2] LST: AFTER PARSING CONFIG"); let ctx = TestContext::new( src, @@ -138,10 +137,8 @@ pub async fn run_test_in_queue< loop { { - println!("LST RUNNING TEST BRO????"); let mut lock = ctx.0.lock().await; if lock.tests.last().unwrap() == key { - println!("LST RUNNING SPECIFIC TEST: {key}"); lock.shared_data = test_fn(ctx.1.clone(), lock.shared_data.clone()).await; let _ = lock.tests.pop(); return; From 4952fd395c9c75ba573d72e814554afb17b1f2fa Mon Sep 17 00:00:00 2001 From: aeryz Date: Wed, 8 Oct 2025 13:08:03 +0300 Subject: [PATCH 30/33] chore: final fix Signed-off-by: aeryz --- Cargo.lock | 937 ++++++++++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 96 +++--- 2 files changed, 977 insertions(+), 56 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33be2fbdfd..ed293afacd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15751,6 +15751,61 @@ dependencies = [ "voyager-vm", ] +[[package]] +name = "voyager-client-bootstrap-module-arbitrum" +version = "0.0.0" +dependencies = [ + "alloy", + "arbitrum-client", + "arbitrum-light-client-types", + "embed-commit", + "ibc-union-spec", + "jsonrpsee 0.25.1", + "serde", + "serde_json", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-client-bootstrap-module-base" +version = "0.0.0" +dependencies = [ + "alloy", + "base-light-client-types", + "embed-commit", + "ibc-union-spec", + "jsonrpsee 0.25.1", + "serde", + "serde_json", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-client-bootstrap-module-bob" +version = "0.0.0" +dependencies = [ + "alloy", + "bob-client", + "bob-light-client-types", + "bob-types", + "bob-verifier", + "embed-commit", + "ibc-union-spec", + "jsonrpsee 0.25.1", + "serde", + "serde_json", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + [[package]] name = "voyager-client-bootstrap-module-cometbls" version = "0.0.0" @@ -15769,6 +15824,168 @@ dependencies = [ "voyager-sdk", ] +[[package]] +name = "voyager-client-bootstrap-module-ethereum" +version = "0.0.0" +dependencies = [ + "alloy", + "beacon-api", + "beacon-api-types", + "embed-commit", + "ethereum-light-client-types", + "ethereum-sync-protocol-types", + "jsonrpsee 0.25.1", + "serde", + "serde_json", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-client-bootstrap-module-ethermint" +version = "0.0.0" +dependencies = [ + "cometbft-rpc", + "embed-commit", + "ethermint-light-client-types", + "ics23", + "jsonrpsee 0.25.1", + "prost 0.12.6", + "protos", + "serde", + "serde_json", + "tendermint-light-client-types", + "thiserror 2.0.12", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-client-bootstrap-module-parlia" +version = "0.0.0" +dependencies = [ + "alloy", + "embed-commit", + "ibc-union-spec", + "jsonrpsee 0.25.1", + "parlia-light-client-types", + "parlia-types", + "parlia-verifier", + "serde", + "serde_json", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-client-bootstrap-module-state-lens-ics23-ics23" +version = "0.0.0" +dependencies = [ + "alloy", + "beacon-api", + "beacon-api-types", + "cometbft-rpc", + "embed-commit", + "ibc-union-spec", + "jsonrpsee 0.25.1", + "serde", + "serde_json", + "state-lens-ics23-ics23-light-client-types", + "tendermint-light-client-types", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-client-bootstrap-module-state-lens-ics23-mpt" +version = "0.0.0" +dependencies = [ + "alloy", + "beacon-api", + "beacon-api-types", + "cometbft-rpc", + "embed-commit", + "ibc-union-spec", + "jsonrpsee 0.25.1", + "serde", + "serde_json", + "state-lens-ics23-mpt-light-client", + "state-lens-ics23-mpt-light-client-types", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-client-bootstrap-module-state-lens-ics23-smt" +version = "0.0.0" +dependencies = [ + "alloy", + "beacon-api", + "beacon-api-types", + "cometbft-rpc", + "embed-commit", + "ibc-union-spec", + "jsonrpsee 0.25.1", + "movement-light-client-types", + "serde", + "serde_json", + "state-lens-ics23-smt-light-client-types", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-client-bootstrap-module-sui" +version = "0.0.0" +dependencies = [ + "bcs", + "cosmwasm-std", + "embed-commit", + "hex-literal 0.4.1", + "jsonrpsee 0.25.1", + "reqwest 0.11.27", + "serde", + "serde_json", + "sui-light-client-types", + "sui-sdk", + "thiserror 2.0.12", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-client-bootstrap-module-tendermint" +version = "0.0.0" +dependencies = [ + "cometbft-rpc", + "embed-commit", + "ics23", + "jsonrpsee 0.25.1", + "protos", + "serde", + "serde_json", + "tendermint-light-client-types", + "thiserror 2.0.12", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + [[package]] name = "voyager-client-bootstrap-module-trusted-mpt" version = "0.0.0" @@ -15786,6 +16003,54 @@ dependencies = [ "voyager-sdk", ] +[[package]] +name = "voyager-client-module-arbitrum" +version = "0.0.0" +dependencies = [ + "arbitrum-light-client-types", + "embed-commit", + "ethereum-light-client-types", + "jsonrpsee 0.25.1", + "serde", + "serde_json", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-client-module-base" +version = "0.0.0" +dependencies = [ + "base-light-client-types", + "embed-commit", + "ethereum-light-client-types", + "jsonrpsee 0.25.1", + "serde", + "serde_json", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-client-module-bob" +version = "0.0.0" +dependencies = [ + "bob-light-client-types", + "embed-commit", + "ethereum-light-client-types", + "jsonrpsee 0.25.1", + "serde", + "serde_json", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + [[package]] name = "voyager-client-module-cometbls" version = "0.0.0" @@ -15810,7 +16075,7 @@ dependencies = [ ] [[package]] -name = "voyager-client-module-trusted-mpt" +name = "voyager-client-module-ethereum" version = "0.0.0" dependencies = [ "embed-commit", @@ -15820,21 +16085,274 @@ dependencies = [ "serde_json", "tokio", "tracing", - "trusted-mpt-light-client-types", "unionlabs", "voyager-sdk", ] [[package]] -name = "voyager-client-update-plugin-cometbls" +name = "voyager-client-module-ethermint" version = "0.0.0" dependencies = [ - "cometbft-rpc", - "cometbft-types", - "cometbls-light-client-types", "embed-commit", - "enumorph", - "galois-rpc", + "ethermint-light-client-types", + "jsonrpsee 0.25.1", + "macros", + "serde", + "serde_json", + "tendermint-light-client-types", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-client-module-parlia" +version = "0.0.0" +dependencies = [ + "embed-commit", + "ethereum-light-client-types", + "jsonrpsee 0.25.1", + "parlia-light-client-types", + "serde", + "serde_json", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-client-module-state-lens-ics23-ics23" +version = "0.0.0" +dependencies = [ + "alloy-sol-types", + "embed-commit", + "futures", + "jsonrpsee 0.25.1", + "macros", + "protos", + "serde", + "serde_json", + "state-lens-ics23-ics23-light-client-types", + "state-lens-light-client-types", + "thiserror 2.0.12", + "tokio", + "tracing", + "tracing-subscriber", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-client-module-state-lens-ics23-mpt" +version = "0.0.0" +dependencies = [ + "alloy-sol-types", + "beacon-api-types", + "embed-commit", + "enumorph", + "ethereum-light-client-types", + "futures", + "jsonrpsee 0.25.1", + "macros", + "prost 0.12.6", + "serde", + "serde-utils", + "serde_json", + "state-lens-ics23-mpt-light-client-types", + "state-lens-light-client-types", + "thiserror 2.0.12", + "tokio", + "tracing", + "tracing-subscriber", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-client-module-state-lens-ics23-smt" +version = "0.0.0" +dependencies = [ + "alloy-sol-types", + "embed-commit", + "enumorph", + "ethereum-light-client-types", + "futures", + "jsonrpsee 0.25.1", + "macros", + "prost 0.12.6", + "serde", + "serde-utils", + "serde_json", + "state-lens-ics23-smt-light-client-types", + "state-lens-light-client-types", + "thiserror 2.0.12", + "tokio", + "tracing", + "tracing-subscriber", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-client-module-sui" +version = "0.0.0" +dependencies = [ + "embed-commit", + "jsonrpsee 0.25.1", + "serde", + "serde_json", + "sui-light-client-types", + "thiserror 2.0.12", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-client-module-tendermint" +version = "0.0.0" +dependencies = [ + "embed-commit", + "jsonrpsee 0.25.1", + "macros", + "serde", + "serde_json", + "tendermint-light-client-types", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-client-module-trusted-mpt" +version = "0.0.0" +dependencies = [ + "embed-commit", + "ethereum-light-client-types", + "jsonrpsee 0.25.1", + "serde", + "serde_json", + "tokio", + "tracing", + "trusted-mpt-light-client-types", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-client-update-plugin-arbitrum" +version = "0.0.0" +dependencies = [ + "alloy", + "arbitrum-client", + "arbitrum-light-client-types", + "arbitrum-types", + "embed-commit", + "enumorph", + "ethereum-light-client-types", + "ibc-union-spec", + "jsonrpsee 0.25.1", + "macros", + "serde", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-client-update-plugin-base" +version = "0.0.0" +dependencies = [ + "alloy", + "base-client", + "base-light-client-types", + "base-verifier", + "bob-types", + "embed-commit", + "enumorph", + "ethereum-light-client-types", + "futures", + "ibc-union-spec", + "jsonrpsee 0.25.1", + "macros", + "serde", + "serde_json", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-client-update-plugin-berachain" +version = "0.0.0" +dependencies = [ + "alloy", + "beacon-api-types", + "berachain-light-client-types", + "cometbft-rpc", + "cometbft-types", + "dashmap 5.5.3", + "embed-commit", + "enumorph", + "ethereum-light-client-types", + "futures", + "ics23", + "jsonrpsee 0.25.1", + "macros", + "num-bigint 0.4.6", + "prost 0.12.6", + "protos", + "serde", + "serde_json", + "ssz", + "thiserror 2.0.12", + "tokio", + "tracing", + "tracing-subscriber", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-client-update-plugin-bob" +version = "0.0.0" +dependencies = [ + "alloy", + "bob-client", + "bob-light-client-types", + "bob-types", + "bob-verifier", + "embed-commit", + "enumorph", + "ethereum-light-client-types", + "futures", + "ibc-union-spec", + "jsonrpsee 0.25.1", + "macros", + "serde", + "serde_json", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-client-update-plugin-cometbls" +version = "0.0.0" +dependencies = [ + "cometbft-rpc", + "cometbft-types", + "cometbls-light-client-types", + "embed-commit", + "enumorph", + "galois-rpc", "jsonrpsee 0.25.1", "macros", "num-bigint 0.4.6", @@ -15848,6 +16366,137 @@ dependencies = [ "voyager-sdk", ] +[[package]] +name = "voyager-client-update-plugin-ethereum" +version = "0.0.0" +dependencies = [ + "alloy", + "beacon-api", + "beacon-api-types", + "bitvec 1.0.1", + "embed-commit", + "enumorph", + "ethereum-light-client-types", + "ethereum-sync-protocol-types", + "futures", + "jsonrpsee 0.25.1", + "macros", + "serde", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-client-update-plugin-ethermint" +version = "0.0.0" +dependencies = [ + "cometbft-rpc", + "cometbft-types", + "embed-commit", + "enumorph", + "ethermint-light-client-types", + "jsonrpsee 0.25.1", + "macros", + "serde", + "serde_json", + "tendermint-light-client-types", + "thiserror 2.0.12", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-client-update-plugin-parlia" +version = "0.0.0" +dependencies = [ + "alloy", + "embed-commit", + "enumorph", + "ethereum-light-client-types", + "futures", + "ibc-union-spec", + "jsonrpsee 0.25.1", + "macros", + "parlia-light-client-types", + "parlia-types", + "parlia-verifier", + "serde", + "serde_json", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-client-update-plugin-state-lens" +version = "0.0.0" +dependencies = [ + "alloy", + "embed-commit", + "enumorph", + "ibc-union-spec", + "ics23", + "jsonrpsee 0.25.1", + "macros", + "protos", + "serde", + "serde_json", + "state-lens-light-client-types", + "tokio", + "tracing", + "tracing-subscriber", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-client-update-plugin-sui" +version = "0.0.0" +dependencies = [ + "bcs", + "embed-commit", + "enumorph", + "hex-literal 0.4.1", + "jsonrpsee 0.25.1", + "macros", + "reqwest 0.11.27", + "serde", + "serde_json", + "subset-of", + "sui-light-client-types", + "sui-sdk", + "thiserror 2.0.12", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-client-update-plugin-tendermint" +version = "0.0.0" +dependencies = [ + "cometbft-rpc", + "cometbft-types", + "embed-commit", + "enumorph", + "jsonrpsee 0.25.1", + "macros", + "serde", + "serde_json", + "tendermint-light-client-types", + "thiserror 2.0.12", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + [[package]] name = "voyager-client-update-plugin-trusted-mpt" version = "0.0.0" @@ -15959,6 +16608,107 @@ dependencies = [ "voyager-sdk", ] +[[package]] +name = "voyager-event-source-plugin-sui" +version = "0.0.0" +dependencies = [ + "anyhow", + "bcs", + "clap", + "embed-commit", + "enumorph", + "ibc-solidity", + "ibc-union-spec", + "jsonrpsee 0.25.1", + "macros", + "serde", + "serde_json", + "sui-light-client-types", + "sui-sdk", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-finality-module-arbitrum" +version = "0.0.0" +dependencies = [ + "alloy", + "arbitrum-client", + "arbitrum-types", + "embed-commit", + "ibc-union-spec", + "jsonrpsee 0.25.1", + "serde", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-finality-module-base" +version = "0.0.0" +dependencies = [ + "alloy", + "base-client", + "embed-commit", + "ibc-union-spec", + "jsonrpsee 0.25.1", + "serde", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-finality-module-berachain" +version = "0.0.0" +dependencies = [ + "alloy", + "beacon-api-types", + "berachain-light-client-types", + "cometbft-rpc", + "dashmap 5.5.3", + "embed-commit", + "enumorph", + "futures", + "ics23", + "jsonrpsee 0.25.1", + "macros", + "num-bigint 0.4.6", + "prost 0.12.6", + "protos", + "serde", + "serde_json", + "tendermint-light-client-types", + "thiserror 2.0.12", + "tokio", + "tracing", + "tracing-subscriber", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-finality-module-bob" +version = "0.0.0" +dependencies = [ + "alloy", + "bob-client", + "embed-commit", + "ibc-union-spec", + "jsonrpsee 0.25.1", + "serde", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + [[package]] name = "voyager-finality-module-cometbls" version = "0.0.0" @@ -15974,6 +16724,71 @@ dependencies = [ "voyager-sdk", ] +[[package]] +name = "voyager-finality-module-ethereum" +version = "0.0.0" +dependencies = [ + "alloy", + "beacon-api", + "beacon-api-types", + "embed-commit", + "jsonrpsee 0.25.1", + "moka", + "serde", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-finality-module-parlia" +version = "0.0.0" +dependencies = [ + "alloy", + "embed-commit", + "ibc-union-spec", + "jsonrpsee 0.25.1", + "parlia-light-client-types", + "parlia-types", + "parlia-verifier", + "serde", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-finality-module-sui" +version = "0.0.0" +dependencies = [ + "embed-commit", + "jsonrpsee 0.25.1", + "serde", + "sui-sdk", + "thiserror 2.0.12", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-finality-module-tendermint" +version = "0.0.0" +dependencies = [ + "cometbft-rpc", + "embed-commit", + "jsonrpsee 0.25.1", + "serde", + "thiserror 2.0.12", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + [[package]] name = "voyager-finality-module-trusted-evm" version = "0.0.0" @@ -16205,6 +17020,26 @@ dependencies = [ "unionlabs", ] +[[package]] +name = "voyager-proof-module-cosmos-sdk" +version = "0.0.0" +dependencies = [ + "clap", + "cometbft-rpc", + "embed-commit", + "ibc-classic-spec", + "jsonrpsee 0.25.1", + "prost 0.12.6", + "protos", + "serde", + "serde_json", + "thiserror 2.0.12", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + [[package]] name = "voyager-proof-module-cosmos-sdk-union" version = "0.0.0" @@ -16242,6 +17077,49 @@ dependencies = [ "voyager-sdk", ] +[[package]] +name = "voyager-proof-module-ethermint" +version = "0.0.0" +dependencies = [ + "clap", + "cometbft-rpc", + "embed-commit", + "ibc-union-spec", + "jsonrpsee 0.25.1", + "prost 0.12.6", + "protos", + "serde", + "serde_json", + "thiserror 2.0.12", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + +[[package]] +name = "voyager-proof-module-sui" +version = "0.0.0" +dependencies = [ + "bcs", + "clap", + "embed-commit", + "ibc-union-spec", + "jsonrpsee 0.25.1", + "move-core-types", + "reqwest 0.11.27", + "serde", + "serde_json", + "sui-light-client-types", + "sui-sdk", + "sui-verifier", + "tokio", + "tracing", + "unionlabs", + "voyager-message", + "voyager-sdk", +] + [[package]] name = "voyager-rpc" version = "0.0.0" @@ -16296,6 +17174,26 @@ dependencies = [ "voyager-vm", ] +[[package]] +name = "voyager-state-module-cosmos-sdk" +version = "0.0.0" +dependencies = [ + "clap", + "cometbft-rpc", + "embed-commit", + "ibc-classic-spec", + "jsonrpsee 0.25.1", + "protos", + "serde", + "serde-utils", + "serde_json", + "thiserror 2.0.12", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + [[package]] name = "voyager-state-module-cosmos-sdk-union" version = "0.0.0" @@ -16338,6 +17236,29 @@ dependencies = [ "voyager-sdk", ] +[[package]] +name = "voyager-state-module-sui" +version = "0.0.0" +dependencies = [ + "bcs", + "clap", + "embed-commit", + "enumorph", + "hex-literal 0.4.1", + "ibc-solidity", + "ibc-union-spec", + "jsonrpsee 0.25.1", + "macros", + "reqwest 0.11.27", + "serde", + "serde_json", + "sui-sdk", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + [[package]] name = "voyager-sui-ibc-app-plugin-zkgm" version = "0.0.0" diff --git a/Cargo.toml b/Cargo.toml index 96d26deff2..37b33a1bcb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -138,73 +138,73 @@ members = [ "lib/voyager-core", "lib/voyager-primitives", - # "voyager/modules/state/cosmos-sdk", + "voyager/modules/state/cosmos-sdk", "voyager/modules/state/cosmos-sdk-union", "voyager/modules/state/ethereum", # "voyager/modules/state/movement", - # "voyager/modules/state/sui", + "voyager/modules/state/sui", - # "voyager/modules/proof/cosmos-sdk", + "voyager/modules/proof/cosmos-sdk", "voyager/modules/proof/cosmos-sdk-union", - # "voyager/modules/proof/ethermint", + "voyager/modules/proof/ethermint", "voyager/modules/proof/ethereum", # "voyager/modules/proof/movement", - # "voyager/modules/proof/sui", + "voyager/modules/proof/sui", - # "voyager/modules/client/base", - # "voyager/modules/client/bob", - # "voyager/modules/client/arbitrum", + "voyager/modules/client/base", + "voyager/modules/client/bob", + "voyager/modules/client/arbitrum", "voyager/modules/client/cometbls", - # "voyager/modules/client/ethereum", + "voyager/modules/client/ethereum", # "voyager/modules/client/movement", - # "voyager/modules/client/parlia", - # "voyager/modules/client/tendermint", - # "voyager/modules/client/ethermint", - # "voyager/modules/client/state-lens/ics23-mpt", - # "voyager/modules/client/state-lens/ics23-ics23", - # "voyager/modules/client/state-lens/ics23-smt", - # "voyager/modules/client/sui", + "voyager/modules/client/parlia", + "voyager/modules/client/tendermint", + "voyager/modules/client/ethermint", + "voyager/modules/client/state-lens/ics23-mpt", + "voyager/modules/client/state-lens/ics23-ics23", + "voyager/modules/client/state-lens/ics23-smt", + "voyager/modules/client/sui", "voyager/modules/client/trusted-mpt", - # "voyager/modules/client-bootstrap/base", - # "voyager/modules/client-bootstrap/bob", - # "voyager/modules/client-bootstrap/arbitrum", + "voyager/modules/client-bootstrap/base", + "voyager/modules/client-bootstrap/bob", + "voyager/modules/client-bootstrap/arbitrum", "voyager/modules/client-bootstrap/cometbls", - # "voyager/modules/client-bootstrap/ethereum", + "voyager/modules/client-bootstrap/ethereum", # "voyager/modules/client-bootstrap/movement", - # "voyager/modules/client-bootstrap/parlia", - # "voyager/modules/client-bootstrap/tendermint", - # "voyager/modules/client-bootstrap/ethermint", + "voyager/modules/client-bootstrap/parlia", + "voyager/modules/client-bootstrap/tendermint", + "voyager/modules/client-bootstrap/ethermint", "voyager/modules/client-bootstrap/trusted-mpt", - # "voyager/modules/client-bootstrap/state-lens/ics23-mpt", - # "voyager/modules/client-bootstrap/state-lens/ics23-smt", - # "voyager/modules/client-bootstrap/state-lens/ics23-ics23", - # "voyager/modules/client-bootstrap/sui", - - # "voyager/modules/finality/base", - # "voyager/modules/finality/bob", - # "voyager/modules/finality/arbitrum", - # "voyager/modules/finality/berachain", + "voyager/modules/client-bootstrap/state-lens/ics23-mpt", + "voyager/modules/client-bootstrap/state-lens/ics23-smt", + "voyager/modules/client-bootstrap/state-lens/ics23-ics23", + "voyager/modules/client-bootstrap/sui", + + "voyager/modules/finality/base", + "voyager/modules/finality/bob", + "voyager/modules/finality/arbitrum", + "voyager/modules/finality/berachain", "voyager/modules/finality/cometbls", - # "voyager/modules/finality/ethereum", + "voyager/modules/finality/ethereum", # "voyager/modules/finality/movement", - # "voyager/modules/finality/parlia", - # "voyager/modules/finality/tendermint", + "voyager/modules/finality/parlia", + "voyager/modules/finality/tendermint", "voyager/modules/finality/trusted-evm", - # "voyager/modules/finality/sui", + "voyager/modules/finality/sui", - # "voyager/plugins/client-update/base", - # "voyager/plugins/client-update/bob", - # "voyager/plugins/client-update/arbitrum", - # "voyager/plugins/client-update/berachain", + "voyager/plugins/client-update/base", + "voyager/plugins/client-update/bob", + "voyager/plugins/client-update/arbitrum", + "voyager/plugins/client-update/berachain", "voyager/plugins/client-update/cometbls", - # "voyager/plugins/client-update/ethereum", + "voyager/plugins/client-update/ethereum", # "voyager/plugins/client-update/movement", - # "voyager/plugins/client-update/parlia", - # "voyager/plugins/client-update/tendermint", - # "voyager/plugins/client-update/ethermint", - # "voyager/plugins/client-update/state-lens", - # "voyager/plugins/client-update/sui", + "voyager/plugins/client-update/parlia", + "voyager/plugins/client-update/tendermint", + "voyager/plugins/client-update/ethermint", + "voyager/plugins/client-update/state-lens", + "voyager/plugins/client-update/sui", "voyager/plugins/client-update/trusted-mpt", # "voyager/plugins/periodic-client-update", @@ -212,12 +212,12 @@ members = [ "voyager/plugins/event-source/cosmos-sdk", "voyager/plugins/event-source/ethereum", # "voyager/plugins/event-source/movement", - # "voyager/plugins/event-source/sui", + "voyager/plugins/event-source/sui", "voyager/plugins/transaction/cosmos-sdk", "voyager/plugins/transaction/ethereum", # "voyager/plugins/transaction/aptos", - # "voyager/plugins/transaction/sui", + "voyager/plugins/transaction/sui", "voyager/plugins/packet-filter", "voyager/plugins/packet-index", From b980383e67083bf1bc5b27150f6afd869d328292 Mon Sep 17 00:00:00 2001 From: aeryz Date: Wed, 8 Oct 2025 13:31:03 +0300 Subject: [PATCH 31/33] chore: clippy Signed-off-by: aeryz --- tools/union-test/tests/e2e.rs | 38 ++++++++++++------------ tools/union-test/tests/lst.rs | 16 +++++----- tools/union-test/tests/lst_common/mod.rs | 1 - 3 files changed, 27 insertions(+), 28 deletions(-) diff --git a/tools/union-test/tests/e2e.rs b/tools/union-test/tests/e2e.rs index da7146e5be..5e61620af0 100644 --- a/tools/union-test/tests/e2e.rs +++ b/tools/union-test/tests/e2e.rs @@ -483,7 +483,7 @@ async fn test_send_packet_from_union_to_evm_and_send_back_unwrap() { .ctx .predict_wrapped_token::( &t.ctx.dst, - ETH_ADDRESS_ZKGM.into(), + ETH_ADDRESS_ZKGM, ChannelId::new(NonZero::new(dst_chain_id).unwrap()), "au".into(), &evm_provider, @@ -586,7 +586,7 @@ async fn test_send_packet_from_union_to_evm_and_send_back_unwrap() { .ctx .send_and_recv_with_retry::( &t.ctx.dst, - ETH_ADDRESS_ZKGM.into(), + ETH_ADDRESS_ZKGM, call, &t.ctx.src, 3, @@ -628,7 +628,7 @@ async fn test_send_packet_from_evm_to_union_and_send_back_unwrap() { let deployed_erc20 = t .ctx .dst - .deploy_basic_erc20(ETH_ADDRESS_ZKGM.into(), evm_provider.clone()) + .deploy_basic_erc20(ETH_ADDRESS_ZKGM, evm_provider.clone()) .await .expect("failed to deploy ERC20"); @@ -688,7 +688,7 @@ async fn test_send_packet_from_evm_to_union_and_send_back_unwrap() { .ctx .send_and_recv_with_retry::( &t.ctx.dst, - ETH_ADDRESS_ZKGM.into(), + ETH_ADDRESS_ZKGM, call, &t.ctx.src, 3, @@ -819,7 +819,7 @@ async fn test_send_packet_from_union_to_evm_get_refund() { .ctx .predict_wrapped_token::( &t.ctx.dst, - ETH_ADDRESS_ZKGM.into(), + ETH_ADDRESS_ZKGM, ChannelId::new(NonZero::new(dst_chain_id).unwrap()), "au".into(), &evm_provider, @@ -962,7 +962,7 @@ async fn test_send_packet_from_evm_to_union_get_refund() { let deployed_erc20 = t .ctx .dst - .deploy_basic_erc20(ETH_ADDRESS_ZKGM.into(), evm_provider.clone()) + .deploy_basic_erc20(ETH_ADDRESS_ZKGM, evm_provider.clone()) .await .expect("failed to deploy ERC20"); @@ -1039,7 +1039,7 @@ async fn test_send_packet_from_evm_to_union_get_refund() { .ctx .send_and_recv_refund::( &t.ctx.dst, - ETH_ADDRESS_ZKGM.into(), + ETH_ADDRESS_ZKGM, call, &t.ctx.src, Duration::from_secs(720), @@ -1239,7 +1239,7 @@ async fn test_from_evm_to_union_tokenv2_unhappy_only_maker_err() { .ctx .send_and_expect_revert::( &t.ctx.dst, - ETH_ADDRESS_IBC.into(), + ETH_ADDRESS_IBC, call, expected_revert_code, &zkgm_deployer_provider, @@ -1310,7 +1310,7 @@ async fn test_from_evm_to_union_tokenv2_unhappy_err_invalid_unescrow() { .ctx .predict_wrapped_token_from_metadata_image_v2::( &t.ctx.dst, - ETH_ADDRESS_ZKGM.into(), + ETH_ADDRESS_ZKGM, ChannelId::new(NonZero::new(pair.dest).unwrap()), "au".into(), img, @@ -1384,7 +1384,7 @@ async fn test_from_evm_to_union_tokenv2_unhappy_err_invalid_unescrow() { .dst .zkgmerc20_approve( quote_token_addr, - ETH_ADDRESS_ZKGM.into(), + ETH_ADDRESS_ZKGM, U256::from(100000000000u64), evm_provider.clone(), ) @@ -1439,7 +1439,7 @@ async fn test_from_evm_to_union_tokenv2_unhappy_err_invalid_unescrow() { .ctx .send_and_expect_revert::( &t.ctx.dst, - ETH_ADDRESS_ZKGM.into(), + ETH_ADDRESS_ZKGM, call, expected_revert_code, &zkgm_deployer_provider, @@ -1490,7 +1490,7 @@ async fn test_from_evm_to_union_tokenv2_unhappy_err_cannot_deploy() { .ctx .predict_wrapped_token::( &t.ctx.dst, - ETH_ADDRESS_ZKGM.into(), + ETH_ADDRESS_ZKGM, ChannelId::new(NonZero::new(pair.dest).unwrap()), "au".into(), &evm_provider, @@ -1577,7 +1577,7 @@ async fn test_from_evm_to_union_batch_err_invalid_batch_instruction() { let deployed_erc20 = t .ctx .dst - .deploy_basic_erc20(ETH_ADDRESS_ZKGM.into(), evm_provider.clone()) + .deploy_basic_erc20(ETH_ADDRESS_ZKGM, evm_provider.clone()) .await .expect("failed to deploy ERC20"); @@ -1633,7 +1633,7 @@ async fn test_from_evm_to_union_batch_err_invalid_batch_instruction() { .ctx .send_and_expect_revert::( &t.ctx.dst, - ETH_ADDRESS_ZKGM.into(), + ETH_ADDRESS_ZKGM, call, expected_revert_code, &zkgm_deployer_provider, @@ -1668,7 +1668,7 @@ async fn test_from_evm_to_union_batch_err_invalid_forward_instruction() { let deployed_erc20 = t .ctx .dst - .deploy_basic_erc20(ETH_ADDRESS_ZKGM.into(), evm_provider.clone()) + .deploy_basic_erc20(ETH_ADDRESS_ZKGM, evm_provider.clone()) .await .expect("failed to deploy ERC20"); @@ -1726,7 +1726,7 @@ async fn test_from_evm_to_union_batch_err_invalid_forward_instruction() { .ctx .send_and_expect_revert::( &t.ctx.dst, - ETH_ADDRESS_ZKGM.into(), + ETH_ADDRESS_ZKGM, call, expected_revert_code, &zkgm_deployer_provider, @@ -1909,7 +1909,7 @@ async fn test_send_vault_unhappy_u_counterparty_is_not_fungible() { .ctx .send_and_expect_revert::( &t.ctx.dst, - ETH_ADDRESS_IBC.into(), + ETH_ADDRESS_IBC, call, expected_revert_code, &zkgm_deployer_provider, @@ -2093,7 +2093,7 @@ async fn test_send_vault_unhappy_u_base_amount_must_cover_quote_amount() { .ctx .send_and_expect_revert::( &t.ctx.dst, - ETH_ADDRESS_IBC.into(), + ETH_ADDRESS_IBC, call, expected_revert_code, &zkgm_deployer_provider, @@ -2277,7 +2277,7 @@ async fn test_send_vault_unhappy_u_fool() { .ctx .send_and_expect_revert::( &t.ctx.dst, - ETH_ADDRESS_IBC.into(), + ETH_ADDRESS_IBC, call, expected_revert_code, &zkgm_deployer_provider, diff --git a/tools/union-test/tests/lst.rs b/tools/union-test/tests/lst.rs index 6d3f4af7e8..12ec7f9c94 100644 --- a/tools/union-test/tests/lst.rs +++ b/tools/union-test/tests/lst.rs @@ -33,7 +33,7 @@ use lst_common::*; fn make_proxy_call(funded_msgs: &[(&str, Binary, Vec)]) -> Vec { let wasm_msgs: Vec = funded_msgs - .into_iter() + .iter() .map(|(contract, msg, funds)| { CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: contract.to_string(), @@ -123,7 +123,7 @@ async fn bond( ); // funding the eth address that we execute bond with, with au - eth_fund_u(&t, src_channel_id, sender_on_evm.into(), 100_000, 500_000) + eth_fund_u(t, src_channel_id, sender_on_evm.into(), 100_000, 500_000) .await .unwrap(); @@ -162,7 +162,7 @@ async fn bond( proxy_address_on_union.as_bytes().to_vec().into(), make_zkgm_bond_payload_via_call( t.union_address.lst_hub.as_str(), - &proxy_address_on_union.to_string(), + proxy_address_on_union.as_ref(), min_mint_amount, "au", bond_amount, @@ -178,7 +178,7 @@ async fn bond( .ctx .send_and_recv_and_ack_with_retry::( &t.ctx.dst, - ETH_ADDRESS_ZKGM.into(), + ETH_ADDRESS_ZKGM, call, &t.ctx.src, 3, @@ -236,7 +236,7 @@ async fn unbond( .ctx .send_and_recv_and_ack_with_retry::( &t.ctx.dst, - ETH_ADDRESS_ZKGM.into(), + ETH_ADDRESS_ZKGM, call, &t.ctx.src, 6, @@ -294,7 +294,7 @@ async fn withdraw( .ctx .send_and_recv_and_ack_with_retry::( &t.ctx.dst, - ETH_ADDRESS_ZKGM.into(), + ETH_ADDRESS_ZKGM, call, &t.ctx.src, 6, @@ -486,7 +486,7 @@ async fn test_unbond_success() { .into(), vec![], ), - &signer, + signer, ) .await .unwrap() @@ -553,7 +553,7 @@ async fn test_withdraw_success() { amount: fund_amount.to_string(), }], ), - &signer, + signer, ) .await .unwrap() diff --git a/tools/union-test/tests/lst_common/mod.rs b/tools/union-test/tests/lst_common/mod.rs index c0d251d89b..200a3f4f1f 100644 --- a/tools/union-test/tests/lst_common/mod.rs +++ b/tools/union-test/tests/lst_common/mod.rs @@ -67,7 +67,6 @@ pub struct Queue { } pub async fn run_test_in_queue< - 'a, Fut: Future, F: Fn(Arc, SharedData) -> Fut, >( From 4d6395f854cff1dc315a989b31ecf8250939e343 Mon Sep 17 00:00:00 2001 From: aeryz Date: Wed, 8 Oct 2025 15:37:14 +0300 Subject: [PATCH 32/33] chore: moar clippy Signed-off-by: aeryz --- tools/union-test/src/evm.rs | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/tools/union-test/src/evm.rs b/tools/union-test/src/evm.rs index 842cf7c873..4aada0c08a 100644 --- a/tools/union-test/src/evm.rs +++ b/tools/union-test/src/evm.rs @@ -6,8 +6,8 @@ use alloy::{ network::{AnyNetwork, EthereumWallet}, primitives::{Address, Bytes}, providers::{ - fillers::RecommendedFillers, DynProvider, PendingTransactionError, Provider, - ProviderBuilder, + DynProvider, PendingTransactionError, Provider, ProviderBuilder, + fillers::RecommendedFillers, }, rpc::types::Filter, signers::local::LocalSigner, @@ -17,13 +17,13 @@ use alloy::{ use bip32::secp256k1::ecdsa::{self, SigningKey}; use concurrent_keyring::{ConcurrentKeyring, KeyringConfig, KeyringEntry}; use ibc_solidity::Ibc::IbcEvents; -use ibc_union_spec::{datagram::Datagram, ChannelId}; +use ibc_union_spec::{ChannelId, datagram::Datagram}; use jsonrpsee::{core::RpcResult, types::ErrorObjectOwned}; use serde::{Deserialize, Serialize}; -use tracing::{debug, error, info_span, warn, Instrument}; +use tracing::{Instrument, debug, error, info_span, warn}; use unionlabs::{ - primitives::{FixedBytes, H160, H256, U256}, ErrorReporter, + primitives::{FixedBytes, H160, H256, U256}, }; use voyager_sdk::{ anyhow::{self}, @@ -174,10 +174,10 @@ impl Module { } }; for log in logs { - if let Ok(ibc_event) = IbcEvents::decode_log(&log.inner) { - if let Some(event) = filter_fn(ibc_event.data) { - events.push(event); - } + if let Ok(ibc_event) = IbcEvents::decode_log(&log.inner) + && let Some(event) = filter_fn(ibc_event.data) + { + events.push(event); } } @@ -739,9 +739,10 @@ impl Module { for raw in logs { if let Ok(alloy_log) = IbcEvents::decode_log(&raw.inner) - && let IbcEvents::PacketSend(ev) = alloy_log.data { - return Ok((ev.packet_hash.into(), block_number)); - } + && let IbcEvents::PacketSend(ev) = alloy_log.data + { + return Ok((ev.packet_hash.into(), block_number)); + } } Err(ErrorObjectOwned::owned( @@ -1187,7 +1188,9 @@ pub enum TxSubmitError { EmptyRevert(Vec), #[error("gas price is too high: max {max}, price {price}")] GasPriceTooHigh { max: u128, price: u128 }, - #[error("rpc error (this is just the IbcDatagram conversion functions but i need to make those errors better)")] + #[error( + "rpc error (this is just the IbcDatagram conversion functions but i need to make those errors better)" + )] RpcError(#[from] ErrorObjectOwned), #[error("batch too large")] BatchTooLarge, From eae8f4123aa9db649ee7339c3c28eb16fc9ac545 Mon Sep 17 00:00:00 2001 From: aeryz Date: Wed, 8 Oct 2025 17:38:46 +0300 Subject: [PATCH 33/33] chore: change name Signed-off-by: aeryz --- ...htly-all-works.yml => nightly-e2e-lst.yml} | 2 +- Cargo.lock | 125 ++++++------------ Cargo.toml | 2 +- e2e/all-tests.nix | 2 +- e2e/union-test.nix | 2 +- garnix.yaml | 4 +- tools/union-test/Cargo.toml | 1 - 7 files changed, 43 insertions(+), 95 deletions(-) rename .github/workflows/{nightly-all-works.yml => nightly-e2e-lst.yml} (89%) diff --git a/.github/workflows/nightly-all-works.yml b/.github/workflows/nightly-e2e-lst.yml similarity index 89% rename from .github/workflows/nightly-all-works.yml rename to .github/workflows/nightly-e2e-lst.yml index eabec78e98..c014a91fb3 100644 --- a/.github/workflows/nightly-all-works.yml +++ b/.github/workflows/nightly-e2e-lst.yml @@ -17,4 +17,4 @@ jobs: trusted-substituters = https://cache.nixos.org https://cache.garnix.io https://union.cachix.org - name: Fetch from Cache run: | - nix build .#checks.x86_64-linux.all-works -L + nix build .#checks.x86_64-linux.e2e-lst -L --option sandbox false diff --git a/Cargo.lock b/Cargo.lock index ed293afacd..ca28e4c57e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -573,7 +573,7 @@ dependencies = [ "futures", "futures-utils-wasm", "lru 0.13.0", - "parking_lot 0.12.3", + "parking_lot", "pin-project", "reqwest 0.12.15", "serde", @@ -596,7 +596,7 @@ dependencies = [ "alloy-transport", "bimap", "futures", - "parking_lot 0.12.3", + "parking_lot", "serde", "serde_json", "tokio", @@ -825,7 +825,7 @@ dependencies = [ "derive_more 2.0.1", "futures", "futures-utils-wasm", - "parking_lot 0.12.3", + "parking_lot", "serde", "serde_json", "thiserror 2.0.12", @@ -3879,7 +3879,7 @@ dependencies = [ "crossterm_winapi", "libc", "mio 0.8.11", - "parking_lot 0.12.3", + "parking_lot", "signal-hook", "signal-hook-mio", "winapi", @@ -4433,7 +4433,7 @@ dependencies = [ "hashbrown 0.14.5", "lock_api", "once_cell", - "parking_lot_core 0.9.10", + "parking_lot_core", ] [[package]] @@ -4447,7 +4447,7 @@ dependencies = [ "hashbrown 0.14.5", "lock_api", "once_cell", - "parking_lot_core 0.9.10", + "parking_lot_core", ] [[package]] @@ -6029,7 +6029,7 @@ checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" dependencies = [ "futures-core", "lock_api", - "parking_lot 0.12.3", + "parking_lot", ] [[package]] @@ -6318,7 +6318,7 @@ dependencies = [ "futures-timer", "no-std-compat", "nonzero_ext", - "parking_lot 0.12.3", + "parking_lot", "portable-atomic", "quanta", "rand 0.8.5", @@ -7275,15 +7275,6 @@ dependencies = [ "similar", ] -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", -] - [[package]] name = "interprocess" version = "2.2.3" @@ -7615,7 +7606,7 @@ dependencies = [ "http-body 1.0.1", "http-body-util", "jsonrpsee-types 0.24.9", - "parking_lot 0.12.3", + "parking_lot", "pin-project", "rand 0.8.5", "rustc-hash 2.1.1", @@ -7641,7 +7632,7 @@ dependencies = [ "http-body 1.0.1", "http-body-util", "jsonrpsee-types 0.25.1", - "parking_lot 0.12.3", + "parking_lot", "pin-project", "rand 0.9.1", "rustc-hash 2.1.1", @@ -8501,7 +8492,7 @@ dependencies = [ "event-listener 5.4.0", "futures-util", "loom", - "parking_lot 0.12.3", + "parking_lot", "portable-atomic", "rustc_version 0.4.1", "smallvec", @@ -9031,7 +9022,7 @@ dependencies = [ "futures", "mysten-metrics", "once_cell", - "parking_lot 0.12.3", + "parking_lot", "rand 0.8.5", "reqwest 0.12.15", "snap", @@ -9051,7 +9042,7 @@ dependencies = [ "dashmap 5.5.3", "futures", "once_cell", - "parking_lot 0.12.3", + "parking_lot", "prometheus", "prometheus-closure-metric", "scopeguard", @@ -9476,7 +9467,7 @@ dependencies = [ "hyper 1.6.0", "itertools 0.13.0", "md-5", - "parking_lot 0.12.3", + "parking_lot", "percent-encoding", "quick-xml", "rand 0.8.5", @@ -9882,17 +9873,6 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", -] - [[package]] name = "parking_lot" version = "0.12.3" @@ -9900,21 +9880,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", - "parking_lot_core 0.9.10", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi", + "parking_lot_core", ] [[package]] @@ -9925,7 +9891,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.11", + "redox_syscall", "smallvec", "windows-targets 0.52.6", ] @@ -10584,7 +10550,7 @@ dependencies = [ "fnv", "lazy_static", "memchr", - "parking_lot 0.12.3", + "parking_lot", "protobuf", "thiserror 1.0.69", ] @@ -11174,15 +11140,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3edd4d5d42c92f0a659926464d4cce56b562761267ecf0f469d85b7de384175" -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.5.11" @@ -12403,28 +12360,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serial_test" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0bccbcf40c8938196944a3da0e133e031a33f4d6b72db3bda3cc556e361905d" -dependencies = [ - "lazy_static", - "parking_lot 0.11.2", - "serial_test_derive", -] - -[[package]] -name = "serial_test_derive" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2acd6defeddb41eb60bb468f8825d0cfd0c2a76bc03bfd235b6a1dc4f6a1ad5" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "sha1" version = "0.10.6" @@ -13280,7 +13215,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" dependencies = [ "new_debug_unreachable", - "parking_lot 0.12.3", + "parking_lot", "phf_shared", "precomputed-hash", ] @@ -13879,7 +13814,7 @@ dependencies = [ "num_enum 0.6.1", "once_cell", "p384", - "parking_lot 0.12.3", + "parking_lot", "passkey-types", "prometheus", "proptest", @@ -14419,7 +14354,7 @@ dependencies = [ "bytes", "libc", "mio 1.0.3", - "parking_lot 0.12.3", + "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", @@ -15403,7 +15338,6 @@ dependencies = [ "regex", "serde", "serde-utils", - "serial_test", "thiserror 2.0.12", "tokio", "tracing", @@ -16822,6 +16756,21 @@ dependencies = [ "voyager-vm", ] +[[package]] +name = "voyager-periodic-client-update-plugin" +version = "0.0.0" +dependencies = [ + "clap", + "embed-commit", + "jsonrpsee 0.25.1", + "macros", + "serde", + "tokio", + "tracing", + "unionlabs", + "voyager-sdk", +] + [[package]] name = "voyager-plugin" version = "0.0.0" @@ -17855,7 +17804,7 @@ checksum = "0048ad49a55b9deb3953841fa1fc5858f0efbcb7a18868c899a360269fac1b23" dependencies = [ "futures", "js-sys", - "parking_lot 0.12.3", + "parking_lot", "pin-utils", "slab", "wasm-bindgen", @@ -17933,7 +17882,7 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6994d13118ab492c3c80c1f81928718159254c53c472bf9ce36f8dae4add02a7" dependencies = [ - "redox_syscall 0.5.11", + "redox_syscall", "wasite", ] diff --git a/Cargo.toml b/Cargo.toml index 37b33a1bcb..5e79b0b1fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -207,7 +207,7 @@ members = [ "voyager/plugins/client-update/sui", "voyager/plugins/client-update/trusted-mpt", - # "voyager/plugins/periodic-client-update", + "voyager/plugins/periodic-client-update", "voyager/plugins/event-source/cosmos-sdk", "voyager/plugins/event-source/ethereum", diff --git a/e2e/all-tests.nix b/e2e/all-tests.nix index 628cd89f72..f4f1b2587f 100644 --- a/e2e/all-tests.nix +++ b/e2e/all-tests.nix @@ -37,7 +37,7 @@ # ensure-blocks = import ./ensure-blocks/ensure-blocks.nix { inherit e2e networks pkgs nixpkgs crane; }; # # Tests from ./union-test.nix - inherit (union-test) lst; + inherit (union-test) e2e-lst; # Tests from ./epoch-staking.nix inherit (epoch-staking) epoch-completes; diff --git a/e2e/union-test.nix b/e2e/union-test.nix index 5a5c478e4a..af4b11d27a 100644 --- a/e2e/union-test.nix +++ b/e2e/union-test.nix @@ -9,7 +9,7 @@ let voyagerBin = "${self'.packages.voyager}/bin/voyager"; in { - lst = e2e.mkE2eTestEthUnion voyagerConfigFile { + e2e-lst = e2e.mkE2eTestEthUnion voyagerConfigFile { name = "lst"; openConnection = true; diff --git a/garnix.yaml b/garnix.yaml index a0dc76fa94..0687abb484 100644 --- a/garnix.yaml +++ b/garnix.yaml @@ -15,7 +15,7 @@ builds: - 'checks.aarch64-linux.nil' - 'checks.aarch64-linux.ssz-tests-up-to-date' - 'checks.*.all-crates-buildable-individually' - - 'checks.*.lst' + - 'checks.*.e2e-lst' - 'checks.*.devnet-eth-runs' - 'checks.*.ensure-blocks' - 'checks.*.epoch-completes' @@ -73,7 +73,7 @@ builds: - 'nixosConfigurations.*' exclude: - 'checks.*.all-crates-buildable-individually' - - 'checks.*.lst' + - 'checks.*.e2e-lst' - 'checks.*.devnet-eth-runs' - 'checks.*.ensure-blocks' - 'checks.*.epoch-completes' diff --git a/tools/union-test/Cargo.toml b/tools/union-test/Cargo.toml index 4b4b72c69e..889b7e993d 100644 --- a/tools/union-test/Cargo.toml +++ b/tools/union-test/Cargo.toml @@ -46,7 +46,6 @@ voyager-sdk = { workspace = true } [dev-dependencies] once_cell = "1.17" rand = "0.6" -serial_test = "0.5" tokio = { version = "1", features = ["macros", "rt"] } tracing-subscriber = "0.3"