Skip to content

Commit

Permalink
Hermes CLI for upgrading client (informalsystems#723)
Browse files Browse the repository at this point in the history
* Added domain type def.

Also cleaned-up the documentation, which looked very sloppy.
https://docs.rs/ibc/0.1.1/ibc/ics02_client/msgs/index.html

* Added partial handler & command

* Added upgrade proto files. Added Cargo.lock for proto-compiler

* Prep for query_upgraded_client_state

* Method & support for querying ugpraded client state

* Support for querying the upgraded consensus state

* Minor dev scripts enhancements & bugs

* Added guide. Uses patched Go relayer

* Proto conversion for upgrade msg. Refactored upgrade() impl

* Fix missing signer bug

* Update msg bf. upgrade. Event parsing

* Changelog. Revised guide

* Aesthetic nits based on file review

* Clarifications in the test instructions

* Documented Go relayer version in testing instructions

* Possible fix for informalsystems#734

* changelog & method documentation

* Apply suggestions from code review

Co-authored-by: Romain Ruetschi <romain@informal.systems>

* Added more derived trait bounds on module events

* Adapt to newer Ics02 structure.

* Added Protobuf impl for MsgUpgradeAnyClient

* FMT

* Added upgrade-chain CLI and updated instructions

* Remove a clone and turn zero_custom_fields into a static method

* Whitespace and nitpick

* Remove obsolete TODO

Co-authored-by: Romain Ruetschi <romain@informal.systems>
Co-authored-by: Anca Zamfir <zamfiranca@gmail.com>
  • Loading branch information
3 people authored Mar 23, 2021
1 parent 2f0d1d0 commit 8247868
Show file tree
Hide file tree
Showing 19 changed files with 801 additions and 11 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
- [ibc-relayer-cli]
- Added `create connection` CLI ([#630])
- Proposed ADR 006 to describe Hermes v0.2.0 use-cases ([#637])
- Added `client-upgrade` CLI ([#357])
- Update gaia to version 4.1.0 for e2e tests on CI ([#702])

### IMPROVEMENTS
Expand All @@ -33,7 +34,7 @@
- [nothing yet]

- [ibc-relayer-cli]
- [nothing yet]
- Clarified success path for updating a client that is already up-to-date ([#734])

### BUG FIXES

Expand Down Expand Up @@ -61,6 +62,7 @@
- [nothing yet]

[#352]: https://github.com/informalsystems/ibc-rs/issues/352
[#357]: https://github.com/informalsystems/ibc-rs/issues/357
[#416]: https://github.com/informalsystems/ibc-rs/issues/416
[#561]: https://github.com/informalsystems/ibc-rs/issues/561
[#599]: https://github.com/informalsystems/ibc-rs/issues/599
Expand All @@ -72,6 +74,7 @@
[#699]: https://github.com/informalsystems/ibc-rs/issues/699
[#700]: https://github.com/informalsystems/ibc-rs/pull/700
[#702]: https://github.com/informalsystems/ibc-rs/issues/702
[#734]: https://github.com/informalsystems/ibc-rs/issues/734
[#736]: https://github.com/informalsystems/ibc-rs/issues/736
[#740]: https://github.com/informalsystems/ibc-rs/issues/740
[#752]: https://github.com/informalsystems/ibc-rs/issues/752
Expand Down
166 changes: 166 additions & 0 deletions guide/src/upgrade_test.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
## Prerequisites

- gaiad `(v4.1.*)`, for example:

```shell
$ gaiad version --long | head -n4
name: gaia
server_name: gaiad
version: 4.1.2
commit: 95b07e641d1f69ee12dd911e92b1679f2c64d385
```

## Testing procedure

1. Start two gaia instances and initialize hermes:

```shell
$ ./scripts/dev-env ~/.hermes/config.toml ibc-0 ibc-1
```
The `one-chain` script is invoked for each chain and modifies the `genesis.json` file to use a short window for governance proposals (`200s` for `max_deposit_period` and `voting_period`). Therefore, an upgrade proposal can be submitted, voted on and accepted within a short time.

2. Create one client on `ibc-1` for `ibc-0`:

```shell
$ hermes tx raw create-client ibc-1 ibc-0
```

3. Create and submit an upgrade plan for chain `ibc-0`:

Use the hermes test command to make an upgrade proposal. In the example below a software upgrade proposal is made for `ibc-0`, for the height `300` blocks from latest height. `10000000stake` is deposited.
The proposal includes the upgraded client state constructed from the state of `07-tendermint-0` client on `ibc-1` that was created in the previous step. In addition, the `unbonding_period` of the client is set to some new value (`400h`)

```shell
$ hermes tx raw upgrade-chain ibc-0 ibc-1 07-tendermint-0 10000000 300
```

Note that the height offset should be picked such that the proposal plan height is reached after the `200s` voting period.

4. Verify that the proposal was accepted:

Query the upgrade plan to check that it was submitted correctly. Note the `height` at which the proposal will take effect (chain halts). Also `status: PROPOSAL_STATUS_VOTING_PERIOD`.

```shell
$ gaiad query gov proposal 1 --home data/ibc-0/
content:
'@type': /cosmos.upgrade.v1beta1.SoftwareUpgradeProposal
description: upgrade the chain software and unbonding period
plan:
height: "382"
info: upgrade the chain software and unbonding period
name: test
time: "0001-01-01T00:00:00Z"
upgraded_client_state:
'@type': /ibc.lightclients.tendermint.v1.ClientState
allow_update_after_expiry: false
allow_update_after_misbehaviour: false
chain_id: ibc-0
frozen_height:
revision_height: "0"
revision_number: "0"
latest_height:
revision_height: "383"
revision_number: "0"
max_clock_drift: 0s
proof_specs:
...
trust_level:
denominator: "0"
numerator: "0"
trusting_period: 0s
unbonding_period: 1440000s
upgrade_path:
- upgrade
- upgradedIBCState
title: upgrade_ibc_clients
deposit_end_time: "2021-03-23T17:25:42.543572Z"
final_tally_result:
abstain: "0"
"no": "0"
no_with_veto: "0"
"yes": "0"
proposal_id: "1"
status: PROPOSAL_STATUS_VOTING_PERIOD
submit_time: "2021-03-23T17:22:22.543572Z"
total_deposit:
- amount: "10000000"
denom: stake
voting_end_time: "2021-03-23T17:25:42.543572Z"
voting_start_time: "2021-03-23T17:22:22.543572Z"
```

5. Vote on the proposal

The parameter `1` should match the `proposal_id:` from the upgrade proposal submitted at step 3. This command must be issued while the proposal status is `PROPOSAL_STATUS_VOTING_PERIOD`.

```shell
gaiad tx gov vote 1 yes --home data/ibc-0/data/ --keyring-backend test --keyring-dir data/ibc-0/ --chain-id ibc-0 --from validator
```

Wait approximately 200 seconds until the proposal changes status to `PROPOSAL_STATUS_PASSED`. Note the `final tally_result` that includes the vote submitted in previous step.

```shell
$ gaiad query gov proposal 1 --home data/ibc-0/
content:
'@type': /cosmos.upgrade.v1beta1.SoftwareUpgradeProposal
description: upgrade the chain software and unbonding period
plan:
...
final_tally_result:
abstain: "0"
"no": "0"
no_with_veto: "0"
"yes": "100000000000"
proposal_id: "1"
status: PROPOSAL_STATUS_PASSED
submit_time: "2021-03-23T17:22:22.543572Z"
total_deposit:
- amount: "10000000"
denom: stake
voting_end_time: "2021-03-23T17:25:42.543572Z"
voting_start_time: "2021-03-23T17:22:22.543572Z"
```

6. Test the `upgrade-client` CLI

The following command performs the upgrade for client `07-tendermint-0`. It outputs two events, one for the updated client state, and another for the upgraded state.

```shell
$ hermes tx raw upgrade-client ibc-1 ibc-0 07-tendermint-0
{
"status": "success",
"result": [
{
"UpdateClient": {
"client_id": "07-tendermint-0",
"client_type": "Tendermint",
"consensus_height": {
"revision_height": 332,
"revision_number": 0
},
"height": {
"revision_height": 404,
"revision_number": 1
}
}
},
{
"UpgradeClient": {
"client_id": "07-tendermint-0",
"client_type": "Tendermint",
"consensus_height": {
"revision_height": 333,
"revision_number": 0
},
"height": {
"revision_height": 404,
"revision_number": 1
}
}
}
]
}
```
11 changes: 10 additions & 1 deletion relayer-cli/src/commands/tx.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
//! `tx` subcommand
use abscissa_core::{Command, Help, Options, Runnable};

use crate::commands::tx::client::{TxCreateClientCmd, TxUpdateClientCmd};
use crate::commands::tx::client::{TxCreateClientCmd, TxUpdateClientCmd, TxUpgradeClientCmd};

mod channel;
mod client;
mod connection;
mod packet;
mod transfer;
mod upgrade;

/// `tx` subcommand
#[derive(Command, Debug, Options, Runnable)]
Expand Down Expand Up @@ -35,6 +36,10 @@ pub enum TxRawCommands {
#[options(help = "Update the specified client on destination chain")]
UpdateClient(TxUpdateClientCmd),

/// The `tx raw upgrade-client` subcommand. Submits a MsgUpgradeClient in a transaction to a chain.
#[options(help = "Upgrade the specified client on destination chain")]
UpgradeClient(TxUpgradeClientCmd),

/// The `tx raw conn-init` subcommand
#[options(help = "Initialize a connection (ConnectionOpenInit)")]
ConnInit(connection::TxRawConnInitCmd),
Expand Down Expand Up @@ -86,4 +91,8 @@ pub enum TxRawCommands {
/// The `tx raw packet-ack` subcommand
#[options(help = "Relay acknowledgment packets")]
PacketAck(packet::TxRawPacketAckCmd),

/// The `tx raw upgrade-chain` subcommand
#[options(help = "Send an upgrade plan")]
UpgradeChain(upgrade::TxUpgradeChainCmd),
}
52 changes: 51 additions & 1 deletion relayer-cli/src/commands/tx/client.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use abscissa_core::{Command, Options, Runnable};
use tracing::info;

use ibc::events::IbcEvent;
use ibc::ics24_host::identifier::{ChainId, ClientId};
Expand All @@ -7,7 +8,7 @@ use ibc_relayer::foreign_client::ForeignClient;

use crate::application::app_config;
use crate::commands::cli_utils::{ChainHandlePair, SpawnOptions};
use crate::conclude::Output;
use crate::conclude::{exit_with_unrecoverable_error, Output};
use crate::error::{Error, Kind};

#[derive(Clone, Command, Debug, Options)]
Expand Down Expand Up @@ -101,3 +102,52 @@ impl Runnable for TxUpdateClientCmd {
}
}
}

#[derive(Clone, Command, Debug, Options)]
pub struct TxUpgradeClientCmd {
#[options(free, required, help = "identifier of the destination chain")]
dst_chain_id: ChainId,

#[options(
free,
required,
help = "identifier of the chain which underwent upgrade (source chain)"
)]
src_chain_id: ChainId,

#[options(
free,
required,
help = "identifier of the client to be upgraded on destination chain"
)]
dst_client_id: ClientId,
}

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

let spawn_options = SpawnOptions::override_store_config(StoreConfig::memory());
let chains = ChainHandlePair::spawn_with(
spawn_options,
&config,
&self.src_chain_id,
&self.dst_chain_id,
)
.unwrap_or_else(exit_with_unrecoverable_error);

info!("Started the chain runtimes");

// Instantiate the client hosted on the destination chain, which is targeting headers for
// the source chain.
let client = ForeignClient::find(chains.src, chains.dst, &self.dst_client_id)
.unwrap_or_else(exit_with_unrecoverable_error);

let outcome = client.upgrade();

match outcome {
Ok(receipt) => Output::success(receipt).exit(),
Err(e) => Output::error(format!("{}", e)).exit(),
}
}
}
Loading

0 comments on commit 8247868

Please sign in to comment.