diff --git a/.changelog/unreleased/features/1287-upgrade-legacy.md b/.changelog/unreleased/features/1287-upgrade-legacy.md new file mode 100644 index 0000000000..2ff89373cf --- /dev/null +++ b/.changelog/unreleased/features/1287-upgrade-legacy.md @@ -0,0 +1,3 @@ +- Add `--legacy | -l` flag to support upgrades for chains built with Cosmos SDK < v0.43.0 ([#1287]) + +[#1287]: https://github.com/informalsystems/ibc-rs/issues/1287 diff --git a/relayer-cli/src/commands/tx/upgrade.rs b/relayer-cli/src/commands/tx/upgrade.rs index 8242bf5bfe..71331dfcd2 100644 --- a/relayer-cli/src/commands/tx/upgrade.rs +++ b/relayer-cli/src/commands/tx/upgrade.rs @@ -61,6 +61,12 @@ pub struct TxIbcUpgradeChainCmd { help = "a string to name the upgrade proposal plan (default: 'plan')" )] upgrade_name: Option, + + #[options( + help = "use legacy upgrade proposal constructs (for chains built with Cosmos SDK < v0.43.0)", + short = "l" + )] + legacy: bool, } impl TxIbcUpgradeChainCmd { @@ -88,6 +94,7 @@ impl TxIbcUpgradeChainCmd { .upgrade_name .clone() .unwrap_or_else(|| "plan".to_string()), + legacy: self.legacy, }; Ok(opts) diff --git a/relayer/src/upgrade_chain.rs b/relayer/src/upgrade_chain.rs index 53f6df26e3..57f97b9325 100644 --- a/relayer/src/upgrade_chain.rs +++ b/relayer/src/upgrade_chain.rs @@ -1,7 +1,9 @@ //! Chain upgrade plans for triggering IBC-breaking upgrades. +#![allow(deprecated)] // TODO(hu55a1n1): remove this when we don't need legacy upgrade support use std::time::Duration; +use bytes::BufMut; use flex_error::define_error; use prost_types::Any; @@ -10,7 +12,7 @@ use ibc::ics02_client::height::Height; use ibc::ics24_host::identifier::{ChainId, ClientId}; use ibc::{events::IbcEvent, ics07_tendermint::client_state::ClientState}; use ibc_proto::cosmos::gov::v1beta1::MsgSubmitProposal; -use ibc_proto::cosmos::upgrade::v1beta1::Plan; +use ibc_proto::cosmos::upgrade::v1beta1::{Plan, SoftwareUpgradeProposal}; use ibc_proto::ibc::core::client::v1::UpgradeProposal; use crate::chain::{ChainEndpoint, CosmosSdkChain}; @@ -55,6 +57,7 @@ pub struct UpgradePlanOptions { pub upgraded_chain_id: ChainId, pub upgraded_unbonding_period: Option, pub upgrade_plan_name: String, + pub legacy: bool, } pub fn build_and_send_ibc_upgrade_proposal( @@ -94,11 +97,16 @@ pub fn build_and_send_ibc_upgrade_proposal( }), }; - let mut buf_proposal = Vec::new(); - prost::Message::encode(&proposal, &mut buf_proposal).unwrap(); + let proposal = if opts.legacy { + Proposal::Legacy(proposal.into()) + } else { + Proposal::Default(proposal) + }; + let mut buf_proposal = Vec::new(); + proposal.encode(&mut buf_proposal); let any_proposal = Any { - type_url: "/ibc.core.client.v1.UpgradeProposal".to_string(), + type_url: proposal.type_url(), value: buf_proposal, }; @@ -138,3 +146,51 @@ pub fn build_and_send_ibc_upgrade_proposal( Some(reason) => Err(UpgradeChainError::tx_response(reason)), } } + +enum Proposal { + Default(UpgradeProposal), + Legacy(LegacyProposal), +} + +impl Proposal { + fn encode(&self, buf: &mut impl BufMut) { + match self { + Proposal::Default(p) => prost::Message::encode(p, buf), + Proposal::Legacy(p) => prost::Message::encode(&p.0, buf), + } + .unwrap() + } + + fn type_url(&self) -> String { + match self { + Proposal::Default(_) => "/ibc.core.client.v1.UpgradeProposal", + Proposal::Legacy(_) => "/cosmos.upgrade.v1beta1.SoftwareUpgradeProposal", + } + .to_owned() + } +} + +struct LegacyProposal(SoftwareUpgradeProposal); + +impl From for LegacyProposal { + fn from(v: UpgradeProposal) -> Self { + let plan = { + if let Some(plan) = v.plan { + Some(Plan { + name: plan.name, + height: plan.height, + info: plan.info, + time: None, + upgraded_client_state: v.upgraded_client_state, + }) + } else { + None + } + }; + Self(SoftwareUpgradeProposal { + title: v.title, + description: v.description, + plan, + }) + } +}