Skip to content

Commit

Permalink
Add support for multiple chain types in the configuration (#2228)
Browse files Browse the repository at this point in the history
* Move `ChainEndpoint` trait into its own module

* Add support for multiple chain types

* Add changelog entry

* Remove `type` entry from the default config

* Update relayer-cli/src/cli_utils.rs

Co-authored-by: Anca Zamfir <[email protected]>

* Ignore case and dashes when deserializing `ChainType`

* Fix test

Co-authored-by: Anca Zamfir <[email protected]>
  • Loading branch information
romac and ancazamfir authored Jun 6, 2022
1 parent 09c9f9f commit 08b7f98
Show file tree
Hide file tree
Showing 39 changed files with 693 additions and 727 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- Add preliminary support for multiple chain types, which can be specified in
the chain configuration. At the moment only the `CosmosSdk` chain type is
supported. ([#2240](https://github.com/informalsystems/ibc-rs/issues/2240))
21 changes: 7 additions & 14 deletions relayer-cli/src/cli_utils.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
use alloc::sync::Arc;

use tokio::runtime::Runtime as TokioRuntime;

use ibc::core::ics02_client::client_state::ClientState;
use ibc::core::ics24_host::identifier::{ChainId, ChannelId, PortId};
use ibc_relayer::chain::counterparty::{channel_connection_client, ChannelConnectionClient};

use ibc_relayer::{
chain::{
counterparty::{channel_connection_client, ChannelConnectionClient},
handle::{BaseChainHandle, ChainHandle},
runtime::ChainRuntime,
CosmosSdkChain,
},
config::Config,
spawn,
};

use crate::error::Error;
Expand Down Expand Up @@ -55,20 +56,12 @@ pub fn spawn_chain_runtime(config: &Config, chain_id: &ChainId) -> Result<impl C
spawn_chain_runtime_generic::<BaseChainHandle>(config, chain_id)
}

pub fn spawn_chain_runtime_generic<Chain: ChainHandle>(
pub fn spawn_chain_runtime_generic<Handle: ChainHandle>(
config: &Config,
chain_id: &ChainId,
) -> Result<Chain, Error> {
let chain_config = config
.find_chain(chain_id)
.cloned()
.ok_or_else(|| Error::missing_chain_config(chain_id.clone()))?;

) -> Result<Handle, Error> {
let rt = Arc::new(TokioRuntime::new().unwrap());
let handle =
ChainRuntime::<CosmosSdkChain>::spawn::<Chain>(chain_config, rt).map_err(Error::relayer)?;

Ok(handle)
spawn::spawn_chain_runtime(config, chain_id, rt).map_err(Error::spawn)
}

/// Spawns a chain runtime for specified chain identifier, queries the counterparty chain associated
Expand Down
23 changes: 7 additions & 16 deletions relayer-cli/src/commands/health.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use std::sync::Arc;

use abscissa_core::clap::Parser;
use abscissa_core::{Command, Runnable};
use tokio::runtime::Runtime as TokioRuntime;

use ibc_relayer::chain::{ChainEndpoint, CosmosSdkChain, HealthCheck::*};
use ibc_relayer::chain::endpoint::HealthCheck::*;
use ibc_relayer::chain::handle::ChainHandle;

use crate::cli_utils::spawn_chain_runtime;
use crate::conclude::{exit_with_unrecoverable_error, Output};
use crate::prelude::*;

Expand All @@ -16,22 +15,14 @@ impl Runnable for HealthCheckCmd {
fn run(&self) {
let config = (*app_config()).clone();

for ch in config.clone().chains {
let rt = Arc::new(TokioRuntime::new().unwrap());

let chain_config = match config.find_chain(&ch.id) {
None => Output::error(format!("chain '{}' not found in configuration file", ch.id))
.exit(),
Some(chain_config) => chain_config,
};

for ch in &config.chains {
info!("[{}] performing health check...", ch.id);

let chain = CosmosSdkChain::bootstrap(chain_config.clone(), rt)
.unwrap_or_else(exit_with_unrecoverable_error);
let chain =
spawn_chain_runtime(&config, &ch.id).unwrap_or_else(exit_with_unrecoverable_error);

match chain.health_check() {
Ok(Healthy) => info!("[{}] chain is healthy", ch.id),
Ok(Healthy) => info!(chain = %ch.id, "chain is healthy"),
Ok(Unhealthy(_)) => {
// No need to print the error here as it's already printed in `Chain::health_check`
// TODO(romac): Move the printing code here and in the supervisor/registry
Expand Down
18 changes: 3 additions & 15 deletions relayer-cli/src/commands/query/channel.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
use alloc::sync::Arc;

use abscissa_core::clap::Parser;
use abscissa_core::{Command, Runnable};
use tokio::runtime::Runtime as TokioRuntime;
use ibc_relayer::chain::handle::ChainHandle;

use ibc::core::ics24_host::identifier::ChainId;
use ibc::core::ics24_host::identifier::{ChannelId, PortId};
use ibc_relayer::chain::requests::QueryChannelRequest;
use ibc_relayer::chain::{ChainEndpoint, CosmosSdkChain};

use crate::cli_utils::spawn_chain_runtime;
use crate::conclude::{exit_with_unrecoverable_error, Output};
use crate::prelude::*;
use ibc::core::ics04_channel::channel::State;
Expand All @@ -32,19 +30,9 @@ impl Runnable for QueryChannelEndCmd {
fn run(&self) {
let config = app_config();

let chain_config = match config.find_chain(&self.chain_id) {
None => Output::error(format!(
"chain '{}' not found in configuration file",
self.chain_id
))
.exit(),
Some(chain_config) => chain_config,
};

debug!("Options: {:?}", self);

let rt = Arc::new(TokioRuntime::new().unwrap());
let chain = CosmosSdkChain::bootstrap(chain_config.clone(), rt)
let chain = spawn_chain_runtime(&config, &self.chain_id)
.unwrap_or_else(exit_with_unrecoverable_error);

let res = chain.query_channel(QueryChannelRequest {
Expand Down
60 changes: 10 additions & 50 deletions relayer-cli/src/commands/query/client.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use alloc::sync::Arc;

use abscissa_core::clap::Parser;
use abscissa_core::{Command, Runnable};
use tracing::debug;

use ibc_relayer::chain::handle::ChainHandle;
use ibc_relayer::chain::requests::{
PageRequest, QueryClientConnectionsRequest, QueryClientStateRequest,
QueryConsensusStateRequest, QueryConsensusStatesRequest,
};
use tokio::runtime::Runtime as TokioRuntime;
use tracing::debug;

use ibc::core::ics02_client::client_consensus::QueryClientEventRequest;
use ibc::core::ics02_client::client_state::ClientState;
Expand All @@ -16,10 +15,9 @@ use ibc::core::ics24_host::identifier::ClientId;
use ibc::events::WithBlockDataType;
use ibc::query::QueryTxRequest;
use ibc::Height;
use ibc_relayer::chain::ChainEndpoint;
use ibc_relayer::chain::CosmosSdkChain;

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

/// Query client state command
Expand All @@ -41,18 +39,9 @@ impl Runnable for QueryClientStateCmd {
fn run(&self) {
let config = app_config();

let chain_config = match config.find_chain(&self.chain_id) {
None => Output::error(format!(
"chain '{}' not found in configuration file",
self.chain_id
))
.exit(),
Some(chain_config) => chain_config,
};

let rt = Arc::new(TokioRuntime::new().unwrap());
let chain = CosmosSdkChain::bootstrap(chain_config.clone(), rt)
let chain = spawn_chain_runtime(&config, &self.chain_id)
.unwrap_or_else(exit_with_unrecoverable_error);

let height = ibc::Height::new(chain.id().version(), self.height.unwrap_or(0_u64));

match chain.query_client_state(QueryClientStateRequest {
Expand Down Expand Up @@ -98,19 +87,9 @@ impl Runnable for QueryClientConsensusCmd {
fn run(&self) {
let config = app_config();

let chain_config = match config.find_chain(&self.chain_id) {
None => Output::error(format!(
"chain '{}' not found in configuration file",
self.chain_id
))
.exit(),
Some(chain_config) => chain_config,
};

debug!("Options: {:?}", self);

let rt = Arc::new(TokioRuntime::new().unwrap());
let chain = CosmosSdkChain::bootstrap(chain_config.clone(), rt)
let chain = spawn_chain_runtime(&config, &self.chain_id)
.unwrap_or_else(exit_with_unrecoverable_error);

let counterparty_chain = match chain.query_client_state(QueryClientStateRequest {
Expand Down Expand Up @@ -184,19 +163,9 @@ impl Runnable for QueryClientHeaderCmd {
fn run(&self) {
let config = app_config();

let chain_config = match config.find_chain(&self.chain_id) {
None => Output::error(format!(
"chain '{}' not found in configuration file",
self.chain_id
))
.exit(),
Some(chain_config) => chain_config,
};

debug!("Options: {:?}", self);

let rt = Arc::new(TokioRuntime::new().unwrap());
let chain = CosmosSdkChain::bootstrap(chain_config.clone(), rt)
let chain = spawn_chain_runtime(&config, &self.chain_id)
.unwrap_or_else(exit_with_unrecoverable_error);

let counterparty_chain = match chain.query_client_state(QueryClientStateRequest {
Expand All @@ -213,6 +182,7 @@ impl Runnable for QueryClientHeaderCmd {

let consensus_height =
ibc::Height::new(counterparty_chain.version(), self.consensus_height);

let height = ibc::Height::new(chain.id().version(), self.height.unwrap_or(0_u64));

let res = chain.query_txs(QueryTxRequest::Client(QueryClientEventRequest {
Expand Down Expand Up @@ -251,19 +221,9 @@ impl Runnable for QueryClientConnectionsCmd {
fn run(&self) {
let config = app_config();

let chain_config = match config.find_chain(&self.chain_id) {
None => Output::error(format!(
"chain '{}' not found in configuration file",
self.chain_id
))
.exit(),
Some(chain_config) => chain_config,
};

debug!("Options: {:?}", self);

let rt = Arc::new(TokioRuntime::new().unwrap());
let chain = CosmosSdkChain::bootstrap(chain_config.clone(), rt)
let chain = spawn_chain_runtime(&config, &self.chain_id)
.unwrap_or_else(exit_with_unrecoverable_error);

let res = chain.query_client_connections(QueryClientConnectionsRequest {
Expand Down
28 changes: 8 additions & 20 deletions relayer-cli/src/commands/query/clients.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
use alloc::sync::Arc;

use abscissa_core::clap::Parser;
use abscissa_core::{Command, Runnable};
use ibc_relayer::chain::handle::ChainHandle;
use serde::Serialize;
use tokio::runtime::Runtime as TokioRuntime;

use ibc::core::ics02_client::client_state::ClientState;
use ibc::core::ics24_host::identifier::{ChainId, ClientId};
use ibc_relayer::chain::requests::{PageRequest, QueryClientStatesRequest};
use ibc_relayer::chain::{ChainEndpoint, CosmosSdkChain};

use crate::cli_utils::spawn_chain_runtime;
use crate::conclude::{exit_with_unrecoverable_error, Output};
use crate::error::Error;
use crate::prelude::*;
Expand Down Expand Up @@ -44,26 +42,16 @@ impl Runnable for QueryAllClientsCmd {
fn run(&self) {
let config = app_config();

let chain_config = match config.find_chain(&self.chain_id) {
None => Output::error(format!(
"chain '{}' not found in configuration file",
self.chain_id
))
.exit(),
Some(chain_config) => chain_config,
};

debug!("Options: {:?}", self);

let rt = Arc::new(TokioRuntime::new().unwrap());
let chain = CosmosSdkChain::bootstrap(chain_config.clone(), rt)
let chain = spawn_chain_runtime(&config, &self.chain_id)
.unwrap_or_else(exit_with_unrecoverable_error);

let req = QueryClientStatesRequest {
pagination: Some(PageRequest::all()),
};

let res: Result<_, Error> = chain.query_clients(req).map_err(Error::relayer);
let res: Result<_, Error> = chain
.query_clients(QueryClientStatesRequest {
pagination: Some(PageRequest::all()),
})
.map_err(Error::relayer);

match res {
Ok(clients) => {
Expand Down
30 changes: 4 additions & 26 deletions relayer-cli/src/commands/query/connection.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
use alloc::sync::Arc;

use abscissa_core::clap::Parser;
use abscissa_core::{Command, Runnable};
use ibc_relayer::chain::handle::ChainHandle;
use ibc_relayer::chain::requests::{
PageRequest, QueryConnectionChannelsRequest, QueryConnectionRequest,
};
use tokio::runtime::Runtime as TokioRuntime;

use ibc::core::{
ics03_connection::connection::State,
ics24_host::identifier::ConnectionId,
ics24_host::identifier::{ChainId, PortChannelId},
};
use ibc_relayer::chain::{ChainEndpoint, CosmosSdkChain};

use crate::cli_utils::spawn_chain_runtime;
use crate::conclude::{exit_with_unrecoverable_error, Output};
use crate::error::Error;
use crate::prelude::*;
Expand All @@ -35,19 +33,9 @@ impl Runnable for QueryConnectionEndCmd {
fn run(&self) {
let config = app_config();

let chain_config = match config.find_chain(&self.chain_id) {
None => Output::error(format!(
"chain '{}' not found in configuration file",
self.chain_id
))
.exit(),
Some(chain_config) => chain_config,
};

debug!("Options: {:?}", self);

let rt = Arc::new(TokioRuntime::new().unwrap());
let chain = CosmosSdkChain::bootstrap(chain_config.clone(), rt)
let chain = spawn_chain_runtime(&config, &self.chain_id)
.unwrap_or_else(exit_with_unrecoverable_error);

let height = ibc::Height::new(chain.id().version(), self.height.unwrap_or(0_u64));
Expand Down Expand Up @@ -88,19 +76,9 @@ impl Runnable for QueryConnectionChannelsCmd {
fn run(&self) {
let config = app_config();

let chain_config = match config.find_chain(&self.chain_id) {
None => Output::error(format!(
"chain '{}' not found in configuration file",
self.chain_id
))
.exit(),
Some(chain_config) => chain_config,
};

debug!("Options: {:?}", self);

let rt = Arc::new(TokioRuntime::new().unwrap());
let chain = CosmosSdkChain::bootstrap(chain_config.clone(), rt)
let chain = spawn_chain_runtime(&config, &self.chain_id)
.unwrap_or_else(exit_with_unrecoverable_error);

let res: Result<_, Error> = chain
Expand Down
Loading

0 comments on commit 08b7f98

Please sign in to comment.