Skip to content

Commit

Permalink
Cross IBC test
Browse files Browse the repository at this point in the history
  • Loading branch information
adairrr committed May 12, 2024
1 parent 20ba4f8 commit d6b2feb
Show file tree
Hide file tree
Showing 10 changed files with 157 additions and 43 deletions.
42 changes: 27 additions & 15 deletions contracts/client/src/handlers/execute.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use abstract_app::sdk::ModuleRegistryInterface;
use abstract_app::traits::{AbstractResponse, AccountIdentification, ModuleInterface};
use cosmwasm_std::{DepsMut, ensure_eq, Env, MessageInfo};
use cosmwasm_std::{Deps, DepsMut, ensure_eq, Env, MessageInfo, Order};

use ibcmail::{IBCMAIL_SERVER_ID, Message, NewMessage, Recipient};
use ibcmail::{IBCMAIL_SERVER_ID, Message, NewMessage, Recipient, Sender};
use ibcmail::client::ClientApp;
use ibcmail::client::state::{RECEIVED, SENT};
use ibcmail::server::api::ServerInterface;
Expand All @@ -15,27 +15,28 @@ use crate::state::CONFIG;

pub fn execute_handler(
deps: DepsMut,
_env: Env,
env: Env,
info: MessageInfo,
app: App,
msg: ClientExecuteMsg,
) -> ClientResult {
println!("Env: {:?}", env);
match msg {
ClientExecuteMsg::SendMessage(message) => send_msg(deps, info, message, app),
ClientExecuteMsg::SendMessage(message) => send_msg(deps, env, info, message, app),
ClientExecuteMsg::ReceiveMessage(message) => receive_msg(deps, info, message, app),
ClientExecuteMsg::UpdateConfig {} => update_config(deps, info, app),
}
}

fn send_msg(deps: DepsMut, info: MessageInfo, msg: NewMessage, app: ClientApp) -> ClientResult {
fn send_msg(deps: DepsMut, env: Env, info: MessageInfo, msg: NewMessage, app: ClientApp) -> ClientResult {
// validate basic fields of message, construct message to send to server
let to_send = Message {
id: Uuid::new_v4().to_string(),
sender: app.account_id(deps.as_ref()).unwrap(),
sender: Sender::account(app.account_id(deps.as_ref()).unwrap(), None),
recipient: msg.recipient,
subject: msg.subject,
body: msg.body,
timestamp: Default::default(),
timestamp: env.block.time,
version: app.version().to_string()
};

Expand All @@ -49,25 +50,36 @@ fn send_msg(deps: DepsMut, info: MessageInfo, msg: NewMessage, app: ClientApp) -

/// Receive a message from the server
fn receive_msg(deps: DepsMut, info: MessageInfo, msg: Message, app: App) -> ClientResult {
println!("Received message: {:?}", msg);
// check that the message sender is the server... this requires the server to be the proper version
let sender_module = app.module_registry(deps.as_ref())?.module_info(info.sender).map_err(|_| ClientError::NotMailServer {})?;
ensure_eq!(sender_module.info.id(), IBCMAIL_SERVER_ID, ClientError::NotMailServer {});

match msg.recipient {
check_recipient(deps.as_ref(), &msg.recipient, &app)?;

RECEIVED.save(deps.storage, msg.id.clone(), &msg)?;
let len = RECEIVED.keys(deps.storage, None, None, Order::Ascending).count();

println!("Received length: {:?}", len);

Ok(app.response("received").add_attribute("message_id", &msg.id))
}

fn check_recipient(deps: Deps, recipient: &Recipient, app: &ClientApp) -> ClientResult<()> {
println!("Checking recipient: {:?}", recipient);
match recipient {
Recipient::Account { id: ref account_id, .. } => {

println!("account_id: {:?}", account_id);
let our_id = app.account_id(deps.as_ref())?;
println!("our_id: {:?}", our_id);
// TODO: this check is screwed up in the tests somehow
let our_id = app.account_id(deps)?;
println!("recipient_id: {:?}, our_id: {:?}", account_id, our_id);

// check that the recipient is the current account
ensure_eq!(account_id, &our_id, ClientError::NotRecipient {} );
}
_ => Err(ClientError::NotImplemented("recipients".to_string()))?,
}

RECEIVED.save(deps.storage, msg.id.clone(), &msg)?;

Ok(app.response("received").add_attribute("message_id", &msg.id))
Ok(())
}

/// Update the configuration of the client
Expand Down
3 changes: 2 additions & 1 deletion contracts/client/src/handlers/instantiate.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use cosmwasm_std::{DepsMut, Env, MessageInfo, Response};
use ibcmail::client::state::RECEIVED;
use ibcmail::client::state::{RECEIVED, TEST};

use crate::contract::{App, ClientResult};
use crate::msg::ClientInstantiateMsg;
Expand All @@ -15,6 +15,7 @@ pub fn instantiate_handler(
let config: Config = Config {};

CONFIG.save(deps.storage, &config)?;
TEST.save(deps.storage, &_env.contract.address)?;

// Example instantiation that doesn't do anything
Ok(Response::new())
Expand Down
8 changes: 6 additions & 2 deletions contracts/client/src/handlers/query.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use crate::contract::{App, ClientResult};
use crate::msg::{ClientQueryMsg, ConfigResponse};
use crate::state::{CONFIG};
use cosmwasm_std::{to_json_binary, Binary, Deps, Env, StdResult};
use cosmwasm_std::{to_json_binary, Binary, Deps, Env, StdResult, Order};
use cw_storage_plus::Bound;
use ibcmail::client::error::ClientError;
use ibcmail::client::msg::{MessageFilter, MessagesResponse};
use ibcmail::client::state::RECEIVED;
use ibcmail::client::state::{RECEIVED, TEST};
use ibcmail::MessageId;

pub const DEFAULT_LIMIT: u32 = 50;
Expand All @@ -27,6 +27,10 @@ fn query_messages(deps: Deps, filter: Option<MessageFilter>, start: Option<Messa
|_id, message| Ok::<_, ClientError>(message),
)?;

let len = RECEIVED.keys(deps.storage, None, None, Order::Ascending).count();

println!("Messages: {:?}, test: {:?}, len: {:?}", messages, TEST.load(deps.storage)?, len);

Ok(MessagesResponse { messages })
}

Expand Down
58 changes: 44 additions & 14 deletions contracts/client/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use cosmwasm_std::coins;
// Use prelude to get all the necessary imports
use cw_orch::{anyhow, prelude::*};

use ibcmail::{IBCMAIL_NAMESPACE, IBCMAIL_SERVER_ID, Message, Recipient};
use ibcmail::{IBCMAIL_NAMESPACE, IBCMAIL_SERVER_ID, Message, Recipient, Sender};
use ibcmail::server::msg::ServerInstantiateMsg;
use ibcmail_client::{
*,
Expand Down Expand Up @@ -47,13 +47,19 @@ impl<Env: CwEnv> TestEnv<Env> {
publisher.publish_app::<ClientInterface<_>>()?;
publisher.publish_adapter::<ServerInstantiateMsg, ServerInterface<_>>(ServerInstantiateMsg {})?;

let app = publisher
.account()
// let app = publisher.account()
// .install_app_with_dependencies::<ClientInterface<_>>(&ClientInstantiateMsg {}, Empty {},&[])?;
// app.authorize_on_adapters(&[IBCMAIL_SERVER_ID])?;
//
// let app2 = publisher.account()
// .install_app_with_dependencies::<ClientInterface<_>>(&ClientInstantiateMsg {}, Empty {},&[])?;
// app2.authorize_on_adapters(&[IBCMAIL_SERVER_ID])?;

let app = abs_client.account_builder().install_on_sub_account(false).build()?
.install_app_with_dependencies::<ClientInterface<_>>(&ClientInstantiateMsg {}, Empty {},&[])?;
app.authorize_on_adapters(&[IBCMAIL_SERVER_ID])?;

let app2 = publisher
.account()
let app2 = abs_client.account_builder().install_on_sub_account(false).build()?
.install_app_with_dependencies::<ClientInterface<_>>(&ClientInstantiateMsg {}, Empty {},&[])?;
app2.authorize_on_adapters(&[IBCMAIL_SERVER_ID])?;

Expand All @@ -80,7 +86,7 @@ impl<Env: CwEnv> TestEnv<Env> {
fn create_test_message(from: AccountId, to: AccountId) -> Message {
Message {
id: "test-id".to_string(),
sender: from.clone(),
sender: Sender::account(from.clone(), None),
recipient: Recipient::account(to.clone(), None),
subject: "test-subject".to_string(),
body: "test-body".to_string(),
Expand Down Expand Up @@ -108,6 +114,9 @@ mod receive_msg {
use ibcmail::client::error::ClientError;
use super::*;


/// Sending a message from the same account to the same account
/// TODO: this test is failing because of an issue with state management...
#[test]
fn can_receive_from_server() -> anyhow::Result<()> {
// Create a sender and mock env
Expand Down Expand Up @@ -159,7 +168,7 @@ mod send_msg {
use abstract_app::objects::chain_name::ChainName;
use cw_orch::daemon::networks::{ARCHWAY_1, JUNO_1};
use cw_orch::tokio::runtime::Runtime;
use ibcmail::NewMessage;
use ibcmail::{IBCMAIL_CLIENT, NewMessage};
use super::*;

#[test]
Expand All @@ -183,33 +192,54 @@ mod send_msg {
fn can_send_remote_message() -> anyhow::Result<()> {
// Create a sender and mock env
let interchain = MockBech32InterchainEnv::new(
vec![("archway-1", "archway18k2uq7srsr8lwrae6zr0qahpn29rsp7td7wvfd"), ("juno-1","juno18k2uq7srsr8lwrae6zr0qahpn29rsp7tw83nyx")]
vec![("juno-1","juno18k2uq7srsr8lwrae6zr0qahpn29rsp7tw83nyx"), ("archway-1", "archway18k2uq7srsr8lwrae6zr0qahpn29rsp7td7wvfd")]
);

// /Users/adair/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cw-orch-mock-0.22.0/src/queriers/env.rs:12:70:
// index out of bounds: the len is 1 but the index is 1
let myos_env = TestEnv::setup(interchain.chain("archway-1")?)?;
// index out of bounds: the len is 1 but the index is 1 (when initializing with "juno")
let arch_env = TestEnv::setup(interchain.chain("archway-1")?)?;
let juno_env = TestEnv::setup(interchain.chain("juno-1")?)?;

myos_env.enable_ibc()?;
arch_env.enable_ibc()?;
juno_env.enable_ibc()?;

// TODO: put somewhere better
ibc_connect_polytone_and_abstract(&interchain, "archway-1", "juno-1")?;

let myos_client = myos_env.client1;
let arch_client = arch_env.client1;
let juno_client = juno_env.client1;

// the trait `From<&str>` is not implemented for `abstract_app::objects::chain_name::ChainName`
let msg = NewMessage::new(Recipient::account(juno_client.account().id()?, Some(ChainName::from_string("juno".into())?)), "test-subject", "test-body");

let res = myos_client.send_message(msg);
let res = arch_client.send_message(msg);

assert_that!(res).is_ok();

let myos_messages = myos_client.messages(None, None, None)?;
interchain.wait_ibc("archway-1", res?)?;

let myos_messages = arch_client.messages(None, None, None)?;
assert_that!(myos_messages.messages).is_empty();



let juno_client_1_module_addresses = juno_client.account().module_addresses(vec![IBCMAIL_CLIENT.into()])?;
let acc_id = juno_client.account().id()?;
println!("juno_client_1 addresses: {:?}, account_id: {:?}", juno_client_1_module_addresses, acc_id);
// TESTING:
let addresses = juno_env.client2.account().module_addresses(vec![IBCMAIL_CLIENT.into()])?;
let acc_id = juno_env.client2.account().id()?;
println!("juno_client_2 addresses: {:?}, account_id: {:?}", addresses, acc_id);

let test_address = juno_client.address()?;
let test_id = juno_client.id();
println!("test_address: {:?}, test_id: {:?}", test_address, test_id);

let mut juno_mail_client = ClientInterface::new(IBCMAIL_CLIENT, juno_env.env.clone());
juno_mail_client.set_address(&juno_client_1_module_addresses.modules[0].1.clone());
let juno_mail_client_messages = juno_mail_client.messages(None, None, None)?;
assert_that!(juno_mail_client_messages.messages).has_length(1);

let juno_messages = juno_client.messages(None, None, None)?;
assert_that!(juno_messages.messages).has_length(1);

Expand Down
9 changes: 5 additions & 4 deletions contracts/server/src/handlers/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use ibcmail::client::msg::ClientExecuteMsg;

use crate::contract::{Adapter, ServerResult};
use crate::error::ServerError;
use ibcmail::server::msg::ServerExecuteMsg;
use ibcmail::server::msg::{ServerExecuteMsg, ServerIbcMessage};
use crate::state::CONFIG;

pub fn execute_handler(
Expand All @@ -32,9 +32,9 @@ pub fn execute_handler(
}
}

fn route_msg(deps: DepsMut, _info: MessageInfo, msg: Message, app: Adapter) -> ServerResult {

pub(crate) fn route_msg(deps: DepsMut, _info: MessageInfo, msg: Message, app: Adapter) -> ServerResult {
let registry = app.account_registry(deps.as_ref())?;
println!("routing message: {:?}", msg);

let msg = match &msg.recipient {
Recipient::Account { id: ref account_id, chain } => {
Expand All @@ -61,6 +61,7 @@ fn route_msg(deps: DepsMut, _info: MessageInfo, msg: Message, app: Adapter) -> S
Ok::<CosmosMsg, ServerError>(exec_msg)
},
Some(chain) => {
println!("routing to chain: {:?}", chain);
// TODO verify that the chain is a valid chain

let current_module_info = ModuleInfo::from_id(app.module_id(), app.version().into())?;
Expand All @@ -69,7 +70,7 @@ fn route_msg(deps: DepsMut, _info: MessageInfo, msg: Message, app: Adapter) -> S
// TODO: why is host chain not chain name
host_chain: chain.to_string(),
target_module: current_module_info,
msg: to_json_binary(&ServerExecuteMsg::RouteMessage(msg))?,
msg: to_json_binary(&ServerIbcMessage::RouteMessage(msg))?,
callback_info: None,
};

Expand Down
47 changes: 43 additions & 4 deletions contracts/server/src/handlers/module_ibc.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,52 @@
use abstract_sdk::AbstractResponse;
use abstract_std::ibc::ModuleIbcMsg;
use cosmwasm_std::{DepsMut, Env, MessageInfo};
use abstract_std::objects::AccountId;
use cosmwasm_std::{DepsMut, Env, from_json, MessageInfo, Response};
use ibcmail::{IBCMAIL_SERVER_ID, Message, Recipient, Sender};
use ibcmail::server::error::ServerError;
use ibcmail::server::msg::{ExecuteMsg, ServerExecuteMsg, ServerIbcMessage};
use ibcmail::server::ServerAdapter;
use crate::contract::{ServerResult};
use crate::contract::{execute, ServerResult};

pub fn module_ibc_handler(
deps: DepsMut,
_env: Env,
app: ServerAdapter,
msg: ModuleIbcMsg,
ibc_msg: ModuleIbcMsg,
) -> ServerResult {
todo!()
println!("module_ibc_handler 1 : {:?}", ibc_msg);
// First check that we received the message from the server
if ibc_msg.source_module.id().ne(IBCMAIL_SERVER_ID) {
println!("UnauthorizedIbcModule: {:?}", ibc_msg.source_module.clone());
return Err(ServerError::UnauthorizedIbcModule(ibc_msg.source_module.clone()));
};

let server_msg: ServerIbcMessage = from_json(&ibc_msg.msg)?;

println!("parsed_msg: {:?}", server_msg);

match server_msg {
ServerIbcMessage::RouteMessage(msg) => {
// Update the sender to the proper remote account?
let updated_sender = match &msg.sender {
// Update the sender
Sender::Account { id, .. } => Sender::Account { id: id.clone(), chain: Some(ibc_msg.client_chain) },
_ => msg.sender
};

let updated_recipient = match &msg.recipient {
// Update the recipient
Recipient::Account { id, .. } => Recipient::Account { id: id.clone(), chain: None },
_ => msg.recipient
};

let updated = Message {
recipient: updated_recipient,
sender: updated_sender,
..msg
};
crate::handlers::execute::route_msg(deps, MessageInfo { funds: vec![], sender: _env.contract.address }, updated, app)
}
_ => Err(ServerError::UnauthorizedIbcMessage {})
}
}
5 changes: 4 additions & 1 deletion packages/ibcmail/src/client/state.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use cw_storage_plus::{Item, Map};
use cosmwasm_std::Addr;
use cw_storage_plus::{Item, Map};
use crate::{Message, MessageId};

#[cosmwasm_schema::cw_serde]
Expand All @@ -9,3 +10,5 @@
pub const SENT: Map<MessageId, Message> = Map::new("sent");

pub const CONFIG: Item<Config> = Item::new("config");

pub const TEST: Item<Addr> = Item::new("test");
11 changes: 10 additions & 1 deletion packages/ibcmail/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ impl NewMessage {
#[cosmwasm_schema::cw_serde]
pub struct Message {
pub id: MessageId,
pub sender: AccountId,
pub sender: Sender,
pub recipient: Recipient,
pub subject: String,
pub body: String,
Expand Down Expand Up @@ -67,4 +67,13 @@ pub enum Sender {
id: AccountId,
chain: Option<ChainName>
}
}

impl Sender {
pub fn account(account_id: AccountId, chain_name: Option<ChainName>) -> Self {
Sender::Account {
id: account_id,
chain: chain_name
}
}
}
Loading

0 comments on commit d6b2feb

Please sign in to comment.