Skip to content

Commit

Permalink
ICS 4 Domain Types for channel handshakes (#391)
Browse files Browse the repository at this point in the history
* First step towards #315

* Domain type & tests for chan_open_init.

* Fix FMT

* WIP ChannelOpenTry Domain type & tests

* Re-adding ConnectionMsgType (accidentally removed).

* Done with OpenTry msg

* Finished ChanOpenAck domain type + tests; also fmt fix.

* Finished ChanOpenConfirm message

* ChanCloseInit done

* FMT fix

* Removed unnecessary derives. Close Confirm done

* Rename packet into RecvPacket. Almost done.

* Updated changelog
  • Loading branch information
adizere authored Nov 12, 2020
1 parent e9f5372 commit 3abb563
Show file tree
Hide file tree
Showing 15 changed files with 1,050 additions and 505 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ Special thanks to external contributors for this release: @CharlyCst ([#347]).

- [changelog] Added "unreleased" section in `CHANGELOG.MD` to help streamline releases ([#274])
- [relayer] Integrate relayer spike into relayer crate ([#335])
- [modules] Implement flexible connection id selection ([#332])
- [modules]
- Implement flexible connection id selection ([#332])
- ICS 4 Domain Types for channel handshakes ([#315])
- [relayer] Implement `query_header_at_height` via plain RPC queries (no light client verification) ([#336])
- [relayer-cli]
- Merge light clients config in relayer config and add commands to add/remove light clients ([#348])
Expand All @@ -19,6 +21,7 @@ Special thanks to external contributors for this release: @CharlyCst ([#347]).
- [ibc-proto] Refactor and allow specifying a commit at which the Cosmos SDK should be checked out ([#366])

[#274]: https://github.com/informalsystems/ibc-rs/issues/274
[#315]: https://github.com/informalsystems/ibc-rs/issues/315
[#332]: https://github.com/informalsystems/ibc-rs/issues/332
[#335]: https://github.com/informalsystems/ibc-rs/pulls/335
[#336]: https://github.com/informalsystems/ibc-rs/issues/336
Expand Down
60 changes: 38 additions & 22 deletions modules/src/ics04_channel/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ use crate::ics04_channel::error::{self, Error, Kind};
use crate::ics24_host::identifier::{ChannelId, ConnectionId, PortId};

use ibc_proto::ibc::core::channel::v1::Channel as RawChannel;
use tendermint_proto::DomainType;

use anomaly::fail;
use std::convert::TryFrom;
use std::str::FromStr;
use tendermint_proto::DomainType;

#[derive(Clone, Debug, PartialEq)]
pub struct ChannelEnd {
Expand Down Expand Up @@ -50,9 +50,7 @@ impl TryFrom<RawChannel> for ChannelEnd {
.collect::<Result<Vec<_>, _>>()
.map_err(|e| Kind::IdentifierError.context(e))?;

// This field is supposed to be opaque to the core IBC protocol. Empty
// version is allowed by the specification (cf. ICS 004). No explicit validation necessary.
let version = value.version;
let version = validate_version(value.version)?;

let mut channel_end = ChannelEnd::new(chan_ordering, remote, connection_hops, version);
channel_end.set_state(chan_state);
Expand Down Expand Up @@ -241,37 +239,55 @@ impl State {
}
}

/// Version validation, specific for channel (ICS4) opening handshake protocol.
/// This field is supposed to be opaque to the core IBC protocol. No explicit validation necessary,
/// and empty version is currently allowed by the specification (cf. ICS 004, v1).
pub fn validate_version(version: String) -> Result<String, Error> {
Ok(version)
}

#[cfg(test)]
pub mod test_util {
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!
pub fn get_dummy_raw_counterparty() -> RawCounterparty {
RawCounterparty {
port_id: "0123456789".into(),
channel_id: "0987654321".into(),
}
}

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

#[cfg(test)]
mod tests {
use std::str::FromStr;

use crate::ics04_channel::channel::test_util::get_dummy_raw_channel_end;
use crate::ics04_channel::channel::ChannelEnd;

use ibc_proto::ibc::core::channel::v1::Channel as RawChannel;
use ibc_proto::ibc::core::channel::v1::Counterparty as RawCounterparty;
use std::convert::TryFrom;

#[test]
fn channel_end_try_from_raw() {
let raw_channel_end = get_dummy_raw_channel_end();

let empty_raw_channel_end = RawChannel {
state: 0,
ordering: 0,
counterparty: None,
connection_hops: vec![],
version: "".to_string(),
};

let cparty = RawCounterparty {
port_id: "0123456789".into(),
channel_id: "0987654321".into(),
};

let raw_channel_end = RawChannel {
state: 0,
ordering: 0,
counterparty: Some(cparty),
connection_hops: vec![],
version: "".to_string(), // The version is not validated.
..raw_channel_end.clone()
};

struct Test {
Expand Down
9 changes: 9 additions & 0 deletions modules/src/ics04_channel/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,15 @@ pub enum Kind {
#[error("invalid version")]
InvalidVersion,

#[error("invalid signer address")]
InvalidSigner,

#[error("invalid proof")]
InvalidProof,

#[error("invalid proof: missing height")]
MissingHeight,

#[error("invalid packet")]
InvalidPacket,

Expand All @@ -31,6 +37,9 @@ pub enum Kind {

#[error("missing counterparty")]
MissingCounterparty,

#[error("missing channel end")]
MissingChannel,
}

impl Kind {
Expand Down
2 changes: 1 addition & 1 deletion modules/src/ics04_channel/msgs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ pub mod chan_close_init;

// Packet specific messages.
pub mod acknowledgement;
pub mod packet;
pub mod recv_packet;
pub mod timeout;
36 changes: 36 additions & 0 deletions modules/src/ics04_channel/msgs/acknowledgement.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
use crate::address::{account_to_string, string_to_account};
use crate::ics04_channel::error::{Error, Kind};
use crate::ics04_channel::packet::Packet;
use crate::ics23_commitment::commitment::CommitmentProof;
use crate::{proofs::Proofs, tx_msg::Msg, Height};

use ibc_proto::ibc::core::channel::v1::MsgAcknowledgement as RawMsgAcknowledgement;
use tendermint::account::Id as AccountId;
use tendermint_proto::DomainType;

use std::convert::TryFrom;

/// Message type for the `MsgAcknowledgement` message.
const TYPE_MSG_ACKNOWLEDGEMENT: &str = "ics04/opaque";
Expand Down Expand Up @@ -64,3 +69,34 @@ impl Msg for MsgAcknowledgement {
vec![self.signer]
}
}

impl DomainType<RawMsgAcknowledgement> for MsgAcknowledgement {}

#[allow(unreachable_code)]
impl TryFrom<RawMsgAcknowledgement> for MsgAcknowledgement {
type Error = anomaly::Error<Kind>;

fn try_from(raw_msg: RawMsgAcknowledgement) -> Result<Self, Self::Error> {
let signer =
string_to_account(raw_msg.signer).map_err(|e| Kind::InvalidSigner.context(e))?;

Ok(MsgAcknowledgement {
packet: Packet,
acknowledgement: vec![],
signer,
proofs: todo!(),
})
}
}

impl From<MsgAcknowledgement> for RawMsgAcknowledgement {
fn from(domain_msg: MsgAcknowledgement) -> Self {
RawMsgAcknowledgement {
packet: None,
acknowledgement: vec![],
proof: vec![],
signer: account_to_string(domain_msg.signer).unwrap(),
proof_height: None,
}
}
}
Loading

0 comments on commit 3abb563

Please sign in to comment.