diff --git a/.changelog/unreleased/features/ibc-relayer/3766-max-memo-receiver-config.md b/.changelog/unreleased/features/ibc-relayer/3766-max-memo-receiver-config.md new file mode 100644 index 0000000000..aca27309b9 --- /dev/null +++ b/.changelog/unreleased/features/ibc-relayer/3766-max-memo-receiver-config.md @@ -0,0 +1,6 @@ +- Add two new packet configurations: + * `ics20_max_memo_size` which filters ICS20 packets with memo + field bigger than the configured value + * `ics20_max_receiver_size` which filters ICS20 packets with receiver + field bigger than the configured value + ([\#3766](https://github.com/informalsystems/hermes/issues/3766)) \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 43cf677b36..adca6e2e9c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1361,6 +1361,7 @@ dependencies = [ name = "ibc-integration-test" version = "0.26.4" dependencies = [ + "byte-unit", "http", "ibc-relayer", "ibc-relayer-types", diff --git a/config.toml b/config.toml index 804025fea5..9ff0aa5ed3 100644 --- a/config.toml +++ b/config.toml @@ -79,6 +79,20 @@ tx_confirmation = false # [Default: false] auto_register_counterparty_payee = false +# Set the maximum size for the memo field in ICS20 packets. +# If the size of the memo field is bigger than the configured +# one, the packet will not be relayed. +# The filter can be disabled by setting `enabled = false`. +# [Default: "32KiB"] +#ics20_max_memo_size = { enabled = true, size = "32KiB" } + +# Set the maximum size for the receiver field in ICS20 packets. +# If the size of the receiver field is bigger than the configured +# one, the packet will not be relayed. +# The filter can be disabled by setting `enabled = false`. +# [Default: "2KiB"] +#ics20_max_receiver_size = { enabled = true, size = "2KiB" } + # The REST section defines parameters for Hermes' built-in RESTful API. # https://hermes.informal.systems/rest.html [rest] diff --git a/crates/relayer-cli/src/commands/clear.rs b/crates/relayer-cli/src/commands/clear.rs index ef463808fd..7535614312 100644 --- a/crates/relayer-cli/src/commands/clear.rs +++ b/crates/relayer-cli/src/commands/clear.rs @@ -152,6 +152,8 @@ impl Runnable for ClearPacketsCmd { let opts = LinkParameters { src_port_id: self.port_id.clone(), src_channel_id: self.channel_id.clone(), + max_memo_size: config.mode.packets.ics20_max_memo_size, + max_receiver_size: config.mode.packets.ics20_max_receiver_size, }; let fwd_link = match Link::new_from_opts(chains.src.clone(), chains.dst, opts, false, false) diff --git a/crates/relayer-cli/src/commands/tx/packet.rs b/crates/relayer-cli/src/commands/tx/packet.rs index 171ac93fad..9a81666b37 100644 --- a/crates/relayer-cli/src/commands/tx/packet.rs +++ b/crates/relayer-cli/src/commands/tx/packet.rs @@ -86,6 +86,8 @@ impl Runnable for TxPacketRecvCmd { let opts = LinkParameters { src_port_id: self.src_port_id.clone(), src_channel_id: self.src_channel_id.clone(), + max_memo_size: config.mode.packets.ics20_max_memo_size, + max_receiver_size: config.mode.packets.ics20_max_receiver_size, }; let link = match Link::new_from_opts(chains.src, chains.dst, opts, false, false) { Ok(link) => link, @@ -181,6 +183,8 @@ impl Runnable for TxPacketAckCmd { let opts = LinkParameters { src_port_id: self.src_port_id.clone(), src_channel_id: self.src_channel_id.clone(), + max_memo_size: config.mode.packets.ics20_max_memo_size, + max_receiver_size: config.mode.packets.ics20_max_receiver_size, }; let link = match Link::new_from_opts(chains.src, chains.dst, opts, false, false) { Ok(link) => link, diff --git a/crates/relayer/src/config.rs b/crates/relayer/src/config.rs index 74f1e491d3..1427f1e7e1 100644 --- a/crates/relayer/src/config.rs +++ b/crates/relayer/src/config.rs @@ -26,6 +26,7 @@ use ibc_relayer_types::core::ics24_host::identifier::{ChainId, ChannelId, PortId use ibc_relayer_types::timestamp::ZERO_DURATION; use crate::chain::cosmos::config::CosmosSdkConfig; +use crate::config::types::ics20_field_size_limit::Ics20FieldSizeLimit; use crate::config::types::TrustThreshold; use crate::error::Error as RelayerError; use crate::extension_options::ExtensionOptionDynamicFeeTx; @@ -230,6 +231,14 @@ pub mod default { buckets: 10, } } + + pub fn ics20_max_memo_size() -> Ics20FieldSizeLimit { + Ics20FieldSizeLimit::new(true, Byte::from_bytes(32768)) + } + + pub fn ics20_max_receiver_size() -> Ics20FieldSizeLimit { + Ics20FieldSizeLimit::new(true, Byte::from_bytes(2048)) + } } #[derive(Clone, Debug, Default, Deserialize, Serialize)] @@ -400,6 +409,10 @@ pub struct Packets { pub tx_confirmation: bool, #[serde(default = "default::auto_register_counterparty_payee")] pub auto_register_counterparty_payee: bool, + #[serde(default = "default::ics20_max_memo_size")] + pub ics20_max_memo_size: Ics20FieldSizeLimit, + #[serde(default = "default::ics20_max_receiver_size")] + pub ics20_max_receiver_size: Ics20FieldSizeLimit, } impl Default for Packets { @@ -410,6 +423,8 @@ impl Default for Packets { clear_on_start: default::clear_on_start(), tx_confirmation: default::tx_confirmation(), auto_register_counterparty_payee: default::auto_register_counterparty_payee(), + ics20_max_memo_size: default::ics20_max_memo_size(), + ics20_max_receiver_size: default::ics20_max_receiver_size(), } } } @@ -742,6 +757,7 @@ impl> From> for Diagnostic { } use crate::chain::cosmos::config::error::Error as CosmosConfigError; + impl From for Error { fn from(error: CosmosConfigError) -> Error { Error::cosmos_config_error(error.to_string()) diff --git a/crates/relayer/src/config/types.rs b/crates/relayer/src/config/types.rs index c79e0bd2ad..eec382a01d 100644 --- a/crates/relayer/src/config/types.rs +++ b/crates/relayer/src/config/types.rs @@ -125,6 +125,10 @@ pub mod max_tx_size { Ok(Self(value)) } + pub fn unsafe_new(value: usize) -> Self { + Self(value) + } + pub fn max() -> Self { Self(Self::MAX_BOUND) } @@ -261,6 +265,61 @@ pub mod memo { } } +pub mod ics20_field_size_limit { + use byte_unit::Byte; + use serde_derive::{Deserialize, Serialize}; + use std::fmt::Display; + + pub enum ValidationResult { + Valid, + Invalid { size: usize, max: usize }, + } + + impl Display for ValidationResult { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Valid => write!(f, "valid"), + + Self::Invalid { size, max } => { + write!(f, "invalid, size `{size}` is greater than max `{max}`") + } + } + } + } + + #[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)] + pub struct Ics20FieldSizeLimit { + enabled: bool, + size: Byte, + } + + impl Ics20FieldSizeLimit { + pub fn new(enabled: bool, size: Byte) -> Self { + Self { enabled, size } + } + + /// If the limit is disabled consider the field as valid. + /// If the limit is enabled assert the field is smaller or equal + /// to the configured value. + pub fn check_field_size(&self, field: &str) -> ValidationResult { + if self.enabled { + let size_limit = self.size.get_bytes() as usize; + + if field.len() <= size_limit { + ValidationResult::Valid + } else { + ValidationResult::Invalid { + size: field.len(), + max: size_limit, + } + } + } else { + ValidationResult::Valid + } + } + } +} + #[cfg(test)] #[allow(dead_code)] // the fields of the structs defined below are never accessed mod tests { diff --git a/crates/relayer/src/link.rs b/crates/relayer/src/link.rs index 5e9716aee4..4c0fc849b2 100644 --- a/crates/relayer/src/link.rs +++ b/crates/relayer/src/link.rs @@ -5,11 +5,14 @@ use ibc_relayer_types::core::{ }; use tracing::info; -use crate::chain::requests::{QueryChannelRequest, QueryHeight}; use crate::chain::{counterparty::check_channel_counterparty, requests::QueryConnectionRequest}; use crate::chain::{handle::ChainHandle, requests::IncludeProof}; use crate::channel::{Channel, ChannelSide}; use crate::link::error::LinkError; +use crate::{ + chain::requests::{QueryChannelRequest, QueryHeight}, + config::types::ics20_field_size_limit::Ics20FieldSizeLimit, +}; pub mod cli; pub mod error; @@ -33,6 +36,8 @@ pub use relay_path::{RelayPath, Resubmit}; pub struct LinkParameters { pub src_port_id: PortId, pub src_channel_id: ChannelId, + pub max_memo_size: Ics20FieldSizeLimit, + pub max_receiver_size: Ics20FieldSizeLimit, } pub struct Link { @@ -43,9 +48,10 @@ impl Link { pub fn new( channel: Channel, with_tx_confirmation: bool, + link_parameters: LinkParameters, ) -> Result { Ok(Self { - a_to_b: RelayPath::new(channel, with_tx_confirmation)?, + a_to_b: RelayPath::new(channel, with_tx_confirmation, link_parameters)?, }) } @@ -140,7 +146,7 @@ impl Link { a_connection.client_id().clone(), a_connection_id, opts.src_port_id.clone(), - Some(opts.src_channel_id), + Some(opts.src_channel_id.clone()), None, ), b_side: ChannelSide::new( @@ -169,7 +175,7 @@ impl Link { .map_err(LinkError::relayer)?; } - Link::new(channel, with_tx_confirmation) + Link::new(channel, with_tx_confirmation, opts) } /// Constructs a link around the channel that is reverse to the channel @@ -182,6 +188,8 @@ impl Link { let opts = LinkParameters { src_port_id: self.a_to_b.dst_port_id().clone(), src_channel_id: self.a_to_b.dst_channel_id().clone(), + max_memo_size: self.a_to_b.max_memo_size, + max_receiver_size: self.a_to_b.max_receiver_size, }; let chain_b = self.a_to_b.dst_chain().clone(); let chain_a = self.a_to_b.src_chain().clone(); diff --git a/crates/relayer/src/link/relay_path.rs b/crates/relayer/src/link/relay_path.rs index 35abb01258..2a1d4307be 100644 --- a/crates/relayer/src/link/relay_path.rs +++ b/crates/relayer/src/link/relay_path.rs @@ -4,6 +4,7 @@ use std::ops::Sub; use std::time::{Duration, Instant}; use ibc_proto::google::protobuf::Any; +use ibc_proto::ibc::applications::transfer::v2::FungibleTokenPacketData as RawPacketData; use itertools::Itertools; use tracing::{debug, error, info, span, trace, warn, Level}; @@ -42,6 +43,8 @@ use crate::chain::tracking::TrackedMsgs; use crate::chain::tracking::TrackingId; use crate::channel::error::ChannelError; use crate::channel::Channel; +use crate::config::types::ics20_field_size_limit::Ics20FieldSizeLimit; +use crate::config::types::ics20_field_size_limit::ValidationResult; use crate::event::source::EventBatch; use crate::event::IbcEventWithHeight; use crate::foreign_client::{ForeignClient, ForeignClientError}; @@ -55,6 +58,7 @@ use crate::link::packet_events::query_write_ack_events; use crate::link::pending::PendingTxs; use crate::link::relay_sender::{AsyncReply, SubmitReply}; use crate::link::relay_summary::RelaySummary; +use crate::link::LinkParameters; use crate::link::{pending, relay_sender}; use crate::path::PathIdentifiers; use crate::telemetry; @@ -108,12 +112,16 @@ pub struct RelayPath { // transactions if [`confirm_txes`] is true. pending_txs_src: PendingTxs, pending_txs_dst: PendingTxs, + + pub max_memo_size: Ics20FieldSizeLimit, + pub max_receiver_size: Ics20FieldSizeLimit, } impl RelayPath { pub fn new( channel: Channel, with_tx_confirmation: bool, + link_parameters: LinkParameters, ) -> Result { let src_chain = channel.src_chain().clone(); let dst_chain = channel.dst_chain().clone(); @@ -152,6 +160,9 @@ impl RelayPath { confirm_txes: with_tx_confirmation, pending_txs_src: PendingTxs::new(src_chain, src_channel_id, src_port_id, dst_chain_id), pending_txs_dst: PendingTxs::new(dst_chain, dst_channel_id, dst_port_id, src_chain_id), + + max_memo_size: link_parameters.max_memo_size, + max_receiver_size: link_parameters.max_receiver_size, }) } @@ -549,6 +560,18 @@ impl RelayPath { for event_with_height in input { trace!(event = %event_with_height, "processing event"); + if let Some(packet) = event_with_height.event.packet() { + // If the event is a ICS-04 packet event, and the packet contains ICS-20 + // packet data, check that the ICS-20 fields are within the configured limits. + if !check_ics20_fields_size( + &packet.data, + self.max_memo_size, + self.max_receiver_size, + ) { + continue; + } + } + let (dst_msg, src_msg) = match &event_with_height.event { IbcEvent::CloseInitChannel(_) => ( self.build_chan_close_confirm_from_event(event_with_height)?, @@ -1363,6 +1386,7 @@ impl RelayPath { dst_info: &ChainStatus, ) -> Result, LinkError> { let packet = event.packet.clone(); + if self .dst_channel(QueryHeight::Specific(dst_info.height))? .state_matches(&ChannelState::Closed) @@ -1381,7 +1405,16 @@ impl RelayPath { dst_info: &ChainStatus, height: Height, ) -> Result<(Option, Option), LinkError> { + crate::time!( + "build_recv_or_timeout_from_send_packet_event", + { + "src_channel": event.packet.source_channel, + "dst_channel": event.packet.destination_channel, + } + ); + let timeout = self.build_timeout_from_send_packet_event(event, dst_info)?; + if timeout.is_some() { Ok((None, timeout)) } else { @@ -1886,3 +1919,34 @@ impl RelayPath { } } } + +#[tracing::instrument(skip(data))] +fn check_ics20_fields_size( + data: &[u8], + memo_limit: Ics20FieldSizeLimit, + receiver_limit: Ics20FieldSizeLimit, +) -> bool { + match serde_json::from_slice::(data) { + Ok(packet_data) => { + match ( + memo_limit.check_field_size(&packet_data.memo), + receiver_limit.check_field_size(&packet_data.receiver), + ) { + (ValidationResult::Valid, ValidationResult::Valid) => true, + + (memo_validity, receiver_validity) => { + debug!("found invalid ICS-20 packet data, not relaying packet!"); + debug!(" ICS-20 memo: {memo_validity}"); + debug!(" ICS-20 receiver: {receiver_validity}"); + + false + } + } + } + Err(e) => { + trace!("failed to decode ICS20 packet data with error `{e}`"); + + true + } + } +} diff --git a/crates/relayer/src/worker.rs b/crates/relayer/src/worker.rs index 915c49ce66..400ff811af 100644 --- a/crates/relayer/src/worker.rs +++ b/crates/relayer/src/worker.rs @@ -117,6 +117,8 @@ pub fn spawn_worker_tasks( LinkParameters { src_port_id: path.src_port_id.clone(), src_channel_id: path.src_channel_id.clone(), + max_memo_size: packets_config.ics20_max_memo_size, + max_receiver_size: packets_config.ics20_max_receiver_size, }, packets_config.tx_confirmation, packets_config.auto_register_counterparty_payee, diff --git a/crates/relayer/tests/config/fixtures/relayer_conf_example.toml b/crates/relayer/tests/config/fixtures/relayer_conf_example.toml index 3665bb595f..f864efecda 100644 --- a/crates/relayer/tests/config/fixtures/relayer_conf_example.toml +++ b/crates/relayer/tests/config/fixtures/relayer_conf_example.toml @@ -19,6 +19,8 @@ enabled = true clear_interval = 100 clear_on_start = true tx_confirmation = true +ics20_max_memo_size = { enabled = true, size = "32KiB" } +ics20_max_receiver_size = { enabled = true, size = "2KiB" } [[chains]] type = "CosmosSdk" diff --git a/tools/integration-test/Cargo.toml b/tools/integration-test/Cargo.toml index 96aa5aa997..3b2327aff1 100644 --- a/tools/integration-test/Cargo.toml +++ b/tools/integration-test/Cargo.toml @@ -56,3 +56,8 @@ version = "0.34.0" [dependencies.tendermint-rpc] version = "0.34.0" features = ["http-client"] + +[dependencies.byte-unit] +version = "4.0.19" +default-features = false +features = ["serde"] \ No newline at end of file diff --git a/tools/integration-test/src/tests/clear_packet.rs b/tools/integration-test/src/tests/clear_packet.rs index 4a02ba0d14..6da6147806 100644 --- a/tools/integration-test/src/tests/clear_packet.rs +++ b/tools/integration-test/src/tests/clear_packet.rs @@ -441,11 +441,12 @@ impl BinaryChannelTest for ClearPacketSequencesTest { fn run( &self, _config: &TestConfig, - _relayer: RelayerDriver, + relayer: RelayerDriver, chains: ConnectedChains, channel: ConnectedChannel, ) -> Result<(), Error> { const NUM_TRANSFERS: usize = 20; + let packet_config = relayer.config.mode.packets; let denom_a = chains.node_a.denom(); @@ -484,6 +485,8 @@ impl BinaryChannelTest for ClearPacketSequencesTest { let opts = LinkParameters { src_port_id: channel.port_a.clone().into_value(), src_channel_id: channel.channel_id_a.clone().into_value(), + max_memo_size: packet_config.ics20_max_memo_size, + max_receiver_size: packet_config.ics20_max_receiver_size, }; // Clear all even packets diff --git a/tools/integration-test/src/tests/execute_schedule.rs b/tools/integration-test/src/tests/execute_schedule.rs index 1dd6b5262a..cd14968f33 100644 --- a/tools/integration-test/src/tests/execute_schedule.rs +++ b/tools/integration-test/src/tests/execute_schedule.rs @@ -37,15 +37,18 @@ impl BinaryChannelTest for ExecuteScheduleTest { fn run( &self, _config: &TestConfig, - _relayer: RelayerDriver, + relayer: RelayerDriver, chains: ConnectedChains, channel: ConnectedChannel, ) -> Result<(), Error> { let amount1 = random_u128_range(1000, 5000); + let packet_config = relayer.config.mode.packets; let chain_a_link_opts = LinkParameters { src_port_id: channel.port_a.clone().into_value(), src_channel_id: channel.channel_id_a.clone().into_value(), + max_memo_size: packet_config.ics20_max_memo_size, + max_receiver_size: packet_config.ics20_max_receiver_size, }; let chain_a_link = Link::new_from_opts( diff --git a/tools/integration-test/src/tests/ics20_filter/memo.rs b/tools/integration-test/src/tests/ics20_filter/memo.rs new file mode 100644 index 0000000000..0ec207af37 --- /dev/null +++ b/tools/integration-test/src/tests/ics20_filter/memo.rs @@ -0,0 +1,131 @@ +use byte_unit::Byte; + +use ibc_relayer::config::types::ics20_field_size_limit::Ics20FieldSizeLimit; +use ibc_test_framework::prelude::*; + +#[test] +fn test_memo_filter() -> Result<(), Error> { + run_binary_channel_test(&IbcMemoFilterTest) +} + +const MEMO_SIZE_LIMIT: usize = 2000; + +pub struct IbcMemoFilterTest; + +impl TestOverrides for IbcMemoFilterTest { + fn modify_relayer_config(&self, config: &mut Config) { + config.mode.packets.ics20_max_memo_size = + Ics20FieldSizeLimit::new(true, Byte::from_bytes(MEMO_SIZE_LIMIT as u64)); + + config.mode.clients.misbehaviour = false; + } +} + +impl BinaryChannelTest for IbcMemoFilterTest { + fn run( + &self, + _config: &TestConfig, + _relayer: RelayerDriver, + chains: ConnectedChains, + channel: ConnectedChannel, + ) -> Result<(), Error> { + let denom_a = chains.node_a.denom(); + + let wallet_a = chains.node_a.wallets().user1().cloned(); + let wallet_b = chains.node_b.wallets().user1().cloned(); + + let balance_a = chains + .node_a + .chain_driver() + .query_balance(&wallet_a.address(), &denom_a)?; + + let a_to_b_amount = 23456u128; + + info!( + "Sending invalid IBC transfer from chain {} to chain {} with amount of {} {}", + chains.chain_id_a(), + chains.chain_id_b(), + a_to_b_amount, + denom_a + ); + + // Create a memo bigger than the allowed limit + let memo = "a".repeat(MEMO_SIZE_LIMIT + 1); + + chains + .node_a + .chain_driver() + .ibc_transfer_token_with_memo_and_timeout( + &channel.port_a.as_ref(), + &channel.channel_id_a.as_ref(), + &wallet_a.as_ref(), + &wallet_b.address(), + &denom_a.with_amount(a_to_b_amount).as_ref(), + Some(memo), + None, + )?; + + // Wait a bit before asserting that the transaction has not been relayed + sleep(Duration::from_secs(10)); + + info!("Assert that the IBC transfer was filtered"); + + let denom_b = derive_ibc_denom( + &channel.port_b.as_ref(), + &channel.channel_id_b.as_ref(), + &denom_a, + )?; + + // The sender tokens will be escrowed since the packet will not have timed out + chains.node_a.chain_driver().assert_eventual_wallet_amount( + &wallet_a.address(), + &(balance_a.clone() - a_to_b_amount).as_ref(), + )?; + + // The receiver will not have received the tokens since the packet should be + // filtered + chains.node_b.chain_driver().assert_eventual_wallet_amount( + &wallet_b.address(), + &denom_b.with_amount(0u64).as_ref(), + )?; + + // Retry the IBC transfer without the memo field + chains + .node_a + .chain_driver() + .ibc_transfer_token_with_memo_and_timeout( + &channel.port_a.as_ref(), + &channel.channel_id_a.as_ref(), + &wallet_a.as_ref(), + &wallet_b.address(), + &denom_a.with_amount(a_to_b_amount).as_ref(), + None, + None, + )?; + + info!( + "Waiting for user on chain B to receive IBC transferred amount of {}", + a_to_b_amount + ); + + // The sender tokens from the first transaction will still be + // escrowed since the packet will not have timed out + chains.node_a.chain_driver().assert_eventual_wallet_amount( + &wallet_a.address(), + &(balance_a - a_to_b_amount - a_to_b_amount).as_ref(), + )?; + + chains.node_b.chain_driver().assert_eventual_wallet_amount( + &wallet_b.address(), + &denom_b.with_amount(a_to_b_amount).as_ref(), + )?; + + info!( + "successfully performed IBC transfer from chain {} to chain {}", + chains.chain_id_a(), + chains.chain_id_b(), + ); + + Ok(()) + } +} diff --git a/tools/integration-test/src/tests/ics20_filter/mod.rs b/tools/integration-test/src/tests/ics20_filter/mod.rs new file mode 100644 index 0000000000..80d0261cba --- /dev/null +++ b/tools/integration-test/src/tests/ics20_filter/mod.rs @@ -0,0 +1 @@ +pub mod memo; diff --git a/tools/integration-test/src/tests/mod.rs b/tools/integration-test/src/tests/mod.rs index 225c2bab19..b56c22b49d 100644 --- a/tools/integration-test/src/tests/mod.rs +++ b/tools/integration-test/src/tests/mod.rs @@ -18,6 +18,7 @@ pub mod denom_trace; pub mod error_events; pub mod execute_schedule; pub mod handshake_on_start; +pub mod ics20_filter; pub mod memo; pub mod python; pub mod query_packet; diff --git a/tools/integration-test/src/tests/ordered_channel_clear.rs b/tools/integration-test/src/tests/ordered_channel_clear.rs index 5885c98618..a005df8f62 100644 --- a/tools/integration-test/src/tests/ordered_channel_clear.rs +++ b/tools/integration-test/src/tests/ordered_channel_clear.rs @@ -78,11 +78,12 @@ impl BinaryChannelTest for OrderedChannelClearTest { fn run( &self, _config: &TestConfig, - _relayer: RelayerDriver, + relayer: RelayerDriver, chains: ConnectedChains, channel: ConnectedChannel, ) -> Result<(), Error> { let denom_a = chains.node_a.denom(); + let packet_config = relayer.config.mode.packets; let wallet_a = chains.node_a.wallets().user1().cloned(); let wallet_b = chains.node_b.wallets().user1().cloned(); @@ -118,6 +119,8 @@ impl BinaryChannelTest for OrderedChannelClearTest { let chain_a_link_opts = LinkParameters { src_port_id: channel.port_a.clone().into_value(), src_channel_id: channel.channel_id_a.clone().into_value(), + max_memo_size: packet_config.ics20_max_memo_size, + max_receiver_size: packet_config.ics20_max_receiver_size, }; let chain_a_link = Link::new_from_opts( @@ -131,6 +134,8 @@ impl BinaryChannelTest for OrderedChannelClearTest { let chain_b_link_opts = LinkParameters { src_port_id: channel.port_b.clone().into_value(), src_channel_id: channel.channel_id_b.clone().into_value(), + max_memo_size: packet_config.ics20_max_memo_size, + max_receiver_size: packet_config.ics20_max_receiver_size, }; let chain_b_link = Link::new_from_opts( @@ -224,11 +229,12 @@ impl BinaryChannelTest for OrderedChannelClearEqualCLITest { fn run( &self, _config: &TestConfig, - _relayer: RelayerDriver, + relayer: RelayerDriver, chains: ConnectedChains, channel: ConnectedChannel, ) -> Result<(), Error> { let num_msgs = 5_usize; + let packet_config = relayer.config.mode.packets; info!( "Performing {} IBC transfers on an ordered channel", @@ -264,6 +270,8 @@ impl BinaryChannelTest for OrderedChannelClearEqualCLITest { let chain_a_link_opts = LinkParameters { src_port_id: channel.port_a.clone().into_value(), src_channel_id: channel.channel_id_a.into_value(), + max_memo_size: packet_config.ics20_max_memo_size, + max_receiver_size: packet_config.ics20_max_receiver_size, }; let chain_a_link = Link::new_from_opts( diff --git a/tools/integration-test/src/tests/query_packet.rs b/tools/integration-test/src/tests/query_packet.rs index 3f22600fed..4ae21ac725 100644 --- a/tools/integration-test/src/tests/query_packet.rs +++ b/tools/integration-test/src/tests/query_packet.rs @@ -30,11 +30,12 @@ impl BinaryChannelTest for QueryPacketPendingTest { fn run( &self, _config: &TestConfig, - _relayer: RelayerDriver, + relayer: RelayerDriver, chains: ConnectedChains, channel: ConnectedChannel, ) -> Result<(), Error> { let denom_a = chains.node_a.denom(); + let packet_config = relayer.config.mode.packets; let wallet_a = chains.node_a.wallets().user1().cloned(); let wallet_b = chains.node_b.wallets().user1().cloned(); @@ -59,6 +60,8 @@ impl BinaryChannelTest for QueryPacketPendingTest { let opts = LinkParameters { src_port_id: channel.port_a.clone().into_value(), src_channel_id: channel.channel_id_a.clone().into_value(), + max_memo_size: packet_config.ics20_max_memo_size, + max_receiver_size: packet_config.ics20_max_receiver_size, }; let link = Link::new_from_opts( chains.handle_a().clone(),