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

Hermes CLI for upgrading client #723

Merged
merged 33 commits into from
Mar 23, 2021
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
12722c0
Added domain type def.
adizere Feb 26, 2021
98736d4
Merge branch 'master' into adi/357_upgrade
adizere Mar 1, 2021
b04e43a
Merge branch 'master' into adi/357_upgrade
adizere Mar 2, 2021
cf1dda7
Added partial handler & command
adizere Mar 3, 2021
a2942de
Added upgrade proto files. Added Cargo.lock for proto-compiler
adizere Mar 3, 2021
172a620
Prep for query_upgraded_client_state
adizere Mar 3, 2021
85f4fee
Method & support for querying ugpraded client state
adizere Mar 4, 2021
83b7ff5
Support for querying the upgraded consensus state
adizere Mar 4, 2021
861a4ff
Minor dev scripts enhancements & bugs
adizere Mar 5, 2021
bacf749
Merge branch 'master' into adi/357_upgrade
adizere Mar 5, 2021
1948fa4
Added guide. Uses patched Go relayer
adizere Mar 8, 2021
b41560d
Proto conversion for upgrade msg. Refactored upgrade() impl
adizere Mar 8, 2021
bb99800
Fix missing signer bug
adizere Mar 9, 2021
8825acc
Update msg bf. upgrade. Event parsing
adizere Mar 9, 2021
892ac8f
Changelog. Revised guide
adizere Mar 9, 2021
3ca422a
Merge branch 'master' into adi/357_upgrade
adizere Mar 9, 2021
942bfff
Aesthetic nits based on file review
adizere Mar 9, 2021
6ba2e0d
Clarifications in the test instructions
adizere Mar 9, 2021
c59224f
Documented Go relayer version in testing instructions
adizere Mar 10, 2021
466f281
Possible fix for #734
adizere Mar 11, 2021
e02d508
changelog & method documentation
adizere Mar 11, 2021
92ff9fd
Merge branch 'master' into adi/357_upgrade
adizere Mar 11, 2021
6f3b09a
Apply suggestions from code review
adizere Mar 15, 2021
d2fae93
Added more derived trait bounds on module events
adizere Mar 15, 2021
bd3727b
Merge branch 'master' into adi/357_upgrade
adizere Mar 15, 2021
5fc61f7
Adapt to newer Ics02 structure.
adizere Mar 15, 2021
7769162
Added Protobuf impl for MsgUpgradeAnyClient
adizere Mar 15, 2021
959f8dd
FMT
adizere Mar 15, 2021
42b326a
Added upgrade-chain CLI and updated instructions
ancazamfir Mar 23, 2021
1e911c0
Merge branch 'master' into adi/357_upgrade
ancazamfir Mar 23, 2021
d3827ec
Remove a clone and turn zero_custom_fields into a static method
romac Mar 23, 2021
5f751b0
Whitespace and nitpick
romac Mar 23, 2021
4187c40
Remove obsolete TODO
romac Mar 23, 2021
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
2 changes: 2 additions & 0 deletions 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])

### IMPROVEMENTS

Expand Down Expand Up @@ -56,6 +57,7 @@
- [nothing yet]

[#352]: https://github.com/informalsystems/ibc-rs/issues/352
[#357]: https://github.com/informalsystems/ibc-rs/issues/357
[#561]: https://github.com/informalsystems/ibc-rs/issues/561
[#599]: https://github.com/informalsystems/ibc-rs/issues/599
[#630]: https://github.com/informalsystems/ibc-rs/issues/630
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
```
$ gaiad version --long | head -n4
name: gaia
server_name: gaiad
version: 4.0.0
commit: a279d091c6f66f8a91c87943139ebaecdd84f689
```

- Go relayer

## Testing procedure

1. Patch the `one-chain` script of the Go relayer.

```shell
cd ~/go/src/github.com/cosmos/relayer/
```

This pathing step is necessary to short-circuit the upgrading of a chain.
With the changes below, a chain will be able to undergo an upgrade within
~200 seconds of the upgrade proposal (instead of the default of 2 days).
With this patch, we can test the upgrade functionality in a matter of minutes.

```diff
diff --git a/scripts/one-chain b/scripts/one-chain
index d0995fe..3702a88 100755
--- a/scripts/one-chain
+++ b/scripts/one-chain
@@ -99,6 +99,7 @@ if [ $platform = 'linux' ]; then
sed -i 's/index_all_keys = false/index_all_keys = true/g' $CHAINDIR/$CHAINID/config/config.toml
# sed -i '' 's#index-events = \[\]#index-events = \["message.action","send_packet.packet_src_channel","send_packet.packet_sequence"\]#g' $CHAINDIR/$CHAINID/config/app.toml
else
+ sed -i '' 's#"172800s"#"200s"#g' $CHAINDIR/$CHAINID/config/genesis.json
sed -i '' 's#"tcp://127.0.0.1:26657"#"tcp://0.0.0.0:'"$RPCPORT"'"#g' $CHAINDIR/$CHAINID/config/config.toml
sed -i '' 's#"tcp://0.0.0.0:26656"#"tcp://0.0.0.0:'"$P2PPORT"'"#g' $CHAINDIR/$CHAINID/config/config.toml
sed -i '' 's#"localhost:6060"#"localhost:'"$P2PPORT"'"#g' $CHAINDIR/$CHAINID/config/config.toml
```

2. Start two gaia instances using the patched developer environment:

```shell
./scripts/two-chainz
```

3. Setup the Go relayer for these chains:
```shell
$ rly tx link demo -d -o 3s
```

Check that everything went fine so far:

```shell
$ rly paths list
0: demo -> chns(✔) clnts(✔) conn(✔) chan(✔) (ibc-0:transfer<>ibc-1:transfer)
```

4. Create the upgrade plan for chain ibc-0:

It's important that we parametrize the upgrade plan with a height parameter that
is at least 300 heights ahead of the current height of chain ibc-0.

First, obtain the current height:
```shell
gaiad query block | jq | grep height
"height": "470",
```

Now create the upgrade plan for height 800:
```shell
echo '{
"Name": "test",
"Height": 800,
"Info": ""
}' > ./upgrade-plan.json
```


5. Submit the upgrade plan

```shell
rly tx upgrade-chain demo ibc-0 400h 10000000stake ./upgrade-plan.json
```

Query for the upgrade plan, check that it was submitted correctly:

```shell
$ gaiad query gov proposal 1 --home data/ibc-0/

content:
'@type': /cosmos.upgrade.v1beta1.SoftwareUpgradeProposal
description: upgrade the chain's software and unbonding period
plan:
height: "800"
info: ""
name: test
....
proposal_id: "1"
status: PROPOSAL_STATUS_VOTING_PERIOD
submit_time: "2021-03-08T13:07:01.417163Z"
total_deposit:
- amount: "10000000"
denom: stake
voting_end_time: "2021-03-08T13:10:21.417163Z"
voting_start_time: "2021-03-08T13:07:01.417163Z"
```

6. Vote on the proposal

The parameter "1" should match the "proposal_id:" from the upgrade proposal
we submitted at step 5.

```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
```

Once ibc-0 reaches height 800, it should stop executing.


7. Initialize and test Hermes

```shell
cd ~/rust/ibc-rs
```


Patch the developer env of Hermes, to redirect to the correct Gaia directory:
```diff
diff --git a/scripts/init-clients b/scripts/init-clients
index 6cf1a674..bfff9721 100755
--- a/scripts/init-clients
+++ b/scripts/init-clients
@@ -49,7 +49,7 @@ if ! grep -q -s "$CHAIN_1_ID" "$CONFIG_FILE"; then
usage
fi

-GAIA_DATA="$(pwd)/data"
+GAIA_DATA="~/go/src/github.com/cosmos/relayer/data"

CHAIN_0_RPC_PORT=26657
CHAIN_0_RPC_ADDR="localhost:$CHAIN_0_RPC_PORT"
```

No setup the clients for Hermes to use:
adizere marked this conversation as resolved.
Show resolved Hide resolved

```shell
$ ./scripts/init-clients ~/.hermes/config.toml ibc-0 ibc-1
Building the Rust relayer...
Removing light client peers from configuration...
Adding primary peers to light client configuration...
Adding secondary peers to light client configuration...
Importing keys...
Done!
```

8. Test the `upgrade-client` CLI

The following command will perform the upgrade for client `07-tendermint-0`. It
will output 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
```
2 changes: 2 additions & 0 deletions modules/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pub enum IbcEvent {

CreateClient(ClientEvents::CreateClient),
UpdateClient(ClientEvents::UpdateClient),
UpgradeClient(ClientEvents::UpgradeClient),
ClientMisbehavior(ClientEvents::ClientMisbehavior),

OpenInitConnection(ConnectionEvents::OpenInit),
Expand Down Expand Up @@ -111,6 +112,7 @@ impl IbcEvent {
IbcEvent::NewBlock(ev) => ev.set_height(height),
IbcEvent::CreateClient(ev) => ev.set_height(height),
IbcEvent::UpdateClient(ev) => ev.set_height(height),
IbcEvent::UpgradeClient(ev) => ev.set_height(height),
IbcEvent::ClientMisbehavior(ev) => ev.set_height(height),
IbcEvent::OpenInitConnection(ev) => ev.set_height(height),
IbcEvent::OpenTryConnection(ev) => ev.set_height(height),
Expand Down
2 changes: 2 additions & 0 deletions modules/src/ics02_client/client_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,8 @@ impl ClientDef for AnyClient {
}
}
}

// TODO: Add upgrade method here
}

#[cfg(test)]
Expand Down
5 changes: 4 additions & 1 deletion modules/src/ics02_client/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use crate::ics02_client::client_def::{AnyClientState, AnyConsensusState};
use crate::ics02_client::client_type::ClientType;
use crate::ics02_client::error::Error;
use crate::ics02_client::handler::ClientResult::{self, Create, Update};
use crate::ics02_client::handler::ClientResult::{self, Create, Update, Upgrade};
use crate::ics24_host::identifier::ClientId;
use crate::Height;

Expand Down Expand Up @@ -46,6 +46,9 @@ pub trait ClientKeeper {
)?;
Ok(())
}
Upgrade(_) => {
unimplemented!()
}
}
}

Expand Down
3 changes: 3 additions & 0 deletions modules/src/ics02_client/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ pub enum Kind {
#[error("client not found: {0}")]
ClientNotFound(ClientId),

#[error("client is frozen: {0}")]
ClientFrozen(ClientId),

#[error("consensus state not found at: {0} at height {1}")]
ConsensusStateNotFound(ClientId, Height),

Expand Down
20 changes: 20 additions & 0 deletions modules/src/ics02_client/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use std::convert::{TryFrom, TryInto};
/// The content of the `type` field for the event that a chain produces upon executing the create client transaction.
const CREATE_EVENT_TYPE: &str = "create_client";
const UPDATE_EVENT_TYPE: &str = "update_client";
const UPGRADE_EVENT_TYPE: &str = "upgrade_client";

/// The content of the `key` field for the attribute containing the client identifier.
const CLIENT_ID_ATTRIBUTE_KEY: &str = "client_id";
Expand All @@ -30,6 +31,9 @@ pub fn try_from_tx(event: &tendermint::abci::Event) -> Option<IbcEvent> {
UPDATE_EVENT_TYPE => Some(IbcEvent::UpdateClient(UpdateClient(
extract_attributes_from_tx(event),
))),
UPGRADE_EVENT_TYPE => Some(IbcEvent::UpgradeClient(UpgradeClient(
extract_attributes_from_tx(event),
))),
_ => None,
}
}
Expand Down Expand Up @@ -214,3 +218,19 @@ impl From<ClientMisbehavior> for IbcEvent {
IbcEvent::ClientMisbehavior(v)
}
}

/// Signals a recent upgrade of an on-chain client (IBC Client).
#[derive(Debug, Deserialize, Serialize, Clone)]
adizere marked this conversation as resolved.
Show resolved Hide resolved
pub struct UpgradeClient(Attributes);

impl UpgradeClient {
pub fn set_height(&mut self, height: Height) {
adizere marked this conversation as resolved.
Show resolved Hide resolved
self.0.height = height;
}
}

impl From<Attributes> for UpgradeClient {
fn from(attrs: Attributes) -> Self {
UpgradeClient(attrs)
}
}
3 changes: 3 additions & 0 deletions modules/src/ics02_client/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ use crate::ics02_client::msgs::ClientMsg;

pub mod create_client;
pub mod update_client;
pub mod upgrade_client;

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ClientResult {
Create(create_client::Result),
Update(update_client::Result),
Upgrade(upgrade_client::Result),
}

/// General entry point for processing any message related to ICS2 (client functions) protocols.
Expand All @@ -22,5 +24,6 @@ where
match msg {
ClientMsg::CreateClient(msg) => create_client::process(ctx, msg),
ClientMsg::UpdateClient(msg) => update_client::process(ctx, msg),
ClientMsg::UpgradeClient(msg) => upgrade_client::process(ctx, msg),
}
}
4 changes: 2 additions & 2 deletions modules/src/ics02_client/handler/update_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ mod tests {
use crate::ics02_client::client_def::AnyClientState;
use crate::ics02_client::error::Kind;
use crate::ics02_client::handler::dispatch;
use crate::ics02_client::handler::ClientResult::{Create, Update};
use crate::ics02_client::handler::ClientResult::Update;
use crate::ics02_client::header::Header;
use crate::ics02_client::msgs::update_client::MsgUpdateAnyClient;
use crate::ics02_client::msgs::ClientMsg;
Expand Down Expand Up @@ -126,7 +126,7 @@ mod tests {
)))
)
}
Create(_) => panic!("update handler result has type CreateResult"),
_ => panic!("update handler result has incorrect type"),
}
}
Err(err) => {
Expand Down
52 changes: 52 additions & 0 deletions modules/src/ics02_client/handler/upgrade_client.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//! Protocol logic specific to processing ICS2 messages of type `MsgUpgradeAnyClient`.
//!
use crate::handler::HandlerResult;
use crate::ics02_client::client_def::{AnyClientState, AnyConsensusState};
use crate::ics02_client::context::ClientReader;
use crate::ics02_client::error::{Error, Kind};
use crate::ics02_client::handler::ClientResult;
use crate::ics02_client::msgs::upgrade_client::MsgUpgradeAnyClient;
use crate::ics02_client::state::ClientState;
use crate::ics24_host::identifier::ClientId;

/// The result following the successful processing of a `MsgUpgradeAnyClient` message.
/// This data type should be used with a qualified name `upgrade_client::Result` to avoid ambiguity.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Result {
pub client_id: ClientId,
pub client_state: AnyClientState,
pub consensus_state: AnyConsensusState,
}

pub fn process(
ctx: &dyn ClientReader,
msg: MsgUpgradeAnyClient,
) -> HandlerResult<ClientResult, Error> {
let MsgUpgradeAnyClient { client_id, .. } = msg;

// Read client state from the host chain store.
let client_state = ctx
.client_state(&client_id)
.ok_or_else(|| Kind::ClientNotFound(client_id.clone()))?;

if client_state.is_frozen() {
return Err(Kind::ClientFrozen(client_id).into());
}

// Not implemented yet: https://github.com/informalsystems/ibc-rs/issues/722
todo!()
adizere marked this conversation as resolved.
Show resolved Hide resolved

// let result = ClientResult::Upgrade(Result {
// client_id: client_id.clone(),
// client_state: new_client_state,
// consensus_state: new_consensus_state,
// });
//
// let event_attributes = Attributes {
// client_id,
// ..Default::default()
// };
// output.emit(IbcEvent::UpgradeClient(event_attributes.into()));
//
// Ok(output.with_result(result))
}
3 changes: 3 additions & 0 deletions modules/src/ics02_client/msgs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@

use crate::ics02_client::msgs::create_client::MsgCreateAnyClient;
use crate::ics02_client::msgs::update_client::MsgUpdateAnyClient;
use crate::ics02_client::msgs::upgrade_client::MsgUpgradeAnyClient;

pub mod create_client;
pub mod update_client;
pub mod upgrade_client;

#[allow(clippy::large_enum_variant)]
#[derive(Clone, Debug)]
pub enum ClientMsg {
CreateClient(MsgCreateAnyClient),
UpdateClient(MsgUpdateAnyClient),
UpgradeClient(MsgUpgradeAnyClient),
}
Loading