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

Add query channel client command to query a channel's client state #2248

Merged
merged 4 commits into from
May 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Added CLI command `query channel client` which outputs the channel's client state.
([#999](https://github.com/informalsystems/ibc-rs/issues/999))
229 changes: 229 additions & 0 deletions guide/src/commands/queries/channel.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ DESCRIPTION:
Query information about channels

SUBCOMMANDS:
client Query channel's client state
end Query channel end
ends Query channel ends and underlying connection and client objects
```
Expand Down Expand Up @@ -182,3 +183,231 @@ Success: ChannelEndsSummary {

Passing the `-v` flag will additionally print all the details of the
channel, connection, and client on both ends.

## Query the channel client state

Use the `query channel client` command to obtain the channel's client state:

```shell
USAGE:
hermes query channel client --port-id <PORT_ID> --channel-id <CHANNEL_ID> <CHAIN_ID>

DESCRIPTION:
Query channel's client state

ARGS:
<CHAIN_ID> identifier of the chain to query

FLAGS:
--channel-id <CHANNEL_ID> identifier of the channel to query
--port-id <PORT_ID> identifier of the port to query
```

If the command is successful a message with the following format will be displayed:
```
Success: Some(
IdentifiedAnyClientState {
client_id: ClientId(
"07-tendermint-0",
),
client_state: Tendermint(
ClientState {
chain_id: ChainId {
id: "network2",
version: 0,
},
trust_level: TrustThreshold {
numerator: 1,
denominator: 3,
},
trusting_period: 1209600s,
unbonding_period: 1814400s,
max_clock_drift: 40s,
latest_height: Height {
revision: 0,
height: 2775,
},
proof_specs: ProofSpecs(
[
ProofSpec(
ProofSpec {
leaf_spec: Some(
LeafOp {
hash: Sha256,
prehash_key: NoHash,
prehash_value: Sha256,
length: VarProto,
prefix: [
0,
],
},
),
inner_spec: Some(
InnerSpec {
child_order: [
0,
1,
],
child_size: 33,
min_prefix_length: 4,
max_prefix_length: 12,
empty_child: [],
hash: Sha256,
},
),
max_depth: 0,
min_depth: 0,
},
),
ProofSpec(
ProofSpec {
leaf_spec: Some(
LeafOp {
hash: Sha256,
prehash_key: NoHash,
prehash_value: Sha256,
length: VarProto,
prefix: [
0,
],
},
),
inner_spec: Some(
InnerSpec {
child_order: [
0,
1,
],
child_size: 32,
min_prefix_length: 1,
max_prefix_length: 1,
empty_child: [],
hash: Sha256,
},
),
max_depth: 0,
min_depth: 0,
},
),
],
),
upgrade_path: [
"upgrade",
"upgradedIBCState",
],
allow_update: AllowUpdate {
after_expiry: true,
after_misbehaviour: true,
},
frozen_height: None,
},
),
},
)
```

**JSON:**

```shell
hermes --json query channel client --port-id <PORT_ID> --channel-id <CHANNEL_ID> <CHAIN_ID>
```
or

```shell
hermes -j query channel client --port-id <PORT_ID> --channel-id <CHANNEL_ID> <CHAIN_ID>
```

If the command is successful a message with the following format will be displayed:

```json
{
"result":
{
"client_id":"07-tendermint-0",
"client_state":
{
"allow_update":
{
"after_expiry":true,
"after_misbehaviour":true
},
"chain_id":"network2",
"frozen_height":null,
"latest_height":
{
"revision_height":2775,
"revision_number":0
},
"max_clock_drift":
{
"nanos":0,
"secs":40
},
"proof_specs":
[
{
"inner_spec":
{
"child_order":[0,1],
"child_size":33,
"empty_child":"",
"hash":1,
"max_prefix_length":12,
"min_prefix_length":4
},
"leaf_spec":
{
"hash":1,
"length":1,
"prefix":"AA==",
"prehash_key":0,
"prehash_value":1
},
"max_depth":0,
"min_depth":0
},
{
"inner_spec":
{
"child_order":[0,1],
"child_size":32,
"empty_child":"",
"hash":1,
"max_prefix_length":1,
"min_prefix_length":1
},
"leaf_spec":
{
"hash":1,
"length":1,
"prefix":"AA==",
"prehash_key":0,
"prehash_value":1
},
"max_depth":0,
"min_depth":0
}
],
"trust_level":
{
"denominator":3,
"numerator":1
},
"trusting_period":
{
"nanos":0,
"secs":1209600
},
"type":"Tendermint",
"unbonding_period":
{
"nanos":0,
"secs":1814400
},
"upgrade_path":["upgrade","upgradedIBCState"]
},
"type":"IdentifiedAnyClientState"
},
"status":"success"
}
```
5 changes: 5 additions & 0 deletions relayer-cli/src/commands/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
use abscissa_core::clap::Parser;
use abscissa_core::{Command, Runnable};

use crate::commands::query::channel_client::QueryChannelClientCmd;
use crate::commands::query::channel_ends::QueryChannelEndsCmd;
use crate::commands::query::channels::QueryChannelsCmd;
use crate::commands::query::packet::QueryPacketCmds;

mod channel;
mod channel_client;
mod channel_ends;
mod channels;
mod client;
Expand Down Expand Up @@ -76,6 +78,9 @@ pub enum QueryConnectionCmds {

#[derive(Command, Debug, Parser, Runnable)]
pub enum QueryChannelCmds {
/// Query channel's client state
Client(QueryChannelClientCmd),

/// Query channel end
End(channel::QueryChannelEndCmd),

Expand Down
44 changes: 44 additions & 0 deletions relayer-cli/src/commands/query/channel_client.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use abscissa_core::clap::Parser;
use abscissa_core::{Command, Runnable};

use ibc::core::ics24_host::identifier::{ChainId, ChannelId, PortId};
use ibc_relayer::chain::handle::ChainHandle;
use ibc_relayer::chain::requests::QueryChannelClientStateRequest;

use crate::application::app_config;
use crate::cli_utils::spawn_chain_runtime;
use crate::conclude::{exit_with_unrecoverable_error, Output};

/// The data structure that represents the arguments when invoking the `query channel client` CLI command.
///
/// `query channel client --port-id <port_id> --channel-id <channel_id> <chain_id>`
///
/// If successful the channel's client state is displayed.
#[derive(Clone, Command, Debug, Parser)]
pub struct QueryChannelClientCmd {
#[clap(required = true, help = "identifier of the chain to query")]
chain_id: ChainId,

#[clap(required = true, long, help = "identifier of the port to query")]
port_id: PortId,

#[clap(required = true, long, help = "identifier of the channel to query")]
channel_id: ChannelId,
}

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

let chain = spawn_chain_runtime(&config, &self.chain_id)
.unwrap_or_else(exit_with_unrecoverable_error);

match chain.query_channel_client_state(QueryChannelClientStateRequest {
port_id: self.port_id.clone(),
channel_id: self.channel_id.clone(),
}) {
Ok(cs) => Output::success(cs).exit(),
Err(e) => Output::error(format!("{}", e)).exit(),
}
}
}