From 14b4b6b8649531d2ce782002b861342b72721c93 Mon Sep 17 00:00:00 2001 From: AntonAndell Date: Tue, 24 Oct 2023 09:58:35 +0200 Subject: [PATCH] fix rollback logic and add integrationt test for happy path --- .../cw-asset-manager/tests/deposit_test.rs | 90 +++++++++++++- .../cw-hub-bnusd/src/contract.rs | 11 +- .../tests/handle_call_message_test.rs | 112 +++++++++--------- 3 files changed, 147 insertions(+), 66 deletions(-) diff --git a/contracts/core-contracts/cw-asset-manager/tests/deposit_test.rs b/contracts/core-contracts/cw-asset-manager/tests/deposit_test.rs index 3e9a5cc..1ddd3b0 100644 --- a/contracts/core-contracts/cw-asset-manager/tests/deposit_test.rs +++ b/contracts/core-contracts/cw-asset-manager/tests/deposit_test.rs @@ -1,18 +1,20 @@ mod setup; use cosmwasm_std::{Addr, Uint128}; -use cw_common::asset_manager_msg::ExecuteMsg; +use cw_common::{x_call_msg::XCallMsg as XCallExecuteMsg, asset_manager_msg::ExecuteMsg}; +use cw_ibc_rlp_lib::rlp::RlpStream; use cw_multi_test::Executor; +use cw_xcall_lib::network_address::NetId; use crate::setup::{ execute_config_x_call, instantiate_contracts, set_default_connection, setup_context, - TestContext, + TestContext, get_event, }; use cw20::{Cw20Contract, Cw20ExecuteMsg}; //test helper fn deposit_cw20_token(mut ctx: TestContext, msg: ExecuteMsg) -> TestContext { - let relay = ctx.get_xcall_connection(); - ctx = set_default_connection(ctx, relay); + let xcall_connection = ctx.get_xcall_connection(); + ctx = set_default_connection(ctx, xcall_connection); let resp = ctx .app @@ -23,13 +25,13 @@ fn deposit_cw20_token(mut ctx: TestContext, msg: ExecuteMsg) -> TestContext { } fn increase_allowance(mut ctx: TestContext, amount: Uint128) -> (TestContext, Uint128) { - let relay = ctx.get_xcall_connection(); + let xcall_connection = ctx.get_xcall_connection(); let am_addr = ctx.get_asset_manager_app(); let spoke_addr = ctx.get_cw20token_app(); let token = Cw20Contract(ctx.get_cw20token_app()); - ctx = set_default_connection(ctx, relay); + ctx = set_default_connection(ctx, xcall_connection); let allowance_msg = Cw20ExecuteMsg::IncreaseAllowance { spender: am_addr.to_string(), @@ -82,3 +84,79 @@ fn test_deposit_expected_for_revert() { let bl = check_balance(&ctx, &spoke_addr, &ctx.get_asset_manager_app()); assert_eq!(Uint128::new(100), bl); } + + +#[test] +fn test_deposit_revert() { + let mut context = setup_context(); + context = instantiate_contracts(context); + let spoke_addr = context.get_cw20token_app(); + let source_x_call = context.get_xcall_app(); + context = execute_config_x_call(context, source_x_call); + let xcall_connection = context.get_xcall_connection(); + context = set_default_connection(context, xcall_connection.clone()); + + + let (mut ctx, _allowance) = increase_allowance(context, Uint128::new(1000)); + let user = ctx.sender.clone(); + + let initial_balance = check_balance(&ctx, &spoke_addr, &user); + + let deposit_msg = ExecuteMsg::Deposit { + token_address: spoke_addr.to_string(), + amount: Uint128::new(100), + to: None, + data: None, + }; + + let response = ctx + .app + .execute_contract(ctx.sender.clone(), ctx.get_asset_manager_app(), &deposit_msg, &[]).unwrap(); + + let event = get_event(&response, "wasm-CallMessageSent").unwrap(); + let sequence_no = event.get("sn").unwrap(); + + let bl = check_balance(&ctx, &spoke_addr, &user); + assert_eq!(initial_balance - Uint128::new(100), bl); + + let message_type: u64 = 2; + let mut stream = RlpStream::new(); + stream.begin_list(2); + stream.append(&sequence_no.parse::().unwrap()); + stream.append(&0); + + let encoded_data: Vec = stream.out().to_vec(); + + let mut stream = RlpStream::new(); + stream.begin_list(2); + stream.append(&message_type); + stream.append(&encoded_data); + + let data = stream.out().to_vec(); + + ctx.app.execute_contract( + xcall_connection.clone(), + ctx.get_xcall_app(), + &XCallExecuteMsg::HandleMessage { + from: NetId::from("icon".to_owned()), + msg: data, + }, + &[], + ).unwrap(); + + ctx + .app + .execute_contract( + user.clone(), + ctx.get_xcall_app(), + &XCallExecuteMsg::ExecuteRollback { + sequence_no: sequence_no.parse::().unwrap() + }, + &[], + ) + .unwrap(); + + + let bl = check_balance(&ctx, &spoke_addr, &user); + assert_eq!(initial_balance, bl); +} diff --git a/contracts/token-contracts/cw-hub-bnusd/src/contract.rs b/contracts/token-contracts/cw-hub-bnusd/src/contract.rs index 0173a46..fe03e8b 100644 --- a/contracts/token-contracts/cw-hub-bnusd/src/contract.rs +++ b/contracts/token-contracts/cw-hub-bnusd/src/contract.rs @@ -229,9 +229,6 @@ mod execute { from: NetworkAddress, data: Vec, ) -> Result { - if !from.validate_foreign_addresses() { - return Err(ContractError::InvalidNetworkAddress); - } let xcall = X_CALL.load(deps.storage)?; if info.sender != xcall { return Err(ContractError::OnlyCallService); @@ -335,9 +332,6 @@ mod execute { from: NetworkAddress, cross_transfer_data: CrossTransfer, ) -> Result { - if !cross_transfer_data.from.validate_foreign_addresses() { - return Err(ContractError::InvalidNetworkAddress); - } let nid = NID.load(deps.storage)?; let hub_net: NetId = DESTINATION_TOKEN_NET.load(deps.storage)?; @@ -393,6 +387,11 @@ mod execute { cross_transfer_revert_data: CrossTransferRevert, ) -> Result { debug_println!("this is {:?},{:?}", cross_transfer_revert_data, from); + let xcall_network_address = X_CALL_NETWORK_ADDRESS.load(deps.storage)?; + if from != xcall_network_address { + return Err(ContractError::WrongAddress {}); + } + deps.api .addr_validate(cross_transfer_revert_data.from.as_ref()) .map_err(ContractError::Std)?; diff --git a/contracts/token-contracts/cw-hub-bnusd/tests/handle_call_message_test.rs b/contracts/token-contracts/cw-hub-bnusd/tests/handle_call_message_test.rs index 0ec10ad..c255a53 100644 --- a/contracts/token-contracts/cw-hub-bnusd/tests/handle_call_message_test.rs +++ b/contracts/token-contracts/cw-hub-bnusd/tests/handle_call_message_test.rs @@ -1,13 +1,13 @@ mod setup; use std::str::FromStr; -use cw_common::{data_types::CrossTransferRevert, x_call_msg::XCallMsg as XCallExecuteMsg}; -use cw_multi_test::Executor; +use cw_common::{x_call_msg::XCallMsg as XCallExecuteMsg, hub_token_msg::ExecuteMsg}; +use cw_multi_test::{Executor, AppResponse}; use cosmwasm_std::{Addr, Uint128}; use cw_common::{data_types::CrossTransfer, network_address::NetworkAddress}; -use crate::setup::{execute_setup, instantiate_contracts}; +use crate::setup::{execute_setup, instantiate_contracts, mint_token, call_set_xcall_host}; use cw20::BalanceResponse; use cw20_base::msg::QueryMsg; use cw_common::network_address::NetId; @@ -128,37 +128,63 @@ fn handle_call_message_test() { execute_and_handle_message(context); } +fn balance_of(context: &TestContext, user: Addr) -> BalanceResponse { + context + .app + .wrap() + .query_wasm_smart( + context.get_hubtoken_app(), + &QueryMsg::Balance { + address: user.to_string(), + }, + ) + .unwrap() +} + #[test] pub fn cross_transfer_revert_data_test() { let mut context: TestContext = setup_context(); context = instantiate_contracts(context); context = execute_setup(context); - let hub_token_addr = context.get_hubtoken_app().into_string(); + let x_call_connection = context.get_xcall_connection(); + context = set_default_connection(context, x_call_connection.clone()); + call_set_xcall_host(&mut context); - let call_data = CrossTransferRevert { - method: "xCrossTransferRevert".to_string(), - from: Addr::unchecked("cx7866543210fedcba9876543210fedcba987654df".to_owned()), - value: 1000, - }; + let initial_balance = Uint128::from(u128::MIN + 1000); - let data = encode(&call_data).to_vec(); + let sender = context.sender.to_string(); + context = mint_token(context, sender, initial_balance); + let to = NetworkAddress::from_str("icon/cx9876543210fedcba9876543210fedcba98765432").unwrap(); + let amount = Uint128::from(u128::MIN + 100); + let user = context.sender.clone(); + let response = context + .app + .execute_contract( + user.clone(), + context.get_hubtoken_app(), + &ExecuteMsg::CrossTransfer { + to: to, + amount: amount.into(), + data: vec![], + }, + &[], + ) + .unwrap(); - let network_address = - NetworkAddress::from_str("icon/cx7866543210fedcba9876543210fedcba987654df").unwrap(); - let sequence_no: u64 = 1234; - let message_type: u64 = 1; + let event = get_event(&response, "wasm-CallMessageSent").unwrap(); + let sequence_no = event.get("sn").unwrap(); + + let balance = balance_of(&context, user.clone()); + let expected_balance = Uint128::from(initial_balance - amount); + assert_eq!(balance.balance, expected_balance); + let message_type: u64 = 2; let mut stream = RlpStream::new(); - stream.begin_list(6); - stream.append(&network_address.to_string()); - stream.append(&hub_token_addr); - stream.append(&sequence_no); - stream.append(&false); - stream.append(&data); - stream.begin_list(0); + stream.begin_list(2); + stream.append(&sequence_no.parse::().unwrap()); + stream.append(&0); let encoded_data: Vec = stream.out().to_vec(); - println!("Encoded Data {:?}", encoded_data); let mut stream = RlpStream::new(); stream.begin_list(2); @@ -167,51 +193,29 @@ pub fn cross_transfer_revert_data_test() { let data = stream.out().to_vec(); - let relay = Addr::unchecked("relay"); - context = set_default_connection(context, relay.clone()); - - let response = context.app.execute_contract( - relay, + context.app.execute_contract( + x_call_connection.clone(), context.get_xcall_app(), &XCallExecuteMsg::HandleMessage { from: NetId::from("icon".to_owned()), msg: data, }, &[], - ); - - println!("Response {:?}", response); - let event = get_event(&response.unwrap(), "wasm-CallMessage").unwrap(); - let request_id = event.get("reqId").unwrap(); - println!("Request ID {:?}", request_id); - - let data = encode(&call_data).to_vec(); + ).unwrap(); - let response = context + context .app .execute_contract( - context.get_hubtoken_app(), + user.clone(), context.get_xcall_app(), - &XCallExecuteMsg::ExecuteCall { - request_id: request_id.parse::().unwrap(), - data, + &XCallExecuteMsg::ExecuteRollback { + sequence_no: sequence_no.parse::().unwrap() }, &[], ) .unwrap(); - let balance: BalanceResponse = context - .app - .wrap() - .query_wasm_smart( - context.get_hubtoken_app(), - &QueryMsg::Balance { - address: call_data.from.to_string(), - }, - ) - .unwrap(); - let expected_balance = Uint128::from(u128::MIN + 1000); - assert_eq!(balance.balance, expected_balance); - - println!("Response {:?}", response); + let balance = balance_of(&context, user.clone()); + println!("{:?}", balance.balance); + assert_eq!(balance.balance, initial_balance); }