Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exclude ChannelEnd from MsgChannelOpenInit and MsgChannelOpenTry #327

Merged
merged 5 commits into from
Jan 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Exclude `ChannelEnd` from `MsgChannelOpenInit` and `MsgChannelOpenTry` and refactor their fields to match the spec
([#20](https://github.com/cosmos/ibc-rs/issues/20))
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Make internal `process()` `pub(crate)`
([#338](https://github.com/cosmos/ibc-rs/issues/338))

This file was deleted.

15 changes: 8 additions & 7 deletions crates/ibc/src/core/ics04_channel/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -501,34 +501,35 @@ impl Display for State {

#[cfg(test)]
pub mod test_util {
use crate::core::ics24_host::identifier::{ChannelId, ConnectionId, PortId};
use crate::core::ics24_host::identifier::{ConnectionId, PortId};
use crate::prelude::*;
use ibc_proto::ibc::core::channel::v1::Channel as RawChannel;
use ibc_proto::ibc::core::channel::v1::Counterparty as RawCounterparty;

/// Returns a dummy `RawCounterparty`, for testing only!
/// Can be optionally parametrized with a specific channel identifier.
pub fn get_dummy_raw_counterparty() -> RawCounterparty {
pub fn get_dummy_raw_counterparty(channel_id: String) -> RawCounterparty {
RawCounterparty {
port_id: PortId::default().to_string(),
channel_id: ChannelId::default().to_string(),
channel_id,
}
}

/// Returns a dummy `RawChannel`, for testing only!
pub fn get_dummy_raw_channel_end() -> RawChannel {
pub fn get_dummy_raw_channel_end(channel_id: String) -> RawChannel {
RawChannel {
state: 1,
ordering: 2,
counterparty: Some(get_dummy_raw_counterparty()),
counterparty: Some(get_dummy_raw_counterparty(channel_id)),
connection_hops: vec![ConnectionId::default().to_string()],
version: "ics20".to_string(), // The version is not validated.
version: "".to_string(), // The version is not validated.
}
}
}

#[cfg(test)]
mod tests {
use crate::core::ics24_host::identifier::ChannelId;
use crate::prelude::*;

use core::str::FromStr;
Expand All @@ -541,7 +542,7 @@ mod tests {

#[test]
fn channel_end_try_from_raw() {
let raw_channel_end = get_dummy_raw_channel_end();
let raw_channel_end = get_dummy_raw_channel_end(ChannelId::default().to_string());

let empty_raw_channel_end = RawChannel {
counterparty: None,
Expand Down
16 changes: 8 additions & 8 deletions crates/ibc/src/core/ics04_channel/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,25 +115,25 @@ where
match msg {
ChannelMsg::OpenInit(msg) => {
let (extras, version) = cb.on_chan_open_init(
msg.chan_end_on_a.ordering,
&msg.chan_end_on_a.connection_hops,
msg.ordering,
&msg.connection_hops_on_a,
&msg.port_id_on_a,
&result.channel_id,
msg.chan_end_on_a.counterparty(),
&msg.chan_end_on_a.version,
&Counterparty::new(msg.port_id_on_b.clone(), None),
&msg.version_proposal,
)?;
result.channel_end.version = version;

Ok(extras)
}
ChannelMsg::OpenTry(msg) => {
let (extras, version) = cb.on_chan_open_try(
msg.chan_end_on_b.ordering,
&msg.chan_end_on_b.connection_hops,
msg.ordering,
&msg.connection_hops_on_b,
&msg.port_id_on_b,
&result.channel_id,
msg.chan_end_on_b.counterparty(),
&msg.version_on_a,
&Counterparty::new(msg.port_id_on_a.clone(), Some(msg.chan_id_on_a.clone())),
&msg.version_supported_on_a,
)?;
result.channel_end.version = version;

Expand Down
8 changes: 4 additions & 4 deletions crates/ibc/src/core/ics04_channel/handler/chan_open_ack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,24 +198,24 @@ mod tests {

let chan_end = ChannelEnd::new(
State::Init,
*msg_chan_try.chan_end_on_b.ordering(),
msg_chan_try.ordering,
Counterparty::new(
msg_chan_ack.port_id_on_a.clone(),
Some(msg_chan_ack.chan_id_on_a.clone()),
),
connection_vec0.clone(),
msg_chan_try.chan_end_on_b.version().clone(),
msg_chan_try.version_supported_on_a.clone(),
);

let failed_chan_end = ChannelEnd::new(
State::Open,
*msg_chan_try.chan_end_on_b.ordering(),
msg_chan_try.ordering,
Counterparty::new(
msg_chan_ack.port_id_on_a.clone(),
Some(msg_chan_ack.chan_id_on_a.clone()),
),
connection_vec0,
msg_chan_try.chan_end_on_b.version().clone(),
msg_chan_try.version_supported_on_a,
);

let tests: Vec<Test> = vec![
Expand Down
18 changes: 9 additions & 9 deletions crates/ibc/src/core/ics04_channel/handler/chan_open_init.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Protocol logic specific to ICS4 messages of type `MsgChannelOpenInit`.

use crate::core::ics04_channel::channel::{ChannelEnd, State};
use crate::core::ics04_channel::channel::{ChannelEnd, Counterparty, State};
use crate::core::ics04_channel::context::ChannelReader;
use crate::core::ics04_channel::error::ChannelError;
use crate::core::ics04_channel::handler::{ChannelIdState, ChannelResult};
Expand All @@ -16,32 +16,32 @@ pub(crate) fn process<Ctx: ChannelReader>(
) -> HandlerResult<ChannelResult, ChannelError> {
let mut output = HandlerOutput::builder();

if msg.chan_end_on_a.connection_hops().len() != 1 {
if msg.connection_hops_on_a.len() != 1 {
return Err(ChannelError::InvalidConnectionHopsLength {
expected: 1,
actual: msg.chan_end_on_a.connection_hops().len(),
actual: msg.connection_hops_on_a.len(),
});
}

// An IBC connection running on the local (host) chain should exist.
let conn_end_on_a = ctx_a.connection_end(&msg.chan_end_on_a.connection_hops()[0])?;
let conn_end_on_a = ctx_a.connection_end(&msg.connection_hops_on_a[0])?;

let conn_version = match conn_end_on_a.versions() {
[version] => version,
_ => return Err(ChannelError::InvalidVersionLengthConnection),
};

let channel_feature = msg.chan_end_on_a.ordering().to_string();
let channel_feature = msg.ordering.to_string();
if !conn_version.is_supported_feature(channel_feature) {
return Err(ChannelError::ChannelFeatureNotSuportedByConnection);
}

let chan_end_on_a = ChannelEnd::new(
State::Init,
*msg.chan_end_on_a.ordering(),
msg.chan_end_on_a.counterparty().clone(),
msg.chan_end_on_a.connection_hops().clone(),
msg.chan_end_on_a.version().clone(),
msg.ordering,
Counterparty::new(msg.port_id_on_b.clone(), None),
msg.connection_hops_on_a.clone(),
msg.version_proposal.clone(),
);

let chan_id_on_a = ChannelId::new(ctx_a.channel_counter()?);
Expand Down
58 changes: 27 additions & 31 deletions crates/ibc/src/core/ics04_channel/handler/chan_open_try.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,17 @@ pub(crate) fn process<Ctx: ChannelReader>(
let mut output = HandlerOutput::builder();

// An IBC connection running on the local (host) chain should exist.
if msg.chan_end_on_b.connection_hops().len() != 1 {
if msg.connection_hops_on_b.len() != 1 {
return Err(ChannelError::InvalidConnectionHopsLength {
expected: 1,
actual: msg.chan_end_on_b.connection_hops().len(),
actual: msg.connection_hops_on_b.len(),
});
}

let conn_end_on_b = ctx_b.connection_end(&msg.chan_end_on_b.connection_hops()[0])?;
let conn_end_on_b = ctx_b.connection_end(&msg.connection_hops_on_b[0])?;
if !conn_end_on_b.state_matches(&ConnectionState::Open) {
return Err(ChannelError::ConnectionNotOpen {
connection_id: msg.chan_end_on_b.connection_hops()[0].clone(),
connection_id: msg.connection_hops_on_b[0].clone(),
});
}

Expand All @@ -38,7 +38,7 @@ pub(crate) fn process<Ctx: ChannelReader>(
_ => return Err(ChannelError::InvalidVersionLengthConnection),
};

let channel_feature = msg.chan_end_on_b.ordering().to_string();
let channel_feature = msg.ordering.to_string();
if !conn_version.is_supported_feature(channel_feature) {
return Err(ChannelError::ChannelFeatureNotSuportedByConnection);
}
Expand All @@ -50,15 +50,11 @@ pub(crate) fn process<Ctx: ChannelReader>(
let consensus_state_of_a_on_b =
ctx_b.client_consensus_state(client_id_on_b, &msg.proof_height_on_a)?;
let prefix_on_a = conn_end_on_b.counterparty().prefix();
let port_id_on_a = &msg.chan_end_on_b.counterparty().port_id;
let chan_id_on_a = msg
.chan_end_on_b
.counterparty()
.channel_id()
.ok_or(ChannelError::InvalidCounterpartyChannelId)?;
let port_id_on_a = &&msg.port_id_on_a;
let chan_id_on_a = msg.chan_id_on_a.clone();
let conn_id_on_a = conn_end_on_b.counterparty().connection_id().ok_or(
ChannelError::UndefinedConnectionCounterparty {
connection_id: msg.chan_end_on_b.connection_hops()[0].clone(),
connection_id: msg.connection_hops_on_b[0].clone(),
},
)?;

Expand All @@ -71,10 +67,10 @@ pub(crate) fn process<Ctx: ChannelReader>(

let expected_chan_end_on_a = ChannelEnd::new(
State::Init,
*msg.chan_end_on_b.ordering(),
msg.ordering,
Counterparty::new(msg.port_id_on_b.clone(), None),
vec![conn_id_on_a.clone()],
msg.version_on_a.clone(),
msg.version_supported_on_a.clone(),
);

// Verify the proof for the channel state against the expected channel end.
Expand All @@ -86,17 +82,17 @@ pub(crate) fn process<Ctx: ChannelReader>(
&msg.proof_chan_end_on_a,
consensus_state_of_a_on_b.root(),
port_id_on_a,
chan_id_on_a,
&chan_id_on_a,
&expected_chan_end_on_a,
)
.map_err(ChannelError::VerifyChannelFailed)?;
}

let chan_end_on_b = ChannelEnd::new(
State::TryOpen,
*msg.chan_end_on_b.ordering(),
msg.chan_end_on_b.counterparty().clone(),
msg.chan_end_on_b.connection_hops().clone(),
msg.ordering,
Counterparty::new(msg.port_id_on_a.clone(), Some(msg.chan_id_on_a.clone())),
msg.connection_hops_on_b.clone(),
// Note: This will be rewritten by the module callback
Version::empty(),
);
Expand Down Expand Up @@ -132,11 +128,12 @@ mod tests {
use crate::core::ics03_connection::error as ics03_error;
use crate::core::ics03_connection::msgs::test_util::get_dummy_raw_counterparty;
use crate::core::ics03_connection::version::get_compatible_versions;
use crate::core::ics04_channel::channel::{ChannelEnd, State};
use crate::core::ics04_channel::channel::{ChannelEnd, Counterparty, State};
use crate::core::ics04_channel::error;
use crate::core::ics04_channel::msgs::chan_open_try::test_util::get_dummy_raw_msg_chan_open_try;
use crate::core::ics04_channel::msgs::chan_open_try::MsgChannelOpenTry;
use crate::core::ics04_channel::msgs::ChannelMsg;
use crate::core::ics04_channel::Version;
use crate::core::ics24_host::identifier::{ChannelId, ClientId, ConnectionId};
use crate::mock::client_state::client_type as mock_client_type;
use crate::mock::context::MockContext;
Expand Down Expand Up @@ -176,16 +173,16 @@ mod tests {

let chan_id = ChannelId::new(24);
let hops = vec![conn_id.clone()];
msg.chan_end_on_b.connection_hops = hops;
msg.connection_hops_on_b = hops;

// A preloaded channel end that resides in the context. This is constructed so as to be
// consistent with the incoming ChanOpenTry message `msg`.
let correct_chan_end = ChannelEnd::new(
State::Init,
*msg.chan_end_on_b.ordering(),
msg.chan_end_on_b.counterparty().clone(),
msg.chan_end_on_b.connection_hops().clone(),
msg.chan_end_on_b.version().clone(),
msg.ordering,
Counterparty::new(msg.port_id_on_a.clone(), Some(msg.chan_id_on_a.clone())),
msg.connection_hops_on_b.clone(),
Version::empty(),
);

let tests: Vec<Test> = vec![
Expand All @@ -195,7 +192,7 @@ mod tests {
msg: ChannelMsg::OpenTry(msg.clone()),
want_pass: false,
match_error: {
let connection_id = msg.chan_end_on_b.connection_hops()[0].clone();
let connection_id = msg.connection_hops_on_b[0].clone();
Box::new(move |e| match e {
error::ChannelError::Connection(e) => {
assert_eq!(
Expand Down Expand Up @@ -320,18 +317,17 @@ mod tests {
// Note: we make the counterparty's channel_id `None`.
let mut msg =
MsgChannelOpenTry::try_from(get_dummy_raw_msg_chan_open_try(proof_height)).unwrap();
msg.chan_end_on_b.remote.channel_id = None;

let chan_id = ChannelId::new(24);
let hops = vec![conn_id.clone()];
msg.chan_end_on_b.connection_hops = hops;
msg.connection_hops_on_b = hops;

let chan_end = ChannelEnd::new(
State::Init,
*msg.chan_end_on_b.ordering(),
msg.chan_end_on_b.counterparty().clone(),
msg.chan_end_on_b.connection_hops().clone(),
msg.chan_end_on_b.version().clone(),
msg.ordering,
Counterparty::new(msg.port_id_on_a.clone(), None),
msg.connection_hops_on_b.clone(),
Version::empty(),
);
let context = MockContext::default()
.with_client(&client_id, Height::new(0, proof_height).unwrap())
Expand Down
Loading