Module ibc_test_framework::docs::walkthroughs::memo
source · Expand description
Memo Test
This walkthrough illustrates an integration test that utilizes a non-empty
struct as test input. This test asserts that the process of transferring
IBC messages preserves the memo field. For the purposes of this explanation,
the memo field is nothing more than a String field for carrying along
some arbitrary metadata as part of the transaction.
The test in most of its entirety (some parts omitted for brevity) looks like this:
#[test]
fn test_memo() -> Result<(), Error> {
let memo = Memo::new(random_string()).unwrap();
let test = MemoTest { memo };
run_binary_channel_test(&test)
}
pub struct MemoTest {
memo: Memo,
}
impl TestOverrides for MemoTest {
fn modify_relayer_config(&self, config: &mut Config) {
for mut chain in config.chains.iter_mut() {
chain.memo_prefix = self.memo.clone();
}
}
}
impl BinaryChannelTest for MemoTest {
fn run<ChainA: ChainHandle, ChainB: ChainHandle>(
&self,
_config: &TestConfig,
_relayer: RelayerDriver,
chains: ConnectedChains<ChainA, ChainB>,
channel: ConnectedChannel<ChainA, ChainB>,
) -> Result<(), Error> {
let denom_a = chains.node_a.denom();
let a_to_b_amount = random_u128_range(1000, 5000);
chains.node_a.chain_driver().ibc_transfer_token(
&channel.port_a.as_ref(),
&channel.channel_id_a.as_ref(),
&chains.node_a.wallets().user1(),
&chains.node_b.wallets().user1().address(),
&denom_a.with_amount(a_to_b_amount).as_ref(),
)?;
let denom_b = derive_ibc_denom(
&channel.port_b.as_ref(),
&channel.channel_id_b.as_ref(),
&denom_a,
)?;
chains.node_b.chain_driver().assert_eventual_wallet_amount(
&chains.node_b.wallets().user1().address(),
&denom_b.with_amount(a_to_b_amount).as_ref(),
)?;
let tx_info = chains
.node_b
.chain_driver()
.query_recipient_transactions(&chains.node_b.wallets().user1().address())?;
assert_tx_memo_equals(&tx_info, self.memo.as_str())?;
Ok(())
}
}
This test runs initializes a MemoTest struct with a random string
in the memo field, then calls the run_binary_channel_test function
with it. The TestOverrides trait is implemented in order to set the
memo_prefix configuration value on the chains that are initialized
over the course of the test.
At a high level, this test performs an IBC token transfer operation from chain A to chain B. Once chain B has received the transaction that chain A initialized, the test asserts that the value of the memo string is indeed what we expected.
The first two lines of the run function perform some necessary
setup for performing an IBC token transfer, namely fetching the
coin denomination of chain A as well as generating a random amount
of that denomination that will be sent to chain B. It then calls
the ibc_token_transfer function to generate a transaction with
this information, including the memo string that was generated
earlier, and sends it to chain B.
Next, the derive_ibc_denom function is called in order to
calculate the appropriate amount of chain B’s coin denomination
based on chain A’s denomination and how much of that denomination
was sent over the transaction so that chain B can represent the
transferred value.
The assert_eventual_wallet_amount function is then called on
chain B in order to confirm that the transaction was indeed
received by checking that chain B’s wallet amount reflects the
expected updated value. The query_recipient_transactions
method is then called to fetch the memo value from the transaction
so that we can confirm that its value is indeed what we expect.
You can find the file containing this test at tools/integration-test/src/tests/memo.rs.