From 2320cccccc23c48b46b81cec271904778751fd00 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Fri, 8 Sep 2023 21:02:29 +0545 Subject: [PATCH] feat: add setup method during contract instantiate Signed-off-by: Night Owl --- .../cw-asset-manager/src/contract.rs | 148 +++++++++--------- .../cw-asset-manager/src/helpers.rs | 12 +- .../cw-asset-manager/src/state.rs | 10 +- .../cw-asset-manager/tests/deposit_test.rs | 4 +- .../cw-asset-manager/tests/setup.rs | 6 +- .../tests/x_handle_msg_test.rs | 5 +- contracts/cw-common/src/asset_manager_msg.rs | 5 +- 7 files changed, 103 insertions(+), 87 deletions(-) diff --git a/contracts/core-contracts/cw-asset-manager/src/contract.rs b/contracts/core-contracts/cw-asset-manager/src/contract.rs index 65daf9c..0114852 100644 --- a/contracts/core-contracts/cw-asset-manager/src/contract.rs +++ b/contracts/core-contracts/cw-asset-manager/src/contract.rs @@ -1,37 +1,41 @@ -use cosmwasm_std::entry_point; +use std::str::FromStr; + +use cosmwasm_std::{ensure_eq, entry_point}; use cosmwasm_std::{ to_binary, Addr, Binary, Deps, DepsMut, Env, Event, MessageInfo, QueryRequest, Reply, Response, StdError, StdResult, SubMsg, SubMsgResult, Uint128, WasmMsg, WasmQuery, }; -use std::str::FromStr; -// use cw2::set_contract_version; +use cw2::set_contract_version; use cw20::{AllowanceResponse, Cw20ExecuteMsg, Cw20QueryMsg}; use cw_common::asset_manager_msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use cw_common::network_address::IconAddressValidation; use cw_common::network_address::NetworkAddress; -use cw_common::x_call_msg::XCallMsg; +use cw_common::x_call_msg::{GetNetworkAddress, XCallMsg}; use cw_common::xcall_data_types::Deposit; use crate::constants::SUCCESS_REPLY_MSG; +use crate::contract::exec::setup; use crate::error::ContractError; use crate::helpers::{decode_encoded_bytes, validate_archway_address, DecodedStruct}; use crate::state::*; -// // version info for migration info -// const CONTRACT_NAME: &str = "crates.io:cw-asset-manager"; -// const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); +// version info for migration info +const CONTRACT_NAME: &str = "crates.io:cw-asset-manager"; +const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( deps: DepsMut, _env: Env, info: MessageInfo, - _msg: InstantiateMsg, -) -> StdResult { - // set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - + msg: InstantiateMsg, +) -> Result { + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION) + .map_err(ContractError::Std)?; OWNER.save(deps.storage, &info.sender)?; - Ok(Response::new().add_attribute("action", "instantiated")) + + setup(deps, msg.source_xcall, msg.destination_asset_manager) } #[cfg_attr(not(feature = "library"), entry_point)] @@ -45,7 +49,11 @@ pub fn execute( ExecuteMsg::ConfigureXcall { source_xcall, destination_asset_manager, - } => exec::configure_network(deps, info, source_xcall, destination_asset_manager), + } => { + let owner = OWNER.load(deps.storage).map_err(ContractError::Std)?; + ensure_eq!(owner, info.sender, ContractError::OnlyOwner); + setup(deps, source_xcall, destination_asset_manager) + } ExecuteMsg::HandleCallMessage { from, data } => { exec::handle_xcall_msg(deps, env, info, from, data) } @@ -71,8 +79,8 @@ pub fn execute( //you can optimize this let recipient: NetworkAddress = match to { Some(to_address) => { - let nw_addr = NetworkAddress::from_str(&*to_address).unwrap(); - if !nw_addr.validate() { + let nw_addr = NetworkAddress::from_str(&to_address).unwrap(); + if !nw_addr.validate_foreign_addresses() { return Err(ContractError::InvalidRecipientAddress); } nw_addr @@ -102,61 +110,57 @@ pub fn execute( } mod exec { - use cw_xcall_multi::msg::QueryMsg::GetNetworkAddress; - use rlp::Encodable; use std::str::FromStr; + use rlp::Encodable; + use cw_common::xcall_data_types::DepositRevert; use super::*; - pub fn configure_network( + pub fn setup( deps: DepsMut, - info: MessageInfo, source_xcall: String, destination_asset_manager: String, ) -> Result { - let owner = OWNER.load(deps.storage)?; - if info.sender != owner { - return Err(ContractError::OnlyOwner); - } - - let x_addr = deps.api.addr_validate(source_xcall.as_ref())?; + // validate source xcall + let x_call_addr = deps + .api + .addr_validate(&source_xcall) + .map_err(ContractError::Std)?; + // query network address of xcall let query_msg = GetNetworkAddress {}; - let query = QueryRequest::Wasm(WasmQuery::Smart { - contract_addr: x_addr.to_string(), - msg: to_binary(&query_msg)?, + contract_addr: x_call_addr.to_string(), + msg: to_binary(&query_msg).map_err(ContractError::Std)?, }); - let x_network_address: NetworkAddress = deps.querier.query(&query)?; + let xcall_network_address: NetworkAddress = deps.querier.query(&query)?; - if x_network_address.ok() { + if !xcall_network_address.to_string().is_empty() { return Err(ContractError::XAddressNotFound); } - let (nid, _) = x_network_address.get_parts(); + // Obtain native network id + let nid = xcall_network_address.nid(); - let dest_nw_addr = NetworkAddress::from_str(&*destination_asset_manager).unwrap(); - - if !dest_nw_addr.validate() { - return Err(ContractError::InvalidNetworkAddressFormat {}); + // validate icon asset manager + let icon_asset_manager = + NetworkAddress::from_str(&destination_asset_manager).map_err(ContractError::Std)?; + if !icon_asset_manager.validate_foreign_addresses() { + return Err(ContractError::InvalidNetworkAddressFormat); } - //save in case required - let (dest_id, _dest_address) = dest_nw_addr.get_parts(); - //update state - X_NETWORK_ADDRESS.save(deps.storage, &x_network_address)?; + SOURCE_XCALL + .save(deps.storage, &x_call_addr) + .map_err(ContractError::Std)?; + X_CALL_NETWORK_ADDRESS.save(deps.storage, &xcall_network_address)?; NID.save(deps.storage, &nid)?; - //TODO: Rename to ICON asset manager - ICON_ASSET_MANAGER.save(deps.storage, &dest_nw_addr)?; - SOURCE_XCALL.save(deps.storage, &source_xcall)?; - ICON_ASSET_MANAGER.save(deps.storage, &dest_nw_addr)?; - ICON_NET_ID.save(deps.storage, &dest_id)?; + ICON_ASSET_MANAGER.save(deps.storage, &icon_asset_manager.account())?; + ICON_NET_ID.save(deps.storage, &icon_asset_manager.nid())?; - //TODO: save the details Ok(Response::default()) } @@ -236,7 +240,7 @@ mod exec { }; let xcall_msg = WasmMsg::Execute { - contract_addr: source_xcall, + contract_addr: source_xcall.to_string(), msg: to_binary(&xcall_message)?, funds: info.funds, }; @@ -274,8 +278,8 @@ mod exec { data: Vec, ) -> Result { let xcall = SOURCE_XCALL.load(deps.storage)?; - let x_call_addr = deps.api.addr_validate(&xcall)?; - let x_network = X_NETWORK_ADDRESS.load(deps.storage)?; + let x_call_addr = deps.api.addr_validate(xcall.as_ref())?; + let x_network = X_CALL_NETWORK_ADDRESS.load(deps.storage)?; if info.sender != x_call_addr { return Err(ContractError::OnlyXcallService); @@ -300,7 +304,7 @@ mod exec { DecodedStruct::WithdrawTo(data_struct) => { //TODO: Check if _from is ICON Asset manager contract let icon_am = ICON_ASSET_MANAGER.load(deps.storage)?; - if from != icon_am.to_string() { + if from != icon_am { return Err(ContractError::OnlyIconAssetManager {}); } @@ -351,9 +355,10 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { } mod query { - use super::*; use cw_common::asset_manager_msg::{ConfigureResponse, NetIdResponse, OwnerResponse}; + use super::*; + pub fn query_get_owner(deps: Deps) -> StdResult { let owner = OWNER.load(deps.storage)?; Ok(OwnerResponse { owner }) @@ -391,9 +396,6 @@ pub fn reply(_deps: DepsMut, _env: Env, msg: Reply) -> Result ( OwnedDeps, @@ -413,19 +419,9 @@ mod tests { let mut deps = mock_dependencies(); let env = mock_env(); let info = mock_info("user", &[]); - - let instantiated_resp = - instantiate(deps.as_mut(), env.clone(), info.clone(), InstantiateMsg {}).unwrap(); - //to pretend us as xcall contract during handle call execution testing let xcall = "xcall"; - let configure_msg = ExecuteMsg::ConfigureXcall { - source_xcall: xcall.to_owned(), - destination_asset_manager: "0x01.icon/cxc2d01de5013778d71d99f985e4e2ff3a9b48a66c" - .to_owned(), - }; - // mocking response for external query i.e. allowance deps.querier.update_wasm(|r: &WasmQuery| match r { WasmQuery::Smart { @@ -448,7 +444,17 @@ mod tests { _ => todo!(), }); - execute(deps.as_mut(), env.clone(), info.clone(), configure_msg).unwrap(); + let instantiated_resp = instantiate( + deps.as_mut(), + env.clone(), + info.clone(), + InstantiateMsg { + source_xcall: xcall.to_owned(), + destination_asset_manager: "0x01.icon/cxc2d01de5013778d71d99f985e4e2ff3a9b48a66c" + .to_owned(), + }, + ) + .unwrap(); (deps, env, info, instantiated_resp) } @@ -662,7 +668,10 @@ mod tests { assert_eq!(response, Response::default()); // Verify the saved values - let saved_source_xcall: String = SOURCE_XCALL.load(deps.as_ref().storage).unwrap(); + let saved_source_xcall: String = SOURCE_XCALL + .load(deps.as_ref().storage) + .unwrap() + .to_string(); let icon_am = ICON_ASSET_MANAGER.load(deps.as_ref().storage).unwrap(); let saved_destination_asset_manager = icon_am.to_string(); @@ -670,13 +679,8 @@ mod tests { assert_eq!(saved_destination_asset_manager, destination_asset_manager); // Verify that only the owner can configure the network - let other_info = mock_info("other_sender", &[]); - let res = configure_network( - deps.as_mut(), - other_info, - source_xcall, - destination_asset_manager, - ); + let _other_info = mock_info("other_sender", &[]); + let res = setup(deps.as_mut(), source_xcall, destination_asset_manager); //check for error assert!(res.is_err()); diff --git a/contracts/core-contracts/cw-asset-manager/src/helpers.rs b/contracts/core-contracts/cw-asset-manager/src/helpers.rs index c9d4fbc..116977d 100644 --- a/contracts/core-contracts/cw-asset-manager/src/helpers.rs +++ b/contracts/core-contracts/cw-asset-manager/src/helpers.rs @@ -1,8 +1,10 @@ -use crate::error::ContractError; use cosmwasm_std::{Addr, DepsMut}; -use cw_common::xcall_data_types::{DepositRevert, WithdrawTo}; use rlp::{DecoderError, Rlp}; +use cw_common::xcall_data_types::{DepositRevert, WithdrawTo}; + +use crate::error::ContractError; + #[derive(Debug)] pub enum DecodedStruct { WithdrawTo(WithdrawTo), @@ -81,10 +83,12 @@ pub fn validate_archway_address(deps: &DepsMut, address: &str) -> (Option, #[cfg(test)] mod tests { - use super::*; - use cw_common::xcall_data_types::Deposit; use rlp::Encodable; + use cw_common::xcall_data_types::Deposit; + + use super::*; + #[test] fn test_encode_decode_withdraw_to() { let withdraw_to = WithdrawTo { diff --git a/contracts/core-contracts/cw-asset-manager/src/state.rs b/contracts/core-contracts/cw-asset-manager/src/state.rs index 217342a..624fe66 100644 --- a/contracts/core-contracts/cw-asset-manager/src/state.rs +++ b/contracts/core-contracts/cw-asset-manager/src/state.rs @@ -1,13 +1,13 @@ use cosmwasm_std::Addr; -use cw_common::network_address::{NetId, NetworkAddress}; use cw_storage_plus::Item; +use cw_common::network_address::{NetId, NetworkAddress}; + pub const OWNER: Item = Item::new("contract_owner"); -pub const SOURCE_XCALL: Item = Item::new("source_xcall_address"); -pub const X_NETWORK_ADDRESS: Item = Item::new("source_xcall_network_address"); +pub const SOURCE_XCALL: Item = Item::new("source_xcall_address"); +pub const X_CALL_NETWORK_ADDRESS: Item = Item::new("source_xcall_network_address"); pub const NID: Item = Item::new("network_id"); -pub const ICON_ASSET_MANAGER: Item = - Item::new("icon_asset_manager_network_address"); +pub const ICON_ASSET_MANAGER: Item = Item::new("icon_asset_manager_network_address"); pub const ICON_NET_ID: Item = Item::new("icon_asset_manager_network_id"); 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 1371217..9dd5071 100644 --- a/contracts/core-contracts/cw-asset-manager/tests/deposit_test.rs +++ b/contracts/core-contracts/cw-asset-manager/tests/deposit_test.rs @@ -17,7 +17,7 @@ fn deposit_cw20_token(mut ctx: TestContext, msg: ExecuteMsg) -> TestContext { let resp = ctx .app - .execute_contract(ctx.sender.clone(), ctx.get_assetmanager_app(), &msg, &[]); + .execute_contract(ctx.sender.clone(), ctx.get_asset_manager_app(), &msg, &[]); println!("deposit execution resp: {:?}", resp); ctx @@ -25,7 +25,7 @@ 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 am_addr = ctx.get_assetmanager_app(); + let am_addr = ctx.get_asset_manager_app(); let spoke_addr = ctx.get_cw20token_app(); let token = Cw20Contract(ctx.get_cw20token_app()); diff --git a/contracts/core-contracts/cw-asset-manager/tests/setup.rs b/contracts/core-contracts/cw-asset-manager/tests/setup.rs index c414b1c..7758589 100644 --- a/contracts/core-contracts/cw-asset-manager/tests/setup.rs +++ b/contracts/core-contracts/cw-asset-manager/tests/setup.rs @@ -235,7 +235,11 @@ pub fn init_asset_manager(mut ctx: TestContext) -> TestContext { .instantiate_contract( code_id, ctx.sender.clone(), - &InstantiateMsg {}, + &InstantiateMsg { + source_xcall: Addr::unchecked("x_call").into_string(), + destination_asset_manager: "0x01.icon/cx7866543210fedcba9876543210fedcba987654df" + .to_owned(), + }, &[], "XCall", None, diff --git a/contracts/core-contracts/cw-asset-manager/tests/x_handle_msg_test.rs b/contracts/core-contracts/cw-asset-manager/tests/x_handle_msg_test.rs index 4576b7b..4ff9899 100644 --- a/contracts/core-contracts/cw-asset-manager/tests/x_handle_msg_test.rs +++ b/contracts/core-contracts/cw-asset-manager/tests/x_handle_msg_test.rs @@ -16,7 +16,7 @@ use std::str::FromStr; fn execute_handle_msg_on_asset_manager_from_relayer(mut ctx: TestContext) -> TestContext { let relay = Addr::unchecked("relayer"); - let asset_manager = ctx.get_assetmanager_app(); + let asset_manager = ctx.get_asset_manager_app(); // ---------------------------- execution flow from RELAYER------> XCALL -------------------------------------------- @@ -36,7 +36,8 @@ fn execute_handle_msg_on_asset_manager_from_relayer(mut ctx: TestContext) -> Tes let msg_typ: u64 = 1; //destination asset manager - let from = NetworkAddress("0x01.icon/cx7866543210fedcba9876543210fedcba987654df".to_owned()); + let from = + NetworkAddress::from_str("0x01.icon/cx7866543210fedcba9876543210fedcba987654df").unwrap(); //construct encoded CallServiceMessageRequest let mut stream = RlpStream::new(); diff --git a/contracts/cw-common/src/asset_manager_msg.rs b/contracts/cw-common/src/asset_manager_msg.rs index 6618f37..b7c8b22 100644 --- a/contracts/cw-common/src/asset_manager_msg.rs +++ b/contracts/cw-common/src/asset_manager_msg.rs @@ -2,7 +2,10 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{Addr, Uint128}; #[cw_serde] -pub struct InstantiateMsg {} +pub struct InstantiateMsg { + pub source_xcall: String, + pub destination_asset_manager: String, +} #[cw_serde] pub enum ExecuteMsg {