Skip to content

Commit

Permalink
Add integration tests for connection and channel workers
Browse files Browse the repository at this point in the history
  • Loading branch information
soareschen committed Dec 15, 2021
1 parent 490b8df commit aad0e00
Show file tree
Hide file tree
Showing 13 changed files with 296 additions and 19 deletions.
5 changes: 3 additions & 2 deletions modules/src/core/ics24_host/identifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,8 +293,9 @@ impl PartialEq<str> for ConnectionId {
pub struct PortId(String);

impl PortId {
pub fn unsafe_new(id: &str) -> Self {
Self(id.to_string())
/// Infallible creation of the well-known transfer port
pub fn transfer() -> Self {
Self("transfer".to_string())
}

/// Get this identifier as a borrowed `&str`
Expand Down
2 changes: 1 addition & 1 deletion relayer/src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1112,7 +1112,7 @@ impl<ChainA: ChainHandle, ChainB: ChainHandle> Connection<ChainA, ChainB> {
}
}

fn extract_connection_id(event: &IbcEvent) -> Result<&ConnectionId, ConnectionError> {
pub fn extract_connection_id(event: &IbcEvent) -> Result<&ConnectionId, ConnectionError> {
match event {
IbcEvent::OpenInitConnection(ev) => ev.connection_id().as_ref(),
IbcEvent::OpenTryConnection(ev) => ev.connection_id().as_ref(),
Expand Down
4 changes: 2 additions & 2 deletions tools/integration-test/src/framework/overrides.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ pub trait TestOverrides {
Implemented for [`PortsOverride`].
*/
fn channel_port_a(&self) -> PortId {
PortId::unsafe_new("transfer")
PortId::transfer()
}

/**
Expand All @@ -92,7 +92,7 @@ pub trait TestOverrides {
Implemented for [`PortsOverride`].
*/
fn channel_port_b(&self) -> PortId {
PortId::unsafe_new("transfer")
PortId::transfer()
}
}

Expand Down
25 changes: 15 additions & 10 deletions tools/integration-test/src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/

pub use eyre::eyre;
pub use ibc::core::ics24_host::identifier::{ChainId, ChannelId, ClientId, ConnectionId, PortId};
pub use ibc_relayer::chain::handle::ChainHandle;
pub use ibc_relayer::config::Config;
pub use ibc_relayer::config::SharedConfig;
Expand All @@ -12,22 +13,26 @@ pub use tracing::{debug, error, info, warn};

pub use crate::chain::driver::{tagged::TaggedChainDriverExt, ChainDriver};
pub use crate::error::Error;
pub use crate::framework::base::HasOverrides;
pub use crate::framework::binary::chain::{
run_binary_chain_test, run_two_way_binary_chain_test, BinaryChainTest,
};
pub use crate::framework::binary::channel::{
run_binary_channel_test, run_two_way_binary_channel_test, BinaryChannelTest,
};
pub use crate::framework::binary::node::{run_binary_node_test, BinaryNodeTest};
pub use crate::framework::overrides::TestOverrides;
pub use crate::relayer::channel::TaggedChannelEndExt;
pub use crate::relayer::connection::{TaggedConnectionEndExt, TaggedConnectionExt};
pub use crate::relayer::foreign_client::TaggedForeignClientExt;
pub use crate::types::binary::chains::ConnectedChains;
pub use crate::types::binary::channel::ConnectedChannel;
pub use crate::types::config::TestConfig;
pub use crate::types::id::*;
pub use crate::types::single::node::{FullNode, TaggedFullNodeExt};
pub use crate::types::tagged::{DualTagged, MonoTagged};
pub use crate::types::wallet::{
TaggedTestWalletsExt, TaggedWallet, TestWallets, Wallet, WalletAddress, WalletId,
};
pub use crate::util::retry::assert_eventually_succeed;
pub use crate::util::suspend::suspend;

pub use crate::framework::binary::channel::{
run_binary_channel_test, run_two_way_binary_channel_test, BinaryChannelTest,
};

pub use crate::framework::binary::chain::{
run_binary_chain_test, run_two_way_binary_chain_test, BinaryChainTest,
};

pub use crate::framework::binary::node::{run_binary_node_test, BinaryNodeTest};
71 changes: 71 additions & 0 deletions tools/integration-test/src/relayer/channel.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use ibc::core::ics04_channel::channel::{ChannelEnd, Order};
use ibc::Height;
use ibc_relayer::chain::handle::ChainHandle;
use ibc_relayer::channel::{extract_channel_id, Channel, ChannelSide};

use crate::error::Error;
use crate::types::id::{
TaggedChannelId, TaggedChannelIdRef, TaggedClientIdRef, TaggedConnectionIdRef, TaggedPortIdRef,
};
use crate::types::tagged::DualTagged;

pub trait TaggedChannelEndExt<ChainA, ChainB> {
fn tagged_counterparty_channel_id(&self) -> Option<TaggedChannelId<ChainB, ChainA>>;
}

impl<ChainA, ChainB> TaggedChannelEndExt<ChainA, ChainB>
for DualTagged<ChainA, ChainB, ChannelEnd>
{
fn tagged_counterparty_channel_id(&self) -> Option<TaggedChannelId<ChainB, ChainA>> {
self.contra_map(|c| c.counterparty().channel_id.clone())
.transpose()
}
}

pub fn init_channel<ChainA: ChainHandle, ChainB: ChainHandle>(
handle_a: &ChainA,
handle_b: &ChainB,
client_id_a: &TaggedClientIdRef<ChainA, ChainB>,
client_id_b: &TaggedClientIdRef<ChainB, ChainA>,
connection_id_a: &TaggedConnectionIdRef<ChainA, ChainB>,
connection_id_b: &TaggedConnectionIdRef<ChainB, ChainA>,
src_port_id: &TaggedPortIdRef<ChainA, ChainB>,
dst_port_id: &TaggedPortIdRef<ChainB, ChainA>,
) -> Result<TaggedChannelId<ChainB, ChainA>, Error> {
let channel = Channel {
connection_delay: Default::default(),
ordering: Order::Unordered,
a_side: ChannelSide::new(
handle_a.clone(),
client_id_a.cloned_value(),
connection_id_a.cloned_value(),
src_port_id.cloned_value(),
None,
None,
),
b_side: ChannelSide::new(
handle_b.clone(),
client_id_b.cloned_value(),
connection_id_b.cloned_value(),
dst_port_id.cloned_value(),
None,
None,
),
};

let event = channel.build_chan_open_init_and_send()?;

let channel_id = extract_channel_id(&event)?;

Ok(DualTagged::new(channel_id.clone()))
}

pub fn query_channel_end<ChainA: ChainHandle, ChainB>(
handle: &ChainA,
channel_id: &TaggedChannelIdRef<ChainA, ChainB>,
port_id: &TaggedPortIdRef<ChainA, ChainB>,
) -> Result<DualTagged<ChainA, ChainB, ChannelEnd>, Error> {
let channel_end = handle.query_channel(port_id.value(), channel_id.value(), Height::zero())?;

Ok(DualTagged::new(channel_end))
}
51 changes: 48 additions & 3 deletions tools/integration-test/src/relayer/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@
Definition for extension trait methods for [`Connection`]
*/

use ibc::core::ics03_connection::connection::ConnectionEnd;
use ibc::timestamp::ZERO_DURATION;
use ibc::Height;
use ibc_relayer::chain::handle::ChainHandle;
use ibc_relayer::connection::Connection;
use ibc_relayer::connection::{extract_connection_id, Connection, ConnectionSide};

use crate::types::id::TaggedConnectionIdRef;
use crate::types::tagged::*;
use crate::error::Error;
use crate::types::id::{TaggedClientIdRef, TaggedConnectionId, TaggedConnectionIdRef};
use crate::types::tagged::DualTagged;

/**
An extension trait that provide helper methods to get tagged identifiers
Expand All @@ -24,6 +28,10 @@ pub trait TaggedConnectionExt<ChainA: ChainHandle, ChainB: ChainHandle> {
fn tagged_connection_id_b(&self) -> Option<TaggedConnectionIdRef<ChainB, ChainA>>;
}

pub trait TaggedConnectionEndExt<ChainA, ChainB> {
fn tagged_counterparty_connection_id(&self) -> Option<TaggedConnectionId<ChainB, ChainA>>;
}

impl<ChainA: ChainHandle, ChainB: ChainHandle> TaggedConnectionExt<ChainA, ChainB>
for Connection<ChainA, ChainB>
{
Expand All @@ -35,3 +43,40 @@ impl<ChainA: ChainHandle, ChainB: ChainHandle> TaggedConnectionExt<ChainA, Chain
self.b_side.connection_id().map(DualTagged::new)
}
}

impl<ChainA, ChainB> TaggedConnectionEndExt<ChainA, ChainB>
for DualTagged<ChainA, ChainB, ConnectionEnd>
{
fn tagged_counterparty_connection_id(&self) -> Option<TaggedConnectionId<ChainB, ChainA>> {
self.contra_map(|c| c.counterparty().connection_id.clone())
.transpose()
}
}

pub fn init_connection<ChainA: ChainHandle, ChainB: ChainHandle>(
handle_a: &ChainA,
handle_b: &ChainB,
client_id_a: &TaggedClientIdRef<ChainA, ChainB>,
client_id_b: &TaggedClientIdRef<ChainB, ChainA>,
) -> Result<TaggedConnectionId<ChainB, ChainA>, Error> {
let connection = Connection {
delay_period: ZERO_DURATION,
a_side: ConnectionSide::new(handle_a.clone(), (*client_id_a.value()).clone(), None),
b_side: ConnectionSide::new(handle_b.clone(), (*client_id_b.value()).clone(), None),
};

let event = connection.build_conn_init_and_send()?;

let connection_id = extract_connection_id(&event)?;

Ok(DualTagged::new(connection_id.clone()))
}

pub fn query_connection_end<ChainA: ChainHandle, ChainB>(
handle: &ChainA,
connection_id: &TaggedConnectionIdRef<ChainA, ChainB>,
) -> Result<DualTagged<ChainA, ChainB, ConnectionEnd>, Error> {
let connection_end = handle.query_connection(connection_id.value(), Height::zero())?;

Ok(DualTagged::new(connection_end))
}
1 change: 1 addition & 0 deletions tools/integration-test/src/relayer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*/

pub mod chain;
pub mod channel;
pub mod connection;
pub mod foreign_client;
pub mod transfer;
1 change: 1 addition & 0 deletions tools/integration-test/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

pub mod memo;
pub mod supervisor;
pub mod transfer;

#[cfg(any(doc, feature = "manual"))]
Expand Down
132 changes: 132 additions & 0 deletions tools/integration-test/src/tests/supervisor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
use core::time::Duration;
use ibc::core::ics03_connection::connection::State as ConnectionState;
use ibc::core::ics04_channel::channel::State as ChannelState;
use ibc_relayer::config::{self, Config, ModeConfig};

use crate::prelude::*;
pub use crate::relayer::channel::{init_channel, query_channel_end};
pub use crate::relayer::connection::{init_connection, query_connection_end};

#[test]
fn test_supervisor() -> Result<(), Error> {
run_binary_chain_test(&SupervisorTest)
}

struct SupervisorTest;

impl TestOverrides for SupervisorTest {
fn modify_relayer_config(&self, config: &mut Config) {
config.mode = ModeConfig {
clients: config::Clients {
enabled: true,
refresh: true,
misbehaviour: true,
},
connections: config::Connections { enabled: true },
channels: config::Channels { enabled: true },
packets: config::Packets {
enabled: true,
clear_interval: 10,
clear_on_start: true,
filter: false,
tx_confirmation: true,
},
};
}
}

impl BinaryChainTest for SupervisorTest {
fn run<ChainA: ChainHandle, ChainB: ChainHandle>(
&self,
_config: &TestConfig,
chains: ConnectedChains<ChainA, ChainB>,
) -> Result<(), Error> {
let connection_id_b = init_connection(
&chains.handle_a,
&chains.handle_b,
&chains.client_b_to_a.tagged_client_id(),
&chains.client_a_to_b.tagged_client_id(),
)?;

let connection_id_a = assert_eventually_succeed(
"connection should eventually open",
|| {
let connection_end_b =
query_connection_end(&chains.handle_b, &connection_id_b.as_ref())?;

if !connection_end_b
.value()
.state_matches(&ConnectionState::Open)
{
return Err(eyre!("expeted connection end A to be in open state"));
}

let connection_id_a = connection_end_b
.tagged_counterparty_connection_id()
.ok_or_else(|| {
eyre!("expected counterparty connection id to present on open connection")
})?;

let connection_end_a =
query_connection_end(&chains.handle_a, &connection_id_a.as_ref())?;

if !connection_end_a
.value()
.state_matches(&ConnectionState::Open)
{
return Err(eyre!("expeted connection end B to be in open state"));
}

Ok(connection_id_a)
},
20,
Duration::from_secs(1),
)?;

let port_a = tagged_transfer_port();
let port_b = tagged_transfer_port();

let channel_id_b = init_channel(
&chains.handle_a,
&chains.handle_b,
&chains.client_id_a(),
&chains.client_id_b(),
&connection_id_a.as_ref(),
&connection_id_b.as_ref(),
&port_a.as_ref(),
&port_b.as_ref(),
)?;

assert_eventually_succeed(
"channel should eventually open",
|| {
let channel_end_b =
query_channel_end(&chains.handle_b, &channel_id_b.as_ref(), &port_b.as_ref())?;

if !channel_end_b.value().state_matches(&ChannelState::Open) {
return Err(eyre!("expeted channel end A to be in open state"));
}

let channel_id_a =
channel_end_b
.tagged_counterparty_channel_id()
.ok_or_else(|| {
eyre!("expected counterparty channel id to present on open channel")
})?;

let channel_end_a =
query_channel_end(&chains.handle_a, &channel_id_a.as_ref(), &port_a.as_ref())?;

if !channel_end_a.value().state_matches(&ChannelState::Open) {
return Err(eyre!("expeted channel end B to be in open state"));
}

Ok(channel_id_a)
},
20,
Duration::from_secs(1),
)?;

Ok(())
}
}
Loading

0 comments on commit aad0e00

Please sign in to comment.