Skip to content

Commit

Permalink
feat: implement chan-upgrade-cancel and add integration test for time…
Browse files Browse the repository at this point in the history
…out on upgrade ack
  • Loading branch information
crodriguezvega committed Dec 17, 2023
1 parent 2b4a2d9 commit 76d88e0
Show file tree
Hide file tree
Showing 25 changed files with 1,048 additions and 30 deletions.
3 changes: 3 additions & 0 deletions crates/relayer-cli/src/commands/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ pub enum TxCmd {
/// Relay the channel upgrade attempt (ChannelUpgradeOpen)
ChanUpgradeOpen(channel::TxChanUpgradeOpenCmd),

/// Relay the channel upgrade cancellation (ChannelUpgradeCancel)
ChanUpgradeCancel(channel::TxChanUpgradeCancelCmd),

/// Send a fungible token transfer test transaction (ICS20 MsgTransfer)
FtTransfer(transfer::TxIcs20MsgTransferCmd),

Expand Down
130 changes: 130 additions & 0 deletions crates/relayer-cli/src/commands/tx/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1185,6 +1185,136 @@ impl Runnable for TxChanUpgradeOpenCmd {
}
}

/// Relay channel upgrade cancel when counterparty has aborted the upgrade (ChannelUpgradeCancel)
///
/// Build and send a `ChannelUpgradeCancel` message to cancel
/// the channel upgrade handshake given that the counterparty has aborted.
#[derive(Clone, Command, Debug, Parser, PartialEq, Eq)]
pub struct TxChanUpgradeCancelCmd {
#[clap(
long = "dst-chain",
required = true,
value_name = "DST_CHAIN_ID",
help_heading = "REQUIRED",
help = "Identifier of the destination chain"
)]
dst_chain_id: ChainId,

#[clap(
long = "src-chain",
required = true,
value_name = "SRC_CHAIN_ID",
help_heading = "REQUIRED",
help = "Identifier of the source chain"
)]
src_chain_id: ChainId,

#[clap(
long = "dst-connection",
visible_alias = "dst-conn",
required = true,
value_name = "DST_CONNECTION_ID",
help_heading = "REQUIRED",
help = "Identifier of the destination connection"
)]
dst_conn_id: ConnectionId,

#[clap(
long = "dst-port",
required = true,
value_name = "DST_PORT_ID",
help_heading = "REQUIRED",
help = "Identifier of the destination port"
)]
dst_port_id: PortId,

#[clap(
long = "src-port",
required = true,
value_name = "SRC_PORT_ID",
help_heading = "REQUIRED",
help = "Identifier of the source port"
)]
src_port_id: PortId,

#[clap(
long = "src-channel",
visible_alias = "src-chan",
required = true,
value_name = "SRC_CHANNEL_ID",
help_heading = "REQUIRED",
help = "Identifier of the source channel (required)"
)]
src_chan_id: ChannelId,

#[clap(
long = "dst-channel",
visible_alias = "dst-chan",
required = true,
help_heading = "REQUIRED",
value_name = "DST_CHANNEL_ID",
help = "Identifier of the destination channel (optional)"
)]
dst_chan_id: Option<ChannelId>,
}

impl Runnable for TxChanUpgradeCancelCmd {
fn run(&self) {
let config = app_config();

let chains = match ChainHandlePair::spawn(&config, &self.src_chain_id, &self.dst_chain_id) {
Ok(chains) => chains,
Err(e) => Output::error(format!("{}", e)).exit(),
};

// Retrieve the connection
let dst_connection = match chains.dst.query_connection(
QueryConnectionRequest {
connection_id: self.dst_conn_id.clone(),
height: QueryHeight::Latest,
},
IncludeProof::No,
) {
Ok((connection, _)) => connection,
Err(e) => Output::error(format!("{}", e)).exit(),
};

// Fetch the Channel that will facilitate the communication between the channel ends
// being upgraded. This channel is assumed to already exist on the destination chain.
let channel = Channel {
connection_delay: Default::default(),
ordering: Ordering::default(),
a_side: ChannelSide::new(
chains.src,
ClientId::default(),
ConnectionId::default(),
self.src_port_id.clone(),
Some(self.src_chan_id.clone()),
None,
),
b_side: ChannelSide::new(
chains.dst,
dst_connection.client_id().clone(),
self.dst_conn_id.clone(),
self.dst_port_id.clone(),
self.dst_chan_id.clone(),
None,
),
};

info!("message ChanUpgradeCancel: {}", channel);

let res: Result<IbcEvent, Error> = channel
.build_chan_upgrade_cancel_and_send()
.map_err(Error::channel);

match res {
Ok(receipt) => Output::success(receipt).exit(),
Err(e) => Output::error(e).exit(),
}
}
}

#[cfg(test)]
mod tests {
use abscissa_core::clap::Parser;
Expand Down
3 changes: 3 additions & 0 deletions crates/relayer-types/src/core/ics04_channel/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ define_error! {
MissingUpgradeFields
| _ | { "missing upgrade fields" },

MissingUpgradeErrorReceipt
| _ | { "missing upgrade error receipt" },

MissingProposedUpgradeChannel
| _ | { "missing proposed upgrade channel" },

Expand Down
102 changes: 102 additions & 0 deletions crates/relayer-types/src/core/ics04_channel/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,108 @@ impl EventType for UpgradeOpen {
}
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
pub struct UpgradeCancel {
pub port_id: PortId,
pub channel_id: ChannelId,
pub counterparty_port_id: PortId,
pub counterparty_channel_id: Option<ChannelId>,
pub upgrade_connection_hops: Vec<ConnectionId>,
pub upgrade_version: Version,
pub upgrade_sequence: Sequence,
pub upgrade_ordering: Ordering
}

impl Display for UpgradeCancel {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
if let Some(counterparty_channel_id) = &self.counterparty_channel_id {
write!(f, "UpgradeAttributes {{ port_id: {}, channel_id: {}, counterparty_port_id: {}, counterparty_channel_id: {counterparty_channel_id}, upgrade_connection_hops: [", self.port_id, self.channel_id, self.counterparty_port_id)?;
} else {
write!(f, "UpgradeAttributes {{ port_id: {}, channel_id: {}, counterparty_port_id: {}, counterparty_channel_id: None, upgrade_connection_hops: [", self.port_id, self.channel_id, self.counterparty_port_id)?;
}
for hop in self.upgrade_connection_hops.iter() {
write!(f, " {} ", hop)?;
}
write!(
f,
"], upgrade_version: {}, upgrade_sequence: {}, upgrade_ordering: {} }}",
self.upgrade_version, self.upgrade_sequence, self.upgrade_ordering
)
}
}

impl From<UpgradeCancel> for UpgradeAttributes {
fn from(ev: UpgradeCancel) -> Self {
Self {
port_id: ev.port_id,
channel_id: ev.channel_id,
counterparty_port_id: ev.counterparty_port_id,
counterparty_channel_id: ev.counterparty_channel_id,
upgrade_connection_hops: ev.upgrade_connection_hops,
upgrade_version: ev.upgrade_version,
upgrade_sequence: ev.upgrade_sequence,
upgrade_ordering: ev.upgrade_ordering,
}
}
}

impl From<UpgradeCancel> for abci::Event {
fn from(value: UpgradeCancel) -> Self {
let kind = UpgradeCancel::event_type().as_str().to_owned();
Self {
kind,
attributes: UpgradeAttributes::from(value).into(),
}
}
}

impl UpgradeCancel {
pub fn channel_id(&self) -> &ChannelId {
&self.channel_id
}

pub fn port_id(&self) -> &PortId {
&self.port_id
}

pub fn counterparty_port_id(&self) -> &PortId {
&self.counterparty_port_id
}

pub fn counterparty_channel_id(&self) -> Option<&ChannelId> {
self.counterparty_channel_id.as_ref()
}
}

impl TryFrom<UpgradeAttributes> for UpgradeCancel {
type Error = EventError;

fn try_from(attrs: UpgradeAttributes) -> Result<Self, Self::Error> {
Ok(Self {
port_id: attrs.port_id,
channel_id: attrs.channel_id,
counterparty_port_id: attrs.counterparty_port_id,
counterparty_channel_id: attrs.counterparty_channel_id,
upgrade_connection_hops: attrs.upgrade_connection_hops,
upgrade_version: attrs.upgrade_version,
upgrade_sequence: attrs.upgrade_sequence,
upgrade_ordering: attrs.upgrade_ordering,
})
}
}

impl From<UpgradeCancel> for IbcEvent {
fn from(v: UpgradeCancel) -> Self {
IbcEvent::UpgradeCancelChannel(v)
}
}

impl EventType for UpgradeCancel {
fn event_type() -> IbcEventType {
IbcEventType::UpgradeCancelChannel
}
}

macro_rules! impl_try_from_attribute_for_event {
($($event:ty),+) => {
$(impl TryFrom<Attributes> for $event {
Expand Down
1 change: 1 addition & 0 deletions crates/relayer-types/src/core/ics04_channel/msgs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub mod chan_upgrade_confirm;
pub mod chan_upgrade_init;
pub mod chan_upgrade_open;
pub mod chan_upgrade_try;
pub mod chan_upgrade_cancel;

// Packet specific messages.
pub mod acknowledgement;
Expand Down
Loading

0 comments on commit 76d88e0

Please sign in to comment.