From 044943bce92b800c1397e09a945971232fed3055 Mon Sep 17 00:00:00 2001 From: Romain Ruetschi Date: Wed, 7 Apr 2021 17:45:31 +0200 Subject: [PATCH] Remove light client commands and configuration (#793) * Remove light client commands and configuration * Remove light client init code in scripts * Update the changelog * Use rpc_timeout field from chain config * Update config files and ADRs * Add --locked flag when compiling hermes in init-clients * Fix ibc-proto recompilation bug (#802) * Fixed overwritten cosmos files * changelog * Fix typo in proto-compiler README * Fix bug where proto-compiler didn't find SDK repo if already cloned Co-authored-by: Romain Ruetschi * Add option to specify which events to listen for in `listen` command (#804) * Update config_example.toml * Rename init-clients to init-hermes Co-authored-by: Adi Seredinschi --- CHANGELOG.md | 6 +- ci/e2e.sh | 24 -- ci/simple_config.toml | 3 +- config.toml | 3 +- config_example.toml | 11 +- docs/architecture/adr-002-ibc-relayer.md | 34 ++- .../adr-006-hermes-v0.2-usecases.md | 1 - relayer-cli/src/cli_utils.rs | 57 +--- relayer-cli/src/commands.rs | 10 +- relayer-cli/src/commands/create/channel.rs | 17 +- relayer-cli/src/commands/create/connection.rs | 15 +- relayer-cli/src/commands/light.rs | 18 -- relayer-cli/src/commands/light/add.rs | 287 ------------------ relayer-cli/src/commands/light/rm.rs | 173 ----------- relayer-cli/src/commands/tx/channel.rs | 12 +- relayer-cli/src/commands/tx/client.rs | 29 +- relayer-cli/src/commands/tx/connection.rs | 12 +- relayer-cli/src/commands/tx/packet.rs | 19 +- relayer-cli/src/registry.rs | 2 +- relayer-cli/tests/fixtures/two_chains.toml | 33 +- relayer/src/chain/cosmos.rs | 17 +- relayer/src/chain/mock.rs | 2 +- relayer/src/config.rs | 96 +----- relayer/src/light_client/tendermint.rs | 17 +- .../config/fixtures/relayer_conf_example.toml | 3 +- .../tests/config/fixtures/simple_config.toml | 9 +- scripts/dev-env | 2 +- scripts/init-clients | 107 ------- scripts/init-hermes | 73 +++++ 29 files changed, 173 insertions(+), 919 deletions(-) delete mode 100644 relayer-cli/src/commands/light.rs delete mode 100644 relayer-cli/src/commands/light/add.rs delete mode 100644 relayer-cli/src/commands/light/rm.rs delete mode 100755 scripts/init-clients create mode 100755 scripts/init-hermes diff --git a/CHANGELOG.md b/CHANGELOG.md index a3831893b4..e96f8a3bab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,10 +67,11 @@ - `MsgConnectionOpenAck.counterparty_connection_id` is now a `ConnectionId` instead of an `Option`([#700]) - [ibc-relayer] - - [nothing yet] + - Remove the light client configuration from the global configuration ([#793]) - [ibc-relayer-cli] - - [nothing yet] + - Remove the light add and light rm commands ([#793]) + [#352]: https://github.com/informalsystems/ibc-rs/issues/352 [#357]: https://github.com/informalsystems/ibc-rs/issues/357 @@ -98,6 +99,7 @@ [#761]: https://github.com/informalsystems/ibc-rs/issues/761 [#772]: https://github.com/informalsystems/ibc-rs/issues/772 [#770]: https://github.com/informalsystems/ibc-rs/issues/770 +[#793]: https://github.com/informalsystems/ibc-rs/pull/793 [#798]: https://github.com/informalsystems/ibc-rs/issues/798 [#801]: https://github.com/informalsystems/ibc-rs/issues/801 diff --git a/ci/e2e.sh b/ci/e2e.sh index aff85b07af..6e9c037f05 100755 --- a/ci/e2e.sh +++ b/ci/e2e.sh @@ -33,30 +33,6 @@ echo "Add keys for chains" echo "-----------------------------------------------------------------------------------------------------------------" hermes -c "$CONFIG_PATH" keys add "$CHAIN_A" key_seed_"$CHAIN_A".json hermes -c "$CONFIG_PATH" keys add "$CHAIN_B" key_seed_"$CHAIN_B".json -echo "-----------------------------------------------------------------------------------------------------------------" -echo "Set the primary peers for clients on each chain " -echo "-----------------------------------------------------------------------------------------------------------------" -LIGHT_ADD_CHAIN_A="hermes -c $CONFIG_PATH light add http://$CHAIN_A:$CHAIN_A_PORT -c $CHAIN_A -s $CHAIN_A_HOME -p -y -f" -echo "Executing: $LIGHT_ADD_CHAIN_A" -bash -c "$LIGHT_ADD_CHAIN_A" -sleep 2 -echo "-----------------------------------------------------------------------------------------------------------------" -LIGHT_ADD_CHAIN_B="hermes -c $CONFIG_PATH light add http://$CHAIN_B:$CHAIN_B_PORT -c $CHAIN_B -s $CHAIN_B_HOME -p -y -f" -echo "Executing: $LIGHT_ADD_CHAIN_B" -bash -c "$LIGHT_ADD_CHAIN_B" -sleep 2 -echo "-----------------------------------------------------------------------------------------------------------------" -echo "Set the secondary peers for clients on each chain " -echo "-----------------------------------------------------------------------------------------------------------------" -LIGHT_ADD_CHAIN_A_PEER="hermes -c $CONFIG_PATH light add http://$CHAIN_A:$CHAIN_A_PORT -c $CHAIN_A -s $CHAIN_A_HOME --peer-id 17D46D8C1576A79203A6733F63B2C9B7235DD559 -y" -echo "Executing: $LIGHT_ADD_CHAIN_A_PEER" -bash -c "$LIGHT_ADD_CHAIN_A_PEER" -sleep 2 -echo "-----------------------------------------------------------------------------------------------------------------" -LIGHT_ADD_CHAIN_B_PEER="hermes -c $CONFIG_PATH light add http://$CHAIN_B:$CHAIN_B_PORT -c $CHAIN_B -s $CHAIN_B_HOME --peer-id A885BB3D3DFF6101188B462466AE926E7A6CD51E -y" -echo "Executing: $LIGHT_ADD_CHAIN_B_PEER" -bash -c "$LIGHT_ADD_CHAIN_B_PEER" -sleep 2 echo "=================================================================================================================" echo " END-TO-END TESTS " diff --git a/ci/simple_config.toml b/ci/simple_config.toml index 7aaf2aff1d..35be457c28 100644 --- a/ci/simple_config.toml +++ b/ci/simple_config.toml @@ -1,5 +1,4 @@ [global] -timeout = '10s' strategy = 'naive' log_level = 'info' @@ -8,6 +7,7 @@ id = 'ibc-0' rpc_addr = 'http://ibc-0:26657' grpc_addr = 'http://ibc-0:9090' websocket_addr = 'ws://ibc-0:26657/websocket' +rpc_timeout = '10s' account_prefix = 'cosmos' key_name = 'testkey' store_prefix = 'ibc' @@ -22,6 +22,7 @@ id = 'ibc-1' rpc_addr = 'http://ibc-1:26657' grpc_addr = 'http://ibc-1:9090' websocket_addr = 'ws://ibc-1:26657/websocket' +rpc_timeout = '10s' account_prefix = 'cosmos' key_name = 'testkey' store_prefix = 'ibc' diff --git a/config.toml b/config.toml index fc677da33d..2904ee82d5 100644 --- a/config.toml +++ b/config.toml @@ -1,5 +1,4 @@ [global] -timeout = '10s' strategy = 'naive' log_level = 'error' @@ -8,6 +7,7 @@ id = 'ibc-0' rpc_addr = 'http://127.0.0.1:26657' grpc_addr = 'http://127.0.0.1:9090' websocket_addr = 'ws://127.0.0.1:26657/websocket' +rpc_timeout = '10s' account_prefix = 'cosmos' key_name = 'testkey' store_prefix = 'ibc' @@ -26,6 +26,7 @@ id = 'ibc-1' rpc_addr = 'http://127.0.0.1:26557' grpc_addr = 'http://127.0.0.1:9091' websocket_addr = 'ws://127.0.0.1:26557/websocket' +rpc_timeout = '10s' account_prefix = 'cosmos' key_name = 'testkey' store_prefix = 'ibc' diff --git a/config_example.toml b/config_example.toml index 0685f82317..b335c8a178 100644 --- a/config_example.toml +++ b/config_example.toml @@ -1,13 +1,13 @@ [global] -timeout = '10s' strategy = 'naive' log_level = 'error' [[chains]] id = 'ibc-0' -rpc_addr = 'tcp://localhost:26657' -grpc_addr = 'tcp://localhost:9090' +rpc_addr = 'http://localhost:26657' +grpc_addr = 'http://localhost:9090' websocket_addr = 'ws://localhost:26657/websocket' +rpc_timeout = '10s' account_prefix = 'cosmos' key_name = 'testkey' store_prefix = 'ibc' @@ -23,9 +23,10 @@ denominator = '3' [[chains]] id = 'ibc-1' -rpc_addr = 'tcp://localhost:26557' -grpc_addr = 'tcp://localhost:9091' +rpc_addr = 'http://localhost:26557' +grpc_addr = 'http://localhost:9091' websocket_addr = 'ws://localhost:26557/websocket' +rpc_timeout = '10s' account_prefix = 'cosmos' key_name = 'testkey' store_prefix = 'ibc' diff --git a/docs/architecture/adr-002-ibc-relayer.md b/docs/architecture/adr-002-ibc-relayer.md index 487a211fbb..1df200c548 100644 --- a/docs/architecture/adr-002-ibc-relayer.md +++ b/docs/architecture/adr-002-ibc-relayer.md @@ -2,6 +2,7 @@ ## Changelog * 2020-05-19: First draft. Accepted +* 2020-04-06: Configuration updates ## Definitions These definitions are specific for this document and they may not be consistent with the IBC Specification. @@ -110,20 +111,23 @@ The relayer MAY: The initial implementation will heavily borrow from the Go relayer implementation that uses a "naive" algorithm for relaying messages. The structure of the configuration file is similar with the one in Go (see [Go-Relayer](https://github.com/cosmos/relayer)) ### Configuration -(WIP) + +> WIP + Upon start the relayer reads a configuration file that includes global and per chain parameters. The file format is .toml Below is an example of a configuration file. ```toml -title = "IBC Relayer Config Example" - [global] -timeout = "10s" strategy = "naive" +log_level = "error" [[chains]] id = "chain_A" - rpc_addr = "localhost:26657" + rpc_addr = "http://localhost:26657" + grpc_addr = "http://localhost:9090" + websocket_addr = "ws://localhost:26657/websocket" + rpc_timeout = "10s" account_prefix = "cosmos" key_name = "testkey" store_prefix = "ibc" @@ -135,7 +139,10 @@ strategy = "naive" [[chains]] id = "chain_B" - rpc_addr = "localhost:26557" + rpc_addr = "http://localhost:26557" + grpc_addr = "http://localhost:9091" + websocket_addr = "ws://localhost:26557/websocket" + rpc_timeout = "10s" account_prefix = "cosmos" key_name = "testkey" store_prefix = "ibc" @@ -197,13 +204,19 @@ pub enum Strategy { } pub struct GlobalConfig { - pub timeout: Duration, pub strategy: Strategy, + + /// All valid log levels, as defined in tracing: + /// https://docs.rs/tracing-core/0.1.17/tracing_core/struct.Level.html + pub log_level: String, } pub struct ChainConfig { pub id: ChainId, pub rpc_addr: tendermint_rpc::Url, + pub websocket_addr: tendermint_rpc::Url, + pub grpc_addr: tendermint_rpc::Url, + pub rpc_timeout: Duration, pub account_prefix: String, pub key_name: String, pub client_ids: Vec, @@ -248,13 +261,6 @@ To validate a configuration file: The command verifies that the specified configuration file parses and it is semantically correct. -#### Light Client Initialization -To initialize a light client: - -`relayer -c light init -x -h ` - -The command initializes the light client for `` with a trusted height and hash. This should be done for all chains for which relaying is performed. - #### Start To start the relayer: diff --git a/docs/architecture/adr-006-hermes-v0.2-usecases.md b/docs/architecture/adr-006-hermes-v0.2-usecases.md index 4620f33760..ee52cd728e 100644 --- a/docs/architecture/adr-006-hermes-v0.2-usecases.md +++ b/docs/architecture/adr-006-hermes-v0.2-usecases.md @@ -230,7 +230,6 @@ of the config file will look as follows: ```toml [global] -timeout = '10s' strategy = 'naive' log_level = 'error' log_json = 'false' diff --git a/relayer-cli/src/cli_utils.rs b/relayer-cli/src/cli_utils.rs index 2bb48c0b80..51c8f3fa42 100644 --- a/relayer-cli/src/cli_utils.rs +++ b/relayer-cli/src/cli_utils.rs @@ -1,7 +1,6 @@ use ibc::ics24_host::identifier::ChainId; use ibc_relayer::chain::runtime::ChainRuntime; use ibc_relayer::chain::CosmosSdkChain; -use ibc_relayer::config::{ChainConfig, StoreConfig}; use ibc_relayer::{chain::handle::ChainHandle, config::Config}; use crate::error::{Error, Kind}; @@ -23,20 +22,8 @@ impl ChainHandlePair { src_chain_id: &ChainId, dst_chain_id: &ChainId, ) -> Result { - Self::spawn_with(Default::default(), config, src_chain_id, dst_chain_id) - } - - /// Spawn the source and destination chain runtime from the configuration and chain identifiers, - /// and return the pair of associated handles. Accepts a `SpawnOptions` argument, which - /// is used to override each chain configuration before spawning its runtime. - pub fn spawn_with( - options: SpawnOptions, - config: &Config, - src_chain_id: &ChainId, - dst_chain_id: &ChainId, - ) -> Result { - let src = spawn_chain_runtime(options.clone(), config, src_chain_id)?; - let dst = spawn_chain_runtime(options, config, dst_chain_id)?; + let src = spawn_chain_runtime(config, src_chain_id)?; + let dst = spawn_chain_runtime(config, dst_chain_id)?; Ok(ChainHandlePair { src, dst }) } @@ -45,18 +32,15 @@ impl ChainHandlePair { /// Spawns a chain runtime from the configuration and given a chain identifier. /// Returns the corresponding handle if successful. pub fn spawn_chain_runtime( - spawn_options: SpawnOptions, config: &Config, chain_id: &ChainId, ) -> Result, Error> { - let mut chain_config = config + let chain_config = config .find_chain(chain_id) .cloned() .ok_or_else(|| format!("missing chain for id ({}) in configuration file", chain_id)) .map_err(|e| Kind::Config.context(e))?; - spawn_options.apply(&mut chain_config); - let chain_res = ChainRuntime::::spawn(chain_config).map_err(|e| Kind::Runtime.context(e)); @@ -64,38 +48,3 @@ pub fn spawn_chain_runtime( Ok(handle) } - -/// Allows override the chain configuration just before -/// spawning a new runtime instance. -/// -/// This is currently only used to override the configured -/// light client store for one-off commands which do not -/// need the disk-based store. -#[derive(Clone, Debug, Default)] -pub struct SpawnOptions { - override_store_config: Option, -} - -impl SpawnOptions { - /// Override the light client store config with the provided config. - pub fn override_store_config(store_config: StoreConfig) -> Self { - Self { - override_store_config: Some(store_config), - } - } - - /// Apply these options to the provided chain configuration. - pub fn apply(&self, chain_config: &mut ChainConfig) { - if let Some(store_config) = &self.override_store_config { - Self::apply_store_config(chain_config, &store_config) - } - } - - fn apply_store_config(chain_config: &mut ChainConfig, store_config: &StoreConfig) { - if let Some(peer_config) = chain_config.peers.as_mut() { - for light_client in &mut peer_config.light_clients { - light_client.store = store_config.clone(); - } - } - } -} diff --git a/relayer-cli/src/commands.rs b/relayer-cli/src/commands.rs index 811f468120..d9f495633a 100644 --- a/relayer-cli/src/commands.rs +++ b/relayer-cli/src/commands.rs @@ -12,15 +12,13 @@ use abscissa_core::{Command, Configurable, FrameworkError, Help, Options, Runnab use crate::config::Config; use self::{ - create::CreateCmds, keys::KeysCmd, light::LightCmd, listen::ListenCmd, query::QueryCmd, - start::StartCmd, start_multi::StartMultiCmd, tx::TxCmd, update::UpdateCmds, - version::VersionCmd, + create::CreateCmds, keys::KeysCmd, listen::ListenCmd, query::QueryCmd, start::StartCmd, + start_multi::StartMultiCmd, tx::TxCmd, update::UpdateCmds, version::VersionCmd, }; mod config; mod create; mod keys; -mod light; mod listen; mod query; mod start; @@ -50,10 +48,6 @@ pub enum CliCmd { #[options(help = "Manage keys in the relayer for each chain")] Keys(KeysCmd), - /// The `light` subcommand - #[options(help = "Basic functionality for managing the light clients")] - Light(LightCmd), - /// The `create` subcommand #[options(help = "Create objects (client, connection, or channel) on chains")] Create(CreateCmds), diff --git a/relayer-cli/src/commands/create/channel.rs b/relayer-cli/src/commands/create/channel.rs index 82a3c7869b..df94458afb 100644 --- a/relayer-cli/src/commands/create/channel.rs +++ b/relayer-cli/src/commands/create/channel.rs @@ -6,11 +6,10 @@ use ibc::ics04_channel::channel::Order; use ibc::ics24_host::identifier::{ChainId, ConnectionId, PortId}; use ibc::Height; use ibc_relayer::channel::Channel; -use ibc_relayer::config::StoreConfig; use ibc_relayer::connection::Connection; use ibc_relayer::foreign_client::ForeignClient; -use crate::cli_utils::{spawn_chain_runtime, ChainHandlePair, SpawnOptions}; +use crate::cli_utils::{spawn_chain_runtime, ChainHandlePair}; use crate::conclude::{exit_with_unrecoverable_error, Output}; use crate::prelude::*; @@ -69,11 +68,9 @@ impl CreateChannelCommand { fn run_using_new_connection(&self, chain_b_id: &ChainId) { let config = app_config(); - let spawn_options = SpawnOptions::override_store_config(StoreConfig::memory()); + let chains = ChainHandlePair::spawn(&config, &self.chain_a_id, chain_b_id) + .unwrap_or_else(exit_with_unrecoverable_error); - let chains = - ChainHandlePair::spawn_with(spawn_options, &config, &self.chain_a_id, chain_b_id) - .unwrap_or_else(exit_with_unrecoverable_error); info!( "Creating new clients, new connection, and a new channel with order {:?} and version {}", self.order, self.version @@ -100,10 +97,8 @@ impl CreateChannelCommand { fn run_reusing_connection(&self) { let config = app_config(); - let spawn_options = SpawnOptions::override_store_config(StoreConfig::memory()); - // Validate & spawn runtime for side a. - let chain_a = spawn_chain_runtime(spawn_options.clone(), &config, &self.chain_a_id) + let chain_a = spawn_chain_runtime(&config, &self.chain_a_id) .unwrap_or_else(exit_with_unrecoverable_error); // Unwrap the identifier of the connection on side a. @@ -130,8 +125,8 @@ impl CreateChannelCommand { .unwrap_or_else(exit_with_unrecoverable_error); // Spawn the runtime for side b. - let chain_b = spawn_chain_runtime(spawn_options, &config, &chain_b_id) - .unwrap_or_else(exit_with_unrecoverable_error); + let chain_b = + spawn_chain_runtime(&config, &chain_b_id).unwrap_or_else(exit_with_unrecoverable_error); // Create the foreign client handles. let client_a = ForeignClient::find(chain_b.clone(), chain_a.clone(), conn_end.client_id()) diff --git a/relayer-cli/src/commands/create/connection.rs b/relayer-cli/src/commands/create/connection.rs index e7cca54b2c..4fd4019ae8 100644 --- a/relayer-cli/src/commands/create/connection.rs +++ b/relayer-cli/src/commands/create/connection.rs @@ -3,11 +3,10 @@ use abscissa_core::{Command, Options, Runnable}; use ibc::ics02_client::client_state::ClientState; use ibc::ics24_host::identifier::{ChainId, ClientId}; use ibc::Height; -use ibc_relayer::config::StoreConfig; use ibc_relayer::connection::Connection; use ibc_relayer::foreign_client::ForeignClient; -use crate::cli_utils::{spawn_chain_runtime, ChainHandlePair, SpawnOptions}; +use crate::cli_utils::{spawn_chain_runtime, ChainHandlePair}; use crate::conclude::{exit_with_unrecoverable_error, Output}; use crate::prelude::*; @@ -60,11 +59,8 @@ impl CreateConnectionCommand { fn run_using_new_clients(&self, chain_b_id: &ChainId) { let config = app_config(); - let spawn_options = SpawnOptions::override_store_config(StoreConfig::memory()); - - let chains = - ChainHandlePair::spawn_with(spawn_options, &config, &self.chain_a_id, chain_b_id) - .unwrap_or_else(exit_with_unrecoverable_error); + let chains = ChainHandlePair::spawn(&config, &self.chain_a_id, chain_b_id) + .unwrap_or_else(exit_with_unrecoverable_error); // Validate the other options. Bail if the CLI was invoked with incompatible options. if self.client_a.is_some() { @@ -99,9 +95,8 @@ impl CreateConnectionCommand { fn run_reusing_clients(&self) { let config = app_config(); - let spawn_options = SpawnOptions::override_store_config(StoreConfig::memory()); // Validate & spawn runtime for chain_a. - let chain_a = match spawn_chain_runtime(spawn_options.clone(), &config, &self.chain_a_id) { + let chain_a = match spawn_chain_runtime(&config, &self.chain_a_id) { Ok(handle) => handle, Err(e) => return Output::error(format!("{}", e)).exit(), }; @@ -131,7 +126,7 @@ impl CreateConnectionCommand { }; // Validate & spawn runtime for chain_b. - let chain_b = match spawn_chain_runtime(spawn_options, &config, &chain_b_id) { + let chain_b = match spawn_chain_runtime(&config, &chain_b_id) { Ok(handle) => handle, Err(e) => return Output::error(format!("{}", e)).exit(), }; diff --git a/relayer-cli/src/commands/light.rs b/relayer-cli/src/commands/light.rs deleted file mode 100644 index ca92b73e8d..0000000000 --- a/relayer-cli/src/commands/light.rs +++ /dev/null @@ -1,18 +0,0 @@ -//! `light` subcommand - -use abscissa_core::{Command, Options, Runnable}; - -mod add; -mod rm; - -/// `light` subcommand -#[derive(Command, Debug, Options, Runnable)] -pub enum LightCmd { - /// The `light add` subcommand - #[options(help = "Add a light client peer for a given chain")] - Add(add::AddCmd), - - /// The `light rm` subcommand - #[options(help = "Remove a light client peer for a given chain")] - Rm(rm::RmCmd), -} diff --git a/relayer-cli/src/commands/light/add.rs b/relayer-cli/src/commands/light/add.rs deleted file mode 100644 index 245128d3ae..0000000000 --- a/relayer-cli/src/commands/light/add.rs +++ /dev/null @@ -1,287 +0,0 @@ -use std::{fmt, io, io::Write, ops::Deref, path::PathBuf}; - -use abscissa_core::{application::fatal_error, error::BoxError, Command, Options, Runnable}; - -use config::StoreConfig; -use ibc::ics24_host::identifier::ChainId; -use ibc_relayer::{ - config, - config::{Config, LightClientConfig, PeersConfig}, - util::block_on, -}; -use tendermint::block::Height; -use tendermint::hash::Hash; -use tendermint_light_client::types::PeerId; -use tendermint_rpc::{Client, HttpClient}; - -use crate::prelude::*; - -#[derive(Command, Debug, Options)] -pub struct AddCmd { - /// RPC network address (required) - #[options(free)] - address: Option, - - /// identifier of the chain (required) - #[options(short = "c")] - chain_id: Option, - - /// path to light client store for this peer (required) - store: Option, - - /// whether this is the primary peer - primary: bool, - - /// allow overriding an existing peer - force: bool, - - /// skip confirmation - yes: bool, - - /// override peer id (optional) - #[options(no_short)] - peer_id: Option, - - /// override height (optional) - #[options(no_short)] - height: Option, - - /// override hash (optional) - #[options(no_short)] - hash: Option, -} - -impl AddCmd { - fn cmd(&self) -> Result<(), BoxError> { - let config = (*app_config()).clone(); - let options = AddOptions::from_cmd(self).map_err(|e| format!("invalid options: {}", e))?; - - options - .validate() - .map_err(|e| format!("invalid options: {}", e))?; - - add(config, options) - } -} - -impl Runnable for AddCmd { - fn run(&self) { - self.cmd() - .unwrap_or_else(|e| fatal_error(app_reader().deref(), &*e)) - } -} - -#[derive(Clone, Debug)] -struct AddOptions { - /// identifier of the chain - chain_id: ChainId, - - /// RPC network address - address: tendermint_rpc::Url, - - /// whether this is the primary peer or not - primary: bool, - - /// path to light client store for this peer - store: PathBuf, - - /// override peer id - override_peer_id: Option, - - /// override height - override_height: Option, - - /// override hash - override_hash: Option, - - /// allow overriding an existing peer - force: bool, - - /// skip confirmation - yes: bool, -} - -impl AddOptions { - fn from_cmd(cmd: &AddCmd) -> Result { - let chain_id = cmd.chain_id.clone().ok_or("missing chain identifier")?; - let address = cmd.address.clone().ok_or("missing RPC network address")?; - let store_path = cmd.store.clone().ok_or("missing store path")?; - - Ok(AddOptions { - chain_id, - address, - store: store_path, - override_peer_id: cmd.peer_id, - override_height: cmd.height, - override_hash: cmd.hash, - primary: cmd.primary, - force: cmd.force, - yes: cmd.yes, - }) - } - - fn validate(&self) -> Result<(), BoxError> { - if !self.store.exists() { - return Err(format!("Store path '{}' does not exists", self.store.display()).into()); - } - - if !self.store.is_dir() { - return Err(format!("Store path '{}' is not a directory", self.store.display()).into()); - } - - Ok(()) - } -} - -#[derive(Debug, Clone)] -pub struct NodeStatus { - chain_id: ChainId, - address: tendermint_rpc::Url, - peer_id: PeerId, - hash: Hash, - height: Height, -} - -impl fmt::Display for NodeStatus { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - writeln!(f, " chain id: {}", self.chain_id)?; - writeln!(f, " address: {}", self.address)?; - writeln!(f, " peer id: {}", self.peer_id)?; - writeln!(f, " height: {}", self.height)?; - writeln!(f, " hash: {}", self.hash)?; - - Ok(()) - } -} - -fn add(mut config: Config, options: AddOptions) -> Result<(), BoxError> { - // Fetch the status from the node - let mut status = fetch_status(options.chain_id.clone(), options.address.clone())?; - - // Override the fetched status with command line arguments, if given - override_status(&mut status, &options); - - // Ask the user for confirmation if --yes was not supplied - if !(options.yes || confirm(&status, options.primary)?) { - return Ok(()); - } - - // Update the in-memory configuration - let new_primary = update_config(options, status.clone(), &mut config)?; - - // Write the updated configuration to disk - let config_path = crate::config::config_path()?; - ibc_relayer::config::store(&config, config_path)?; - - status_ok!( - "Success", - "Added light client:\n{} primary: {}", - status, - status.peer_id == new_primary, - ); - - Ok(()) -} - -fn fetch_status(chain_id: ChainId, address: tendermint_rpc::Url) -> Result { - let rpc_client = HttpClient::new(address.clone())?; - let response = block_on(rpc_client.status())?; - - let peer_id = response.node_info.id; - let height = response.sync_info.latest_block_height; - let hash = response.sync_info.latest_block_hash; - - Ok(NodeStatus { - chain_id, - address, - peer_id, - hash, - height, - }) -} - -fn override_status(status: &mut NodeStatus, options: &AddOptions) { - if let Some(peer_id) = options.override_peer_id { - status.peer_id = peer_id; - } - - if let Some(height) = options.override_height { - status.height = height; - } - - if let Some(hash) = options.override_hash { - status.hash = hash; - } -} - -fn confirm(status: &NodeStatus, primary: bool) -> Result { - print!("Light client configuration:\n{}", status); - println!(" primary: {}", primary); - - loop { - print!("\n? Do you want to add a new light client with these trust options? (y/n) > "); - io::stdout().flush()?; // need to flush stdout since stdout is often line-buffered - - let mut choice = String::new(); - io::stdin().read_line(&mut choice)?; - - match choice.trim_end() { - "y" | "yes" => return Ok(true), - "n" | "no" => return Ok(false), - _ => continue, - } - } -} - -fn update_config( - options: AddOptions, - status: NodeStatus, - config: &mut Config, -) -> Result { - let chain_config = config - .find_chain_mut(&options.chain_id) - .ok_or_else(|| format!("could not find config for chain: {}", options.chain_id))?; - - let peers_config = chain_config.peers.get_or_insert_with(|| PeersConfig { - primary: status.peer_id, - light_clients: vec![], - }); - - // Check if the given peer exists already, in which case throw an error except if the - // --force flag is set. - let peer_exists = peers_config.light_client(status.peer_id).is_some(); - if peer_exists && !options.force { - return Err(format!( - "a peer with id {} already exists, remove it first \ - or pass the --force flag to override it", - status.peer_id - ) - .into()); - } - - let light_client_config = LightClientConfig { - peer_id: status.peer_id, - address: status.address.clone(), - timeout: config::default::timeout(), - trusted_header_hash: status.hash, - trusted_height: status.height, - store: StoreConfig::Disk { - path: options.store.join(status.peer_id.to_string()), - }, - }; - - if peer_exists { - // Filter out the light client config with the specified peer id - peers_config - .light_clients - .retain(|p| p.peer_id != status.peer_id); - } - - peers_config.light_clients.push(light_client_config); - - if options.primary { - peers_config.primary = status.peer_id; - } - - Ok(peers_config.primary) -} diff --git a/relayer-cli/src/commands/light/rm.rs b/relayer-cli/src/commands/light/rm.rs deleted file mode 100644 index dc2bbf8628..0000000000 --- a/relayer-cli/src/commands/light/rm.rs +++ /dev/null @@ -1,173 +0,0 @@ -use std::{io, io::Write, ops::Deref}; - -use abscissa_core::{application::fatal_error, error::BoxError, Command, Options, Runnable}; -use tendermint_light_client::types::PeerId; - -use ibc::ics24_host::identifier::ChainId; -use ibc_relayer::config::PeersConfig; - -use crate::conclude::Output; -use crate::prelude::*; - -#[derive(Command, Debug, Options)] -pub struct RmCmd { - /// identifiers of peers to remove - #[options(free)] - peer_id: Vec, - - /// identifier of the chain to remove peers from - #[options(short = "c")] - chain_id: Option, - - /// force removal of primary peer - #[options(short = "f")] - force: bool, - - /// remove all peers, implies --force - #[options(no_short)] - all: bool, - - /// skip confirmation - yes: bool, -} - -#[derive(Clone, Debug)] -struct RmOptions { - /// identifier of the chain to remove peers from - chain_id: ChainId, - - /// identifiers of peers to remove - peer_ids: Vec, - - /// remove all peers, implies --force - all: bool, - - /// force removal of primary peer - force: bool, - - /// skip confirmation - yes: bool, -} - -impl RmOptions { - fn from_cmd(cmd: &RmCmd) -> Result { - let chain_id = cmd.chain_id.clone().ok_or("missing chain identifier")?; - let peer_ids = if !cmd.all && cmd.peer_id.is_empty() { - return Err("missing peer identifier".into()); - } else { - cmd.peer_id.clone() - }; - - Ok(RmOptions { - chain_id, - peer_ids, - all: cmd.all, - yes: cmd.yes, - force: cmd.force, - }) - } -} - -impl Runnable for RmCmd { - fn run(&self) { - self.cmd() - .unwrap_or_else(|e| fatal_error(app_reader().deref(), &*e)) - } -} - -impl RmCmd { - fn cmd(&self) -> Result<(), BoxError> { - let options = RmOptions::from_cmd(self).map_err(|e| format!("invalid options: {}", e))?; - let mut config = (*app_config()).clone(); - - let chain_config = config - .find_chain_mut(&options.chain_id) - .ok_or_else(|| format!("could not find config for chain: {}", options.chain_id))?; - - let mut peers_config = chain_config - .peers - .as_mut() - .ok_or_else(|| format!("no peers configured for chain: {}", options.chain_id))?; - - let rmd_peers = if options.all && (options.yes || confirm(&options.chain_id)?) { - let removed_peers = get_all_peer_ids(&peers_config); - chain_config.peers = None; - - removed_peers - } else { - let mut res: Vec = vec![]; - for peer_id in options.peer_ids { - let removed_peer = remove_peer(&mut peers_config, peer_id, options.force)?; - res.push(removed_peer.to_string()); - } - - res - }; - - let config_path = crate::config::config_path()?; - ibc_relayer::config::store(&config, config_path)?; - - Output::success(format!("Removed light client peer(s) '{:?}'", rmd_peers)).exit(); - - Ok(()) - } -} - -fn remove_peer( - peers_config: &mut PeersConfig, - peer_id: PeerId, - force: bool, -) -> Result { - // Check if the given peer actually exists already, if not throw an error. - let peer_exists = peers_config.light_client(peer_id).is_some(); - if !peer_exists { - return Err(format!("cannot find peer: {}", peer_id).into()); - } - - // Only allow remove the primary peer if the --force option is set - let removed_primary = peers_config.primary == peer_id; - if removed_primary && !force { - return Err("cannot remove primary peer, pass --force flag to force removal".into()); - } - - // Filter out the light client config with the specified peer id - peers_config.light_clients.retain(|p| p.peer_id != peer_id); - - // If the peer we removed was the primary peer, use the next available peer as the primary, - // if any. - if removed_primary { - if let Some(new_primary) = peers_config.light_clients.first() { - peers_config.primary = new_primary.peer_id; - } - } - - Ok(peer_id) -} - -fn get_all_peer_ids(peers_config: &PeersConfig) -> Vec { - peers_config - .light_clients - .iter() - .map(|c| c.peer_id.to_string()) - .collect() -} - -fn confirm(chain_id: &ChainId) -> Result { - loop { - print!( - "\n? Do you really want to remove all peers for chain '{}'? (y/n) > ", - chain_id - ); - - io::stdout().flush()?; // need to flush stdout since stdout is often line-buffered - - let mut choice = String::new(); - io::stdin().read_line(&mut choice)?; - - match choice.trim_end() { - "y" | "yes" => return Ok(true), - "n" | "no" => return Ok(false), - _ => continue, - } - } -} diff --git a/relayer-cli/src/commands/tx/channel.rs b/relayer-cli/src/commands/tx/channel.rs index 0931c2b06f..914f78c52c 100644 --- a/relayer-cli/src/commands/tx/channel.rs +++ b/relayer-cli/src/commands/tx/channel.rs @@ -6,9 +6,8 @@ use ibc::ics04_channel::channel::Order; use ibc::ics24_host::identifier::{ChainId, ChannelId, ClientId, ConnectionId, PortId}; use ibc::Height; use ibc_relayer::channel::{Channel, ChannelSide}; -use ibc_relayer::config::StoreConfig; -use crate::cli_utils::{ChainHandlePair, SpawnOptions}; +use crate::cli_utils::ChainHandlePair; use crate::conclude::Output; use crate::error::{Error, Kind}; use crate::prelude::*; @@ -17,13 +16,8 @@ macro_rules! tx_chan_cmd { ($dbg_string:literal, $func:ident, $self:expr, $chan:expr) => { let config = app_config(); - let spawn_options = SpawnOptions::override_store_config(StoreConfig::memory()); - let chains = match ChainHandlePair::spawn_with( - spawn_options, - &config, - &$self.src_chain_id, - &$self.dst_chain_id, - ) { + let chains = match ChainHandlePair::spawn(&config, &$self.src_chain_id, &$self.dst_chain_id) + { Ok(chains) => chains, Err(e) => return Output::error(format!("{}", e)).exit(), }; diff --git a/relayer-cli/src/commands/tx/client.rs b/relayer-cli/src/commands/tx/client.rs index 38b0b3a209..8f6701a978 100644 --- a/relayer-cli/src/commands/tx/client.rs +++ b/relayer-cli/src/commands/tx/client.rs @@ -3,11 +3,10 @@ use tracing::info; use ibc::events::IbcEvent; use ibc::ics24_host::identifier::{ChainId, ClientId}; -use ibc_relayer::config::StoreConfig; use ibc_relayer::foreign_client::ForeignClient; use crate::application::app_config; -use crate::cli_utils::{ChainHandlePair, SpawnOptions}; +use crate::cli_utils::ChainHandlePair; use crate::conclude::{exit_with_unrecoverable_error, Output}; use crate::error::{Error, Kind}; @@ -26,13 +25,7 @@ impl Runnable for TxCreateClientCmd { fn run(&self) { let config = app_config(); - let spawn_options = SpawnOptions::override_store_config(StoreConfig::memory()); - let chains = match ChainHandlePair::spawn_with( - spawn_options, - &config, - &self.src_chain_id, - &self.dst_chain_id, - ) { + let chains = match ChainHandlePair::spawn(&config, &self.src_chain_id, &self.dst_chain_id) { Ok(chains) => chains, Err(e) => return Output::error(format!("{}", e)).exit(), }; @@ -75,13 +68,7 @@ impl Runnable for TxUpdateClientCmd { fn run(&self) { let config = app_config(); - let spawn_options = SpawnOptions::override_store_config(StoreConfig::memory()); - let chains = match ChainHandlePair::spawn_with( - spawn_options, - &config, - &self.src_chain_id, - &self.dst_chain_id, - ) { + let chains = match ChainHandlePair::spawn(&config, &self.src_chain_id, &self.dst_chain_id) { Ok(chains) => chains, Err(e) => return Output::error(format!("{}", e)).exit(), }; @@ -127,14 +114,8 @@ 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); + let chains = ChainHandlePair::spawn(&config, &self.src_chain_id, &self.dst_chain_id) + .unwrap_or_else(exit_with_unrecoverable_error); info!("Started the chain runtimes"); diff --git a/relayer-cli/src/commands/tx/connection.rs b/relayer-cli/src/commands/tx/connection.rs index 702ff36906..161416cf32 100644 --- a/relayer-cli/src/commands/tx/connection.rs +++ b/relayer-cli/src/commands/tx/connection.rs @@ -2,10 +2,9 @@ use abscissa_core::{Command, Options, Runnable}; use ibc::events::IbcEvent; use ibc::ics24_host::identifier::{ChainId, ClientId, ConnectionId}; -use ibc_relayer::config::StoreConfig; use ibc_relayer::connection::{Connection, ConnectionSide}; -use crate::cli_utils::{ChainHandlePair, SpawnOptions}; +use crate::cli_utils::ChainHandlePair; use crate::conclude::Output; use crate::error::{Error, Kind}; use crate::prelude::*; @@ -14,13 +13,8 @@ macro_rules! conn_open_cmd { ($dbg_string:literal, $func:ident, $self:expr, $conn:expr) => { let config = app_config(); - let spawn_options = SpawnOptions::override_store_config(StoreConfig::memory()); - let chains = match ChainHandlePair::spawn_with( - spawn_options, - &config, - &$self.src_chain_id, - &$self.dst_chain_id, - ) { + let chains = match ChainHandlePair::spawn(&config, &$self.src_chain_id, &$self.dst_chain_id) + { Ok(chains) => chains, Err(e) => return Output::error(format!("{}", e)).exit(), }; diff --git a/relayer-cli/src/commands/tx/packet.rs b/relayer-cli/src/commands/tx/packet.rs index bf765a6df9..d31ad2e0be 100644 --- a/relayer-cli/src/commands/tx/packet.rs +++ b/relayer-cli/src/commands/tx/packet.rs @@ -2,10 +2,9 @@ use abscissa_core::{Command, Options, Runnable}; use ibc::events::IbcEvent; use ibc::ics24_host::identifier::{ChainId, ChannelId, PortId}; -use ibc_relayer::config::StoreConfig; use ibc_relayer::link::{Link, LinkParameters}; -use crate::cli_utils::{ChainHandlePair, SpawnOptions}; +use crate::cli_utils::ChainHandlePair; use crate::conclude::Output; use crate::error::{Error, Kind}; use crate::prelude::*; @@ -29,13 +28,7 @@ impl Runnable for TxRawPacketRecvCmd { fn run(&self) { let config = app_config(); - let spawn_options = SpawnOptions::override_store_config(StoreConfig::memory()); - let chains = match ChainHandlePair::spawn_with( - spawn_options, - &config, - &self.src_chain_id, - &self.dst_chain_id, - ) { + let chains = match ChainHandlePair::spawn(&config, &self.src_chain_id, &self.dst_chain_id) { Ok(chains) => chains, Err(e) => return Output::error(format!("{}", e)).exit(), }; @@ -79,13 +72,7 @@ impl Runnable for TxRawPacketAckCmd { fn run(&self) { let config = app_config(); - let spawn_options = SpawnOptions::override_store_config(StoreConfig::memory()); - let chains = match ChainHandlePair::spawn_with( - spawn_options, - &config, - &self.src_chain_id, - &self.dst_chain_id, - ) { + let chains = match ChainHandlePair::spawn(&config, &self.src_chain_id, &self.dst_chain_id) { Ok(chains) => chains, Err(e) => return Output::error(format!("{}", e)).exit(), }; diff --git a/relayer-cli/src/registry.rs b/relayer-cli/src/registry.rs index eaf8a8f4d0..5f0b395448 100644 --- a/relayer-cli/src/registry.rs +++ b/relayer-cli/src/registry.rs @@ -30,7 +30,7 @@ impl<'a> Registry<'a> { /// return its handle. pub fn get_or_spawn(&mut self, chain_id: &ChainId) -> Result, Error> { if !self.handles.contains_key(chain_id) { - let handle = spawn_chain_runtime(Default::default(), &self.config, chain_id)?; + let handle = spawn_chain_runtime(&self.config, chain_id)?; self.handles.insert(chain_id.clone(), handle); } diff --git a/relayer-cli/tests/fixtures/two_chains.toml b/relayer-cli/tests/fixtures/two_chains.toml index d73a2dc06e..0e4548b42a 100644 --- a/relayer-cli/tests/fixtures/two_chains.toml +++ b/relayer-cli/tests/fixtures/two_chains.toml @@ -1,5 +1,4 @@ [global] -timeout = '10s' strategy = 'naive' log_level = 'error' # valid options: 'error', 'warn', 'info', 'debug', 'trace' @@ -8,14 +7,11 @@ id = 'ibc-0' rpc_addr = 'http://127.0.0.1:26657' grpc_addr = 'http://127.0.0.1:9090' websocket_addr = 'ws://127.0.0.1:26657/websocket' +rpc_timeout = '10s' account_prefix = 'cosmos' key_name = 'testkey' store_prefix = 'ibc' - -client_ids = [ - 'cla1', - 'cla2', -] +client_ids = ['cla1', 'cla2'] gas = 200000 clock_drift = '5s' trusting_period = '14days' @@ -24,23 +20,12 @@ trusting_period = '14days' numerator = '1' denominator = '3' -[chains.peers] -primary = 'E0DE6C540C65FC9059660A7A8535F70048A94539' - -[[chains.peers.light_clients]] -peer_id = 'E0DE6C540C65FC9059660A7A8535F70048A94539' -address = 'http://127.0.0.1:26657' -trusted_header_hash = '169F8F6318B8FAABDBA128AD1689E238566B69DDBD2B36F1911C0DFCA73FD401' -trusted_height = '7806' - -[chains.peers.light_clients.store] -type = 'memory' - [[chains]] id = 'ibc-1' rpc_addr = 'http://127.0.0.1:26657' grpc_addr = 'http://127.0.0.1:9090' websocket_addr = 'ws://127.0.0.1:26657/websocket' +rpc_timeout = '10s' account_prefix = 'cosmos' key_name = 'testkey' store_prefix = 'ibc' @@ -52,15 +37,3 @@ trusting_period = '14days' [chains.trust_threshold] numerator = '1' denominator = '3' - -[chains.peers] -primary = '356DB878F398BA707DBE69950067C8E6471D8948' - -[[chains.peers.light_clients]] -peer_id = '356DB878F398BA707DBE69950067C8E6471D8948' -address = 'http://127.0.0.1:26557' -trusted_header_hash = 'CC291E79B2E2068984EB13BBF420B4F4AE95357E25B9BA0A30CA26FF27AF3C75' -trusted_height = '7741' - -[chains.peers.light_clients.store] -type = 'memory' diff --git a/relayer/src/chain/cosmos.rs b/relayer/src/chain/cosmos.rs index dce44693fd..8c50a11598 100644 --- a/relayer/src/chain/cosmos.rs +++ b/relayer/src/chain/cosmos.rs @@ -62,7 +62,7 @@ use crate::config::ChainConfig; use crate::error::{Error, Kind}; use crate::event::monitor::{EventBatch, EventMonitor}; use crate::keyring::store::{KeyEntry, KeyRing, KeyRingOperations, StoreBackend}; -use crate::light_client::tendermint::LightClient as TMLightClient; +use crate::light_client::tendermint::LightClient as TmLightClient; use crate::light_client::LightClient; use super::Chain; @@ -320,7 +320,7 @@ impl Chain for CosmosSdkChain { .map_err(|e| Kind::Rpc(config.rpc_addr.clone()).context(e))?; // Initialize key store and load key - let key_store = KeyRing::init(StoreBackend::Test, config.clone()) + let keybase = KeyRing::init(StoreBackend::Test, config.clone()) .map_err(|e| Kind::KeyBase.context(e))?; let grpc_addr = @@ -329,16 +329,25 @@ impl Chain for CosmosSdkChain { Ok(Self { rt, config, - keybase: key_store, + keybase, rpc_client, grpc_addr, }) } fn init_light_client(&self) -> Result>, Error> { + use tendermint_light_client::types::PeerId; + crate::time!("init_light_client"); - let light_client = TMLightClient::from_config(&self.config)?; + let peer_id: PeerId = self + .rt + .block_on(self.rpc_client.status()) + .map(|s| s.node_info.id) + .map_err(|e| Kind::Rpc(self.config.rpc_addr.clone()).context(e))?; + + let light_client = TmLightClient::from_config(&self.config, peer_id)?; + Ok(Box::new(light_client)) } diff --git a/relayer/src/chain/mock.rs b/relayer/src/chain/mock.rs index ee9bd48d24..7653ee290d 100644 --- a/relayer/src/chain/mock.rs +++ b/relayer/src/chain/mock.rs @@ -339,6 +339,7 @@ pub mod test_utils { rpc_addr: "http://127.0.0.1:26656".parse().unwrap(), grpc_addr: "http://127.0.0.1:9090".parse().unwrap(), websocket_addr: "ws://127.0.0.1:26656/websocket".parse().unwrap(), + rpc_timeout: crate::config::default::rpc_timeout(), account_prefix: "".to_string(), key_name: "".to_string(), store_prefix: "".to_string(), @@ -350,7 +351,6 @@ pub mod test_utils { clock_drift: Duration::from_secs(5), trusting_period: Duration::from_secs(14 * 24 * 60 * 60), // 14 days trust_threshold: Default::default(), - peers: None, } } } diff --git a/relayer/src/config.rs b/relayer/src/config.rs index 66f0d8fb2c..d02b106659 100644 --- a/relayer/src/config.rs +++ b/relayer/src/config.rs @@ -1,16 +1,9 @@ //! Relayer configuration -use std::{ - fs, - fs::File, - io::Write, - path::{Path, PathBuf}, - time::Duration, -}; +use std::{fs, fs::File, io::Write, path::Path, time::Duration}; use serde_derive::{Deserialize, Serialize}; -use tendermint::Hash; -use tendermint_light_client::types::{Height, PeerId, TrustThreshold}; +use tendermint_light_client::types::TrustThreshold; use ibc::ics24_host::identifier::{ChainId, PortId}; @@ -20,7 +13,7 @@ use crate::error; pub mod default { use super::*; - pub fn timeout() -> Duration { + pub fn rpc_timeout() -> Duration { Duration::from_secs(10) } @@ -77,9 +70,6 @@ impl Default for Strategy { #[derive(Clone, Debug, Deserialize, Serialize)] pub struct GlobalConfig { - #[serde(default = "default::timeout", with = "humantime_serde")] - pub timeout: Duration, - #[serde(default)] pub strategy: Strategy, @@ -91,7 +81,6 @@ pub struct GlobalConfig { impl Default for GlobalConfig { fn default() -> Self { Self { - timeout: default::timeout(), strategy: Strategy::default(), log_level: "info".to_string(), } @@ -104,6 +93,8 @@ pub struct ChainConfig { pub rpc_addr: tendermint_rpc::Url, pub websocket_addr: tendermint_rpc::Url, pub grpc_addr: tendermint_rpc::Url, + #[serde(default = "default::rpc_timeout", with = "humantime_serde")] + pub rpc_timeout: Duration, pub account_prefix: String, pub key_name: String, pub store_prefix: String, @@ -118,34 +109,6 @@ pub struct ChainConfig { pub trusting_period: Duration, #[serde(default)] pub trust_threshold: TrustThreshold, - - // initially empty, to configure with the `light add/rm` commands - #[serde(skip_serializing_if = "Option::is_none")] - pub peers: Option, -} - -impl ChainConfig { - pub fn primary(&self) -> Option<&LightClientConfig> { - let peers = self.peers.as_ref()?; - peers.light_client(peers.primary) - } - - pub fn light_client(&self, id: PeerId) -> Option<&LightClientConfig> { - let peers = self.peers.as_ref()?; - peers.light_client(id) - } - - pub fn witnesses(&self) -> Option> { - let peers = self.peers.as_ref()?; - - Some( - peers - .light_clients - .iter() - .filter(|p| p.peer_id != peers.primary) - .collect(), - ) - } } #[derive(Clone, Debug, Deserialize, Serialize)] @@ -161,55 +124,6 @@ pub struct RelayPath { pub b_port: PortId, } -#[derive(Clone, Debug, Deserialize, Serialize)] -pub struct PeersConfig { - pub primary: PeerId, - pub light_clients: Vec, -} - -impl PeersConfig { - pub fn light_client(&self, id: PeerId) -> Option<&LightClientConfig> { - self.light_clients.iter().find(|p| p.peer_id == id) - } - - pub fn light_client_mut(&mut self, id: PeerId) -> Option<&mut LightClientConfig> { - self.light_clients.iter_mut().find(|p| p.peer_id == id) - } -} - -#[derive(Clone, Debug, Deserialize, Serialize)] -pub struct LightClientConfig { - pub peer_id: PeerId, - pub address: tendermint_rpc::Url, - #[serde(default = "default::timeout", with = "humantime_serde")] - pub timeout: Duration, - pub trusted_header_hash: Hash, - pub trusted_height: Height, - pub store: StoreConfig, -} - -#[derive(Clone, Debug, Deserialize, Serialize)] -#[serde(tag = "type")] -pub enum StoreConfig { - #[serde(rename = "disk")] - Disk { path: PathBuf }, - #[serde(rename = "memory")] - Memory { - #[serde(skip)] - dummy: (), - }, -} - -impl StoreConfig { - pub fn disk(path: PathBuf) -> Self { - Self::Disk { path } - } - - pub fn memory() -> Self { - Self::Memory { dummy: () } - } -} - /// Attempt to load and parse the TOML config file as a `Config`. pub fn parse(path: impl AsRef) -> Result { let config_toml = diff --git a/relayer/src/light_client/tendermint.rs b/relayer/src/light_client/tendermint.rs index 239032b776..f5648b4c6b 100644 --- a/relayer/src/light_client/tendermint.rs +++ b/relayer/src/light_client/tendermint.rs @@ -12,8 +12,11 @@ use tendermint_light_client::{ types::{LightBlock, PeerId, Status}, }; -use ibc::{downcast, ics02_client::client_state::AnyClientState}; -use ibc::{ics02_client::client_type::ClientType, ics24_host::identifier::ChainId}; +use ibc::{ + downcast, + ics02_client::{client_state::AnyClientState, client_type::ClientType}, + ics24_host::identifier::ChainId, +}; use crate::{ chain::CosmosSdkChain, @@ -56,19 +59,15 @@ impl super::LightClient for LightClient { } impl LightClient { - pub fn from_config(config: &ChainConfig) -> Result { + pub fn from_config(config: &ChainConfig, peer_id: PeerId) -> Result { let rpc_client = rpc::HttpClient::new(config.rpc_addr.clone()) .map_err(|e| error::Kind::LightClient(config.rpc_addr.to_string()).context(e))?; - let peer = config.primary().ok_or_else(|| { - error::Kind::LightClient(config.rpc_addr.to_string()).context("no primary peer") - })?; - - let io = components::io::ProdIo::new(peer.peer_id, rpc_client, Some(peer.timeout)); + let io = components::io::ProdIo::new(peer_id, rpc_client, Some(config.rpc_timeout)); Ok(Self { chain_id: config.id.clone(), - peer_id: peer.peer_id, + peer_id, io, }) } diff --git a/relayer/tests/config/fixtures/relayer_conf_example.toml b/relayer/tests/config/fixtures/relayer_conf_example.toml index 016a8455c3..234c133427 100644 --- a/relayer/tests/config/fixtures/relayer_conf_example.toml +++ b/relayer/tests/config/fixtures/relayer_conf_example.toml @@ -1,5 +1,4 @@ [global] -timeout = '10s' strategy = 'naive' log_level = 'error' @@ -8,6 +7,7 @@ id = 'chain_A' rpc_addr = 'http://127.0.0.1:26657' grpc_addr = 'http://127.0.0.1:9090' websocket_addr = 'ws://localhost:26657/websocket' +rpc_timeout = '10s' account_prefix = 'cosmos' key_name = 'testkey' store_prefix = 'ibc' @@ -28,6 +28,7 @@ id = 'chain_B' rpc_addr = 'http://127.0.0.1:26557' grpc_addr = 'http://127.0.0.1:9090' websocket_addr = 'ws://localhost:26557/websocket' +rpc_timeout = '10s' account_prefix = 'cosmos' key_name = 'testkey' store_prefix = 'ibc' diff --git a/relayer/tests/config/fixtures/simple_config.toml b/relayer/tests/config/fixtures/simple_config.toml index ce62e6d952..bd0bd6a8b2 100644 --- a/relayer/tests/config/fixtures/simple_config.toml +++ b/relayer/tests/config/fixtures/simple_config.toml @@ -3,7 +3,6 @@ title = "IBC Relayer Config Example" [global] -timeout = "10s" strategy = "naive" [[chains]] @@ -11,6 +10,7 @@ strategy = "naive" rpc_addr = "http://127.0.0.1:26657" grpc_addr = 'http://127.0.0.1:9090' websocket_addr = 'ws://localhost:26657/websocket' + rpc_timeout = '10s' account_prefix = "cosmos" key_name = "testkey" store_prefix = "ibc" @@ -21,14 +21,12 @@ strategy = "naive" gas_price = "0.025stake" trusting_period = "336h" - # TODO: Move to light client config - peer_id = "BADFADAD0BEFEEDC0C0ADEADBEEFC0FFEEFACADE" - [[chains]] id = "chain_B" rpc_addr = "http://127.0.0.1:26557" grpc_addr = 'http://127.0.0.1:9090' websocket_addr = 'ws://localhost:26557/websocket' + rpc_timeout = '10s' account_prefix = "cosmos" key_name = "testkey" store_prefix = "ibc" @@ -39,9 +37,6 @@ strategy = "naive" gas_price = "0.025stake" trusting_period = "336h" - # TODO: Move to light client config - peer_id = "DC0C0ADEADBEEFC0FFEEFACADEBADFADAD0BEFEE" - [[connections]] a_chain = "ibc1" b_chain = "ibc0" diff --git a/scripts/dev-env b/scripts/dev-env index 3dfd929573..eeb3dd87ba 100755 --- a/scripts/dev-env +++ b/scripts/dev-env @@ -35,7 +35,7 @@ CHAIN_1_ID="$3" CHAIN_2_ID="$4" SETUP_CHAINS="$(dirname "$0")/setup-chains" -INIT_CLIENTS="$(dirname "$0")/init-clients" +INIT_CLIENTS="$(dirname "$0")/init-hermes" "$SETUP_CHAINS" "$CHAIN_0_ID" "$CHAIN_1_ID" "$CHAIN_2_ID" "$INIT_CLIENTS" "$CONFIG_FILE" "$CHAIN_0_ID" "$CHAIN_1_ID" "$CHAIN_2_ID" diff --git a/scripts/init-clients b/scripts/init-clients deleted file mode 100755 index 5843247686..0000000000 --- a/scripts/init-clients +++ /dev/null @@ -1,107 +0,0 @@ -#!/bin/bash -e - -# Initialize the light clients in the relayer configuration. - -usage() { - echo "Usage: $0 CONFIG_FILE CHAIN_0_ID CHAIN_1_ID [CHAIN_2_ID]" - echo "Example: $0 ./config.toml ibc-0 ibc-1 ibc-2" - exit 1 -} - -missing() { - echo "Missing $1 parameter. Please check if all parameters were specified." - usage -} - -if [ -z "$1" ]; then - missing "CONFIG_FILE" -fi - -if [ -z "$2" ]; then - missing "CHAIN_0_ID" -fi - -if [ -z "$3" ]; then - missing "CHAIN_1_ID" -fi - - -if [ "$#" -gt 4 ]; then - echo "Incorrect number of parameters." - usage -fi - -CONFIG_FILE="$1" -CHAIN_0_ID="$2" -CHAIN_1_ID="$3" -CHAIN_2_ID="$4" - -if ! [ -f "$CONFIG_FILE" ]; then - echo "[CONFIG_FILE] ($1) does not exist or is not a file." - usage -fi - -if ! grep -q -s "$CHAIN_0_ID" "$CONFIG_FILE"; then - echo "error: configuration for chain [$CHAIN_0_ID] does not exist in file $CONFIG_FILE." - usage -fi - -if ! grep -q -s "$CHAIN_1_ID" "$CONFIG_FILE"; then - echo "error: configuration for chain [$CHAIN_1_ID] does not exist in file $CONFIG_FILE." - usage -fi - -if [ -n "$CHAIN_2_ID" ] && ! grep -q -s "$CHAIN_2_ID" "$CONFIG_FILE"; then - echo "error: configuration for chain [$CHAIN_2_ID] does not exist in file $CONFIG_FILE." - usage -fi - -GAIA_DATA="$(pwd)/data" - -CHAIN_0_RPC_PORT=26657 -CHAIN_0_RPC_ADDR="http://127.0.0.1:$CHAIN_0_RPC_PORT" -CHAIN_1_RPC_PORT=26557 -CHAIN_1_RPC_ADDR="http://127.0.0.1:$CHAIN_1_RPC_PORT" -CHAIN_2_RPC_PORT=26457 -CHAIN_2_RPC_ADDR="http://127.0.0.1:$CHAIN_2_RPC_PORT" - -echo "Building the Rust relayer..." -cargo build -q - -# cleanup the client entries from config -echo "Removing light client peers from configuration..." -cargo run -q --bin hermes -- -c "$CONFIG_FILE" light rm -c "$CHAIN_0_ID" --all -y || true -cargo run -q --bin hermes -- -c "$CONFIG_FILE" light rm -c "$CHAIN_1_ID" --all -y || true - -if [ -n "$CHAIN_2_ID" ]; then - cargo run -q --bin hermes -- -c "$CONFIG_FILE" light rm -c "$CHAIN_2_ID" --all -y || true -fi - -# set the primary peers for clients on each chain -echo "Adding primary peers to light client configuration..." -cargo run -q --bin hermes -- -c "$CONFIG_FILE" light add $CHAIN_0_RPC_ADDR -c "$CHAIN_0_ID" -f -p -s "$GAIA_DATA/$CHAIN_0_ID/data" -y -cargo run -q --bin hermes -- -c "$CONFIG_FILE" light add $CHAIN_1_RPC_ADDR -c "$CHAIN_1_ID" -f -p -s "$GAIA_DATA/$CHAIN_1_ID/data" -y - -if [ -n "$CHAIN_2_ID" ]; then - cargo run -q --bin hermes -- -c "$CONFIG_FILE" light add $CHAIN_2_RPC_ADDR -c "$CHAIN_2_ID" -f -p -s "$GAIA_DATA/$CHAIN_2_ID/data" -y -fi - -# set the secondary peers for clients on each chain -echo "Adding secondary peers to light client configuration..." -cargo run -q --bin hermes -- -c "$CONFIG_FILE" light add $CHAIN_0_RPC_ADDR -c "$CHAIN_0_ID" -s "$GAIA_DATA/$CHAIN_0_ID/data" -y --peer-id 2427F8D914A6862279B3326FA64F76E3BC06DB2E -cargo run -q --bin hermes -- -c "$CONFIG_FILE" light add $CHAIN_1_RPC_ADDR -c "$CHAIN_1_ID" -s "$GAIA_DATA/$CHAIN_1_ID/data" -y --peer-id A885BB3D3DFF6101188B462466AE926E7A6CD51E - -if [ -n "$CHAIN_2_ID" ]; then - cargo run -q --bin hermes -- -c "$CONFIG_FILE" light add $CHAIN_2_RPC_ADDR -c "$CHAIN_2_ID" -s "$GAIA_DATA/$CHAIN_2_ID/data" -y --peer-id 08B4625466AE926E7A5BB3D3DFF611E6CD118A88 -fi - -# add the key seeds to the keyring of each chain -echo "Importing keys..." -cargo run -q --bin hermes -- -c "$CONFIG_FILE" keys add "$CHAIN_0_ID" "$GAIA_DATA/$CHAIN_0_ID/key_seed.json" -cargo run -q --bin hermes -- -c "$CONFIG_FILE" keys add "$CHAIN_1_ID" "$GAIA_DATA/$CHAIN_1_ID/key_seed.json" - -if [ -n "$CHAIN_2_ID" ]; then - cargo run -q --bin hermes -- -c "$CONFIG_FILE" keys add "$CHAIN_2_ID" "$GAIA_DATA/$CHAIN_2_ID/key_seed.json" -fi - -echo "Done!" diff --git a/scripts/init-hermes b/scripts/init-hermes new file mode 100755 index 0000000000..f52ffe8708 --- /dev/null +++ b/scripts/init-hermes @@ -0,0 +1,73 @@ +#!/bin/bash -e + +# Initialize the light clients in the relayer configuration. + +usage() { + echo "Usage: $0 CONFIG_FILE CHAIN_0_ID CHAIN_1_ID [CHAIN_2_ID]" + echo "Example: $0 ./config.toml ibc-0 ibc-1 ibc-2" + exit 1 +} + +missing() { + echo "Missing $1 parameter. Please check if all parameters were specified." + usage +} + +if [ -z "$1" ]; then + missing "CONFIG_FILE" +fi + +if [ -z "$2" ]; then + missing "CHAIN_0_ID" +fi + +if [ -z "$3" ]; then + missing "CHAIN_1_ID" +fi + + +if [ "$#" -gt 4 ]; then + echo "Incorrect number of parameters." + usage +fi + +CONFIG_FILE="$1" +CHAIN_0_ID="$2" +CHAIN_1_ID="$3" +CHAIN_2_ID="$4" + +if ! [ -f "$CONFIG_FILE" ]; then + echo "[CONFIG_FILE] ($1) does not exist or is not a file." + usage +fi + +if ! grep -q -s "$CHAIN_0_ID" "$CONFIG_FILE"; then + echo "error: configuration for chain [$CHAIN_0_ID] does not exist in file $CONFIG_FILE." + usage +fi + +if ! grep -q -s "$CHAIN_1_ID" "$CONFIG_FILE"; then + echo "error: configuration for chain [$CHAIN_1_ID] does not exist in file $CONFIG_FILE." + usage +fi + +if [ -n "$CHAIN_2_ID" ] && ! grep -q -s "$CHAIN_2_ID" "$CONFIG_FILE"; then + echo "error: configuration for chain [$CHAIN_2_ID] does not exist in file $CONFIG_FILE." + usage +fi + +GAIA_DATA="$(pwd)/data" + +echo "Building the Rust relayer..." +cargo build -q --locked + +# add the key seeds to the keyring of each chain +echo "Importing keys..." +cargo run -q --bin hermes -- -c "$CONFIG_FILE" keys add "$CHAIN_0_ID" "$GAIA_DATA/$CHAIN_0_ID/key_seed.json" +cargo run -q --bin hermes -- -c "$CONFIG_FILE" keys add "$CHAIN_1_ID" "$GAIA_DATA/$CHAIN_1_ID/key_seed.json" + +if [ -n "$CHAIN_2_ID" ]; then + cargo run -q --bin hermes -- -c "$CONFIG_FILE" keys add "$CHAIN_2_ID" "$GAIA_DATA/$CHAIN_2_ID/key_seed.json" +fi + +echo "Done!"