diff --git a/.changelog/unreleased/improvements/ibc-integration-test/3235-add-juno.md b/.changelog/unreleased/improvements/ibc-integration-test/3235-add-juno.md new file mode 100644 index 0000000000..a9690c6974 --- /dev/null +++ b/.changelog/unreleased/improvements/ibc-integration-test/3235-add-juno.md @@ -0,0 +1,2 @@ +- Add Juno to chains tested in the integration tests + ([#3235](https://github.com/informalsystems/hermes/issues/3235)) \ No newline at end of file diff --git a/.changelog/unreleased/improvements/ibc-relayer/1541-config-keyring-store-directory.md b/.changelog/unreleased/improvements/ibc-relayer/1541-config-keyring-store-directory.md new file mode 100644 index 0000000000..74a58ed161 --- /dev/null +++ b/.changelog/unreleased/improvements/ibc-relayer/1541-config-keyring-store-directory.md @@ -0,0 +1,2 @@ +- Added a configuration to specify the directory used to the keyring store + ([#1541](https://github.com/informalsystems/hermes/issues/1541)) \ No newline at end of file diff --git a/.changelog/unreleased/improvements/ibc-relayer/3001-default-misbehaviour-detection-true.md b/.changelog/unreleased/improvements/ibc-relayer/3001-default-misbehaviour-detection-true.md new file mode 100644 index 0000000000..2462209e73 --- /dev/null +++ b/.changelog/unreleased/improvements/ibc-relayer/3001-default-misbehaviour-detection-true.md @@ -0,0 +1,2 @@ +- Enable misbehaviour detection by default. + ([#3001](https://github.com/informalsystems/hermes/issues/3001)) \ No newline at end of file diff --git a/.github/workflows/integration.yaml b/.github/workflows/integration.yaml index 2360158c4c..f9d6c42713 100644 --- a/.github/workflows/integration.yaml +++ b/.github/workflows/integration.yaml @@ -75,6 +75,9 @@ jobs: - package: stride command: strided account_prefix: stride + - package: juno + command: junod + account_prefix: juno steps: - uses: actions/checkout@v2 @@ -233,6 +236,9 @@ jobs: - package: gaia9 command: gaiad account_prefix: cosmos + - package: juno + command: junod + account_prefix: juno steps: - uses: actions/checkout@v2 - uses: cachix/install-nix-action@v15 diff --git a/.github/workflows/multi-chains.yaml b/.github/workflows/multi-chains.yaml index bfae44da1c..d1e49eb72b 100644 --- a/.github/workflows/multi-chains.yaml +++ b/.github/workflows/multi-chains.yaml @@ -59,42 +59,27 @@ jobs: matrix: first-package: - package: gaia9 - chain_command_path: gaiad + command: gaiad account_prefix: cosmos - package: ibc-go-v7-simapp - chain_command_path: simd + command: simd account_prefix: cosmos - package: wasmd - chain_command_path: wasmd + command: wasmd account_prefix: wasm - - package: evmos - chain_command_path: evmosd - account_prefix: evmos - - package: osmosis - chain_command_path: osmosisd - account_prefix: osmo - - package: stride - chain_command_path: strided - account_prefix: stride second-package: - - package: gaia9 - chain_command_path: gaiad - account_prefix: cosmos - - package: ibc-go-v7-simapp - chain_command_path: simd - account_prefix: cosmos - - package: wasmd - chain_command_path: wasmd - account_prefix: wasm - package: evmos - chain_command_path: evmosd + command: evmosd account_prefix: evmos - package: osmosis - chain_command_path: osmosisd + command: osmosisd account_prefix: osmo - package: stride - chain_command_path: strided + command: strided account_prefix: stride + - package: juno + command: junod + account_prefix: juno steps: - uses: actions/checkout@v2 @@ -126,7 +111,7 @@ jobs: max_attempts: 2 timeout_minutes: 60 command: | - CHAIN_COMMAND_PATHS=$(nix shell .#${{ matrix.first-package.package }} -c which ${{ matrix.first-package.chain_command_path }}),$(nix shell .#${{ matrix.second-package.package }} -c which ${{ matrix.second-package.chain_command_path }}) \ + CHAIN_COMMAND_PATHS=$(nix shell .#${{ matrix.first-package.package }} -c which ${{ matrix.first-package.command }}),$(nix shell .#${{ matrix.second-package.package }} -c which ${{ matrix.second-package.command }}) \ nix shell .#python -c cargo \ test -p ibc-integration-test --no-fail-fast -- \ --nocapture --test-threads=2 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c32aa32049..53af715a2c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,19 +1,23 @@ # Contributing -Thank you for your interest in contributing! The goal -of ibc-rs is to provide a high quality, formally verified implementation of -the IBC protocol and relayer. +Thank you for your interest in contributing to the Hermes IBC relayer! The goal +of this project is to provide a high quality, formally verified IBC relayer +implementation in Rust. All work on the code base should be motivated by a Github issue. Before opening a new issue, first do a search of open and closed issues to make sure that yours will not be a duplicate. If you would like to work on an issue which already exists, please indicate so -by leaving a comment. If what you'd like to work on hasn't already been covered -by an issue, then open a new one to get the process going. +by leaving a comment on the issue. If what you'd like to work on hasn't already +been covered by an issue, then open a new one to get the process going. Please +do your best to ensure that your issue adheres to one of the +[issue templates](https://github.com/informalsystems/hermes/tree/master/.github/ISSUE_TEMPLATE) +that we have in the repository. The rest of this document outlines the best practices for contributing to this repository: +- [Core Team Responsibility](#responsibility) - what the core team is responsible for - [Decision Making](#decision-making) - process for agreeing to changes - [Issues](#issues) - what makes a good issue - [Pull Requests](#pull-requests) - what makes a good pull request @@ -21,6 +25,14 @@ repository: - [Changelog](#changelog) - changes must be recorded in the changelog - [Releases](#releases) - how to release new version of the crates +## Core Team Responsibility + +The Hermes core team is responsible for stewarding this project over time. This means that the core team needs to understand the nature of, and agree to maintain, all of the changes that land on the master branch. It may cost a few days or weeks' worth of time to submit a particular change, but maintaining that change over the years has a much higher cost that the core team is responsible for bearing. + +With that in mind, the core team must balance the potential risks of maintaining +any contribution in the long-term against the immediate usefulness or utility +that that contribution manifests. + ## Decision Making When contributing to the project, the following process leads to the best chance of @@ -101,30 +113,31 @@ explaining why, and we will reprioritize it! ## Pull Requests -If you have write access to the ibc-rs repo, you can directly branch off of `master`. +If you have write access to the Hermes repo, you can directly branch off of `master`. This makes it easier for project maintainers to directly make changes to your -branch should the need arise. Otherwise, check [Forking](#forking) section for instructions. - -Branch names should be prefixed with the author's name followed by a short description -of the feature, eg. `name/feature-x`. +branch should the need arise. Otherwise, check the [Forking](#forking) section for instructions. -Pull requests are made against `master` and are squash-merged into master. - -PRs must: +Branch names should be prefixed with the author's name followed by a short description of the feature, eg. `name/feature-x`. +Pull requests are made against `master` and are squash-merged into master. Each +PR should: - make reference to an issue outlining the context - update any relevant documentation and include tests - add a corresponding entry in the `.changelog` directory using `unclog`, see the [Changelog](#changelog) section for more details. -Pull requests should aim to be small and self-contained to facilitate quick -review and merging. Larger change sets should be broken up across multiple PRs. -Commits should be concise but informative, and moderately clean. Commits will be squashed into a -single commit for the PR with all the commit messages. +Additionally, in order to make PRs as easy to review as possible, each PR should: +- Be focused on implementing _*one*_ piece of logic from end-to-end. It must be +very clear what the purpose of the PR is from looking at the PR's title, description, and/or linked issue(s). It should also be very clear what value the changes incorporated in the PR aim to deliver. A single PR that does multiple things, without a clear articulation of the problem it attempts to solve, will very likely be rejected. +- Be small, ideally no more than 500 lines of code changes. While this is a guideline and not a hard rule, in general, larger changes should be structured as a series of PRs, each building off of the previous ones; these PRs should also be tracked in a tracking issue. + + If a single PR absolutely has to be larger, it _must_ be structured such that it can be reviewed commit-by-commit, with each commit doing a single logical thing, accompanied with a good description of what it aims to achieve in the git commit message. Poorly structured PRs will likely be rejected on the grounds of being too much of a burden for the core maintainers to review; you will be asked to restructure the PR in accordance with the guidelines laid out here. + + This does not necessarily apply to documentation-related changes or automatically generated code (e.g. generated from Protobuf definitions). But automatically generated code changes should occur within separate commits, so they are easily distinguishable from manual code changes. In order to help facilitate the PR review process, tag *one* person as the reviewer of the PR. If you are unsure of who to tag, your point of contact on -the ibc-rs team is always a natural candidate; they'll make sure that the PR gets +the Hermes team is always a natural candidate; they'll make sure that the PR gets reviewed by whomever is most appropriate to review it. It also helps to notify the person whom you tagged as reviewer through direct means, such as through Slack or Discord, as it is easy for GitHub notifications to get lost or buried. @@ -216,7 +229,7 @@ and [Hashicorp Consul](http://github.com/hashicorp/consul/tree/master/CHANGELOG. See those changelogs for examples. We currently split changes for a given release between these four sections: Breaking -Changes, Features, Improvements, Bug Fixes. +Changes, Features, Improvements, and Bug Fixes. Entries in the changelog should initially be logged in the __Unreleased__ section, which represents a "staging area" for accumulating all the changes throughout a @@ -272,16 +285,15 @@ Our release process is as follows: 2. All crates' `lib.rs` files documentation references' `html_root_url` parameters must point to the new version. 3. Every reference to Hermes version in the [guide](./guide). - 4. Run `cargo doc --all-features --open` locally to double-check that all the - documentation compiles and seems up-to-date and coherent. Fix any potential + documentation compiles and is up-to-date and coherent. Fix any potential issues here and push them to the release PR. 5. Mark the PR as **Ready for Review** and incorporate feedback on the release. 6. Once approved, merge the PR. 7. Pull `master` and run the [`release.sh`](./scripts/release.sh) script. If any problem arises, submit a new PR, get it merged to `master` and try again. The reason for not releasing straight from the release branch, and therefore losing the - ability to fix publishing problems as they arise, is that we would like the embedded + ability to fix publishing-related problems as they arise, is that we would like the embedded metadata of the published crates, namely the Git commit at which the release was done, to match the Git commit on the `master` branch which will be tagged. [See this article][crates.io-security] for a more in-depth explanation. diff --git a/Cargo.lock b/Cargo.lock index 1e791e947a..7b2a66908f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,7 +21,7 @@ dependencies = [ "semver", "serde", "termcolor", - "toml", + "toml 0.5.11", "tracing", "tracing-log", "tracing-subscriber", @@ -1425,9 +1425,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be7b54589b581f624f566bf5d8eb2bab1db736c51528720b6bd36b96b55924d" +checksum = "66b91535aa35fea1523ad1b86cb6b53c28e0ae566ba4a460f4457e936cad7c6f" dependencies = [ "bytes", "fnv", @@ -1758,7 +1758,7 @@ dependencies = [ "serde_json", "tempfile", "time", - "toml", + "toml 0.7.3", "tonic", ] @@ -1834,7 +1834,7 @@ dependencies = [ "tiny-bip39", "tiny-keccak", "tokio", - "toml", + "toml 0.7.3", "tonic", "tracing", "tracing-subscriber", @@ -1892,7 +1892,7 @@ dependencies = [ "reqwest", "serde", "tokio", - "toml", + "toml 0.7.3", "tracing", ] @@ -1973,7 +1973,7 @@ dependencies = [ "subtle-encoding", "tendermint-rpc", "tokio", - "toml", + "toml 0.7.3", "tonic", "tracing", "tracing-subscriber", @@ -1981,9 +1981,9 @@ dependencies = [ [[package]] name = "ics23" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca44b684ce1859cff746ff46f5765ab72e12e3c06f76a8356db8f9a2ecf43f17" +checksum = "352b6bbf6a07602cf8def05362987835a255d3312eae59c1af358af3ac57e0cc" dependencies = [ "anyhow", "bytes", @@ -2289,7 +2289,7 @@ dependencies = [ "shlex", "tempfile", "tokio", - "toml", + "toml 0.5.11", "topological-sort", "warp", ] @@ -3570,6 +3570,15 @@ dependencies = [ "syn 2.0.13", ] +[[package]] +name = "serde_spanned" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0efd8caf556a6cebd3b285caf480045fcc1ac04f6bd786b09a6f11af30c4fcf4" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -3968,7 +3977,7 @@ dependencies = [ "serde", "serde_json", "tendermint", - "toml", + "toml 0.5.11", "url", ] @@ -4360,6 +4369,40 @@ dependencies = [ "serde", ] +[[package]] +name = "toml" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b403acf6f2bb0859c93c7f0d967cb4a75a7ac552100f9322faf64dc047669b21" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "tonic" version = "0.9.1" @@ -5055,6 +5098,15 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +[[package]] +name = "winnow" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae8970b36c66498d8ff1d66685dc86b91b29db0c7739899012f63a63814b4b28" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.10.1" diff --git a/config.toml b/config.toml index 3bdd994323..6bd018af15 100644 --- a/config.toml +++ b/config.toml @@ -23,7 +23,7 @@ enabled = true # there is activity on a connection or channel they are involved with. refresh = true -# Whether or not to enable misbehaviour detection for clients. [Default: false] +# Whether or not to enable misbehaviour detection for clients. [Default: true] misbehaviour = true # Specify the connections mode. @@ -140,6 +140,10 @@ account_prefix = 'cosmos' # https://hermes.informal.systems/commands/keys/index.html#adding-keys key_name = 'testkey' +# Specify the folder used to store the keys. Optional +# If this is not specified then the hermes home folder is used. +# key_store_folder = '$HOME/.hermes/keys' + # Specify the address type which determines: # 1) address derivation; # 2) how to retrieve and decode accounts and pubkeys; diff --git a/crates/relayer-cli/src/chain_registry.rs b/crates/relayer-cli/src/chain_registry.rs index ef0165cfa4..922d48aa9c 100644 --- a/crates/relayer-cli/src/chain_registry.rs +++ b/crates/relayer-cli/src/chain_registry.rs @@ -116,6 +116,7 @@ where account_prefix: chain_data.bech32_prefix, key_name: String::new(), key_store_type: Store::default(), + key_store_folder: None, store_prefix: "ibc".to_string(), default_gas: Some(100000), max_gas: Some(400000), diff --git a/crates/relayer-cli/src/commands/create/channel.rs b/crates/relayer-cli/src/commands/create/channel.rs index 40b339d76f..3de03a257a 100644 --- a/crates/relayer-cli/src/commands/create/channel.rs +++ b/crates/relayer-cli/src/commands/create/channel.rs @@ -13,7 +13,7 @@ use ibc_relayer::connection::Connection; use ibc_relayer::foreign_client::ForeignClient; use ibc_relayer_types::core::ics02_client::client_state::ClientState; use ibc_relayer_types::core::ics03_connection::connection::IdentifiedConnectionEnd; -use ibc_relayer_types::core::ics04_channel::channel::Order; +use ibc_relayer_types::core::ics04_channel::channel::Ordering; use ibc_relayer_types::core::ics04_channel::version::Version; use ibc_relayer_types::core::ics24_host::identifier::{ChainId, ConnectionId, PortId}; @@ -106,7 +106,7 @@ pub struct CreateChannelCommand { help = "The channel ordering, valid options 'unordered' (default) and 'ordered'", default_value_t )] - order: Order, + order: Ordering, #[clap( long = "channel-version", @@ -275,7 +275,7 @@ mod tests { use super::CreateChannelCommand; use abscissa_core::clap::Parser; - use ibc_relayer_types::core::ics04_channel::channel::Order; + use ibc_relayer_types::core::ics04_channel::channel::Ordering; use ibc_relayer_types::core::ics04_channel::version::Version; use ibc_relayer_types::core::ics24_host::identifier::{ChainId, ConnectionId, PortId}; @@ -288,7 +288,7 @@ mod tests { connection_a: Some(ConnectionId::from_str("connection_a").unwrap()), port_a: PortId::from_str("port_id_a").unwrap(), port_b: PortId::from_str("port_id_b").unwrap(), - order: Order::Unordered, + order: Ordering::Unordered, version: None, new_client_connection: false, yes: false @@ -316,7 +316,7 @@ mod tests { connection_a: Some(ConnectionId::from_str("connection_a").unwrap()), port_a: PortId::from_str("port_id_a").unwrap(), port_b: PortId::from_str("port_id_b").unwrap(), - order: Order::Unordered, + order: Ordering::Unordered, version: Some(Version::new("v1".to_owned())), new_client_connection: false, yes: false @@ -346,7 +346,7 @@ mod tests { connection_a: Some(ConnectionId::from_str("connection_a").unwrap()), port_a: PortId::from_str("port_id_a").unwrap(), port_b: PortId::from_str("port_id_b").unwrap(), - order: Order::Ordered, + order: Ordering::Ordered, version: None, new_client_connection: false, yes: false @@ -376,7 +376,7 @@ mod tests { connection_a: Some(ConnectionId::from_str("connection_a").unwrap()), port_a: PortId::from_str("port_id_a").unwrap(), port_b: PortId::from_str("port_id_b").unwrap(), - order: Order::Unordered, + order: Ordering::Unordered, version: None, new_client_connection: false, yes: false @@ -462,7 +462,7 @@ mod tests { connection_a: None, port_a: PortId::from_str("port_id_a").unwrap(), port_b: PortId::from_str("port_id_b").unwrap(), - order: Order::Unordered, + order: Ordering::Unordered, version: None, new_client_connection: true, yes: false @@ -491,7 +491,7 @@ mod tests { connection_a: None, port_a: PortId::from_str("port_id_a").unwrap(), port_b: PortId::from_str("port_id_b").unwrap(), - order: Order::Unordered, + order: Ordering::Unordered, version: None, new_client_connection: true, yes: true @@ -521,7 +521,7 @@ mod tests { connection_a: None, port_a: PortId::from_str("port_id_a").unwrap(), port_b: PortId::from_str("port_id_b").unwrap(), - order: Order::Unordered, + order: Ordering::Unordered, version: None, new_client_connection: true, yes: false diff --git a/crates/relayer-cli/src/commands/keys/add.rs b/crates/relayer-cli/src/commands/keys/add.rs index 5b876ece26..fb3e063c35 100644 --- a/crates/relayer-cli/src/commands/keys/add.rs +++ b/crates/relayer-cli/src/commands/keys/add.rs @@ -200,8 +200,12 @@ pub fn add_key( ) -> eyre::Result { let key_pair = match config.r#type { ChainType::CosmosSdk => { - let mut keyring = - KeyRing::new_secp256k1(Store::Test, &config.account_prefix, &config.id)?; + let mut keyring = KeyRing::new_secp256k1( + Store::Test, + &config.account_prefix, + &config.id, + &config.key_store_folder, + )?; check_key_exists(&keyring, key_name, overwrite); @@ -229,8 +233,12 @@ pub fn restore_key( let key_pair = match config.r#type { ChainType::CosmosSdk => { - let mut keyring = - KeyRing::new_secp256k1(Store::Test, &config.account_prefix, &config.id)?; + let mut keyring = KeyRing::new_secp256k1( + Store::Test, + &config.account_prefix, + &config.id, + &config.key_store_folder, + )?; check_key_exists(&keyring, key_name, overwrite); diff --git a/crates/relayer-cli/src/commands/keys/delete.rs b/crates/relayer-cli/src/commands/keys/delete.rs index b27e5ee19f..fdc892afa9 100644 --- a/crates/relayer-cli/src/commands/keys/delete.rs +++ b/crates/relayer-cli/src/commands/keys/delete.rs @@ -115,8 +115,12 @@ impl Runnable for KeysDeleteCmd { pub fn delete_key(config: &ChainConfig, key_name: &str) -> eyre::Result<()> { match config.r#type { ChainType::CosmosSdk => { - let mut keyring = - KeyRing::new_secp256k1(Store::Test, &config.account_prefix, &config.id)?; + let mut keyring = KeyRing::new_secp256k1( + Store::Test, + &config.account_prefix, + &config.id, + &config.key_store_folder, + )?; keyring.remove_key(key_name)?; } } @@ -126,8 +130,12 @@ pub fn delete_key(config: &ChainConfig, key_name: &str) -> eyre::Result<()> { pub fn delete_all_keys(config: &ChainConfig) -> eyre::Result<()> { match config.r#type { ChainType::CosmosSdk => { - let mut keyring = - KeyRing::new_secp256k1(Store::Test, &config.account_prefix, &config.id)?; + let mut keyring = KeyRing::new_secp256k1( + Store::Test, + &config.account_prefix, + &config.id, + &config.key_store_folder, + )?; let keys = keyring.keys()?; for (key_name, _) in keys { keyring.remove_key(&key_name)?; diff --git a/crates/relayer-cli/src/commands/tx/channel.rs b/crates/relayer-cli/src/commands/tx/channel.rs index 18ee4d2565..c4950ac816 100644 --- a/crates/relayer-cli/src/commands/tx/channel.rs +++ b/crates/relayer-cli/src/commands/tx/channel.rs @@ -5,7 +5,7 @@ use ibc_relayer::chain::handle::ChainHandle; use ibc_relayer::chain::requests::{IncludeProof, QueryConnectionRequest, QueryHeight}; use ibc_relayer::channel::{Channel, ChannelSide}; use ibc_relayer_types::core::ics03_connection::connection::ConnectionEnd; -use ibc_relayer_types::core::ics04_channel::channel::Order; +use ibc_relayer_types::core::ics04_channel::channel::Ordering; use ibc_relayer_types::core::ics24_host::identifier::{ ChainId, ChannelId, ClientId, ConnectionId, PortId, }; @@ -105,7 +105,7 @@ pub struct TxChanOpenInitCmd { value_name = "ORDER", help = "The channel ordering, valid options 'unordered' (default) and 'ordered'" )] - order: Order, + order: Ordering, } impl Runnable for TxChanOpenInitCmd { @@ -239,7 +239,7 @@ impl Runnable for TxChanOpenTryCmd { |chains: ChainHandlePair, dst_connection: ConnectionEnd| { Channel { connection_delay: Default::default(), - ordering: Order::default(), + ordering: Ordering::default(), a_side: ChannelSide::new( chains.src, ClientId::default(), @@ -340,7 +340,7 @@ impl Runnable for TxChanOpenAckCmd { |chains: ChainHandlePair, dst_connection: ConnectionEnd| { Channel { connection_delay: Default::default(), - ordering: Order::default(), + ordering: Ordering::default(), a_side: ChannelSide::new( chains.src, ClientId::default(), @@ -441,7 +441,7 @@ impl Runnable for TxChanOpenConfirmCmd { |chains: ChainHandlePair, dst_connection: ConnectionEnd| { Channel { connection_delay: Default::default(), - ordering: Order::default(), + ordering: Ordering::default(), a_side: ChannelSide::new( chains.src, ClientId::default(), @@ -542,7 +542,7 @@ impl Runnable for TxChanCloseInitCmd { |chains: ChainHandlePair, dst_connection: ConnectionEnd| { Channel { connection_delay: Default::default(), - ordering: Order::default(), + ordering: Ordering::default(), a_side: ChannelSide::new( chains.src, ClientId::default(), @@ -643,7 +643,7 @@ impl Runnable for TxChanCloseConfirmCmd { |chains: ChainHandlePair, dst_connection: ConnectionEnd| { Channel { connection_delay: Default::default(), - ordering: Order::default(), + ordering: Ordering::default(), a_side: ChannelSide::new( chains.src, ClientId::default(), @@ -677,7 +677,7 @@ mod tests { use abscissa_core::clap::Parser; use ibc_relayer_types::core::{ - ics04_channel::channel::Order, + ics04_channel::channel::Ordering, ics24_host::identifier::{ChainId, ChannelId, ConnectionId, PortId}, }; @@ -690,7 +690,7 @@ mod tests { dst_conn_id: ConnectionId::from_str("connection_b").unwrap(), dst_port_id: PortId::from_str("port_b").unwrap(), src_port_id: PortId::from_str("port_a").unwrap(), - order: Order::Unordered + order: Ordering::Unordered }, TxChanOpenInitCmd::parse_from([ "test", @@ -717,7 +717,7 @@ mod tests { dst_conn_id: ConnectionId::from_str("connection_b").unwrap(), dst_port_id: PortId::from_str("port_b").unwrap(), src_port_id: PortId::from_str("port_a").unwrap(), - order: Order::Ordered + order: Ordering::Ordered }, TxChanOpenInitCmd::parse_from([ "test", @@ -746,7 +746,7 @@ mod tests { dst_conn_id: ConnectionId::from_str("connection_b").unwrap(), dst_port_id: PortId::from_str("port_b").unwrap(), src_port_id: PortId::from_str("port_a").unwrap(), - order: Order::Unordered + order: Ordering::Unordered }, TxChanOpenInitCmd::parse_from([ "test", diff --git a/crates/relayer-rest/Cargo.toml b/crates/relayer-rest/Cargo.toml index 1be9d38dd2..f57509bdf6 100644 --- a/crates/relayer-rest/Cargo.toml +++ b/crates/relayer-rest/Cargo.toml @@ -25,4 +25,4 @@ tokio = "1.26" [dev-dependencies] reqwest = { version = "0.11.16", features = ["json"], default-features = false } -toml = "0.5.10" +toml = "0.7.3" diff --git a/crates/relayer-types/Cargo.toml b/crates/relayer-types/Cargo.toml index 768362dd54..d7a3bd6488 100644 --- a/crates/relayer-types/Cargo.toml +++ b/crates/relayer-types/Cargo.toml @@ -27,8 +27,8 @@ mocks = ["tendermint-testgen", "clock", "std"] [dependencies] # Proto definitions for all IBC-related interfaces, e.g., connections or channels. -ibc-proto = { version = "0.30.0", default-features = false } -ics23 = { version = "=0.9.0", default-features = false, features = ["host-functions"] } +ibc-proto = { version = "0.29.0", default-features = false } +ics23 = { version = "0.10.0", default-features = false, features = ["host-functions"] } time = { version = ">=0.3.0, <0.3.21", default-features = false } serde_derive = { version = "1.0.104", default-features = false } serde = { version = "1.0", default-features = false } diff --git a/crates/relayer-types/src/applications/transfer/error.rs b/crates/relayer-types/src/applications/transfer/error.rs index 81571b0449..aad0522a3e 100644 --- a/crates/relayer-types/src/applications/transfer/error.rs +++ b/crates/relayer-types/src/applications/transfer/error.rs @@ -6,7 +6,7 @@ use ibc_proto::protobuf::Error as TendermintProtoError; use subtle_encoding::Error as EncodingError; use uint::FromDecStrErr; -use crate::core::ics04_channel::channel::Order; +use crate::core::ics04_channel::channel::Ordering; use crate::core::ics04_channel::error as channel_error; use crate::core::ics04_channel::version::Version; use crate::core::ics24_host::error::ValidationError; @@ -90,8 +90,8 @@ define_error! { | _ | { "invalid hex string" }, ChannelNotUnordered - { order: Order } - | e | { format_args!("expected '{0}' channel, got '{1}'", Order::Unordered, e.order) }, + { order: Ordering } + | e | { format_args!("expected '{0}' channel, got '{1}'", Ordering::Unordered, e.order) }, InvalidVersion { version: Version } diff --git a/crates/relayer-types/src/core/ics03_connection/version.rs b/crates/relayer-types/src/core/ics03_connection/version.rs index 4109aade31..a3123afa32 100644 --- a/crates/relayer-types/src/core/ics03_connection/version.rs +++ b/crates/relayer-types/src/core/ics03_connection/version.rs @@ -8,7 +8,7 @@ use ibc_proto::protobuf::Protobuf; use serde::{Deserialize, Serialize}; use crate::core::ics03_connection::error::Error; -use crate::core::ics04_channel::channel::Order; +use crate::core::ics04_channel::channel::Ordering; /// Stores the identifier and the features supported by a version #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] @@ -60,8 +60,8 @@ impl Default for Version { Version { identifier: "1".to_string(), features: vec![ - Order::Ordered.as_str().to_owned(), - Order::Unordered.as_str().to_owned(), + Ordering::Ordered.as_str().to_owned(), + Ordering::Unordered.as_str().to_owned(), ], } } diff --git a/crates/relayer-types/src/core/ics04_channel/channel.rs b/crates/relayer-types/src/core/ics04_channel/channel.rs index 8b675e1c51..b1f7b2162e 100644 --- a/crates/relayer-types/src/core/ics04_channel/channel.rs +++ b/crates/relayer-types/src/core/ics04_channel/channel.rs @@ -76,7 +76,7 @@ impl From for RawIdentifiedChannel { #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct ChannelEnd { pub state: State, - pub ordering: Order, + pub ordering: Ordering, pub remote: Counterparty, pub connection_hops: Vec, pub version: Version, @@ -116,7 +116,7 @@ impl TryFrom for ChannelEnd { return Ok(ChannelEnd::default()); } - let chan_ordering = Order::from_i32(value.ordering)?; + let chan_ordering = Ordering::from_i32(value.ordering)?; // Assemble the 'remote' attribute of the Channel, which represents the Counterparty. let remote = value @@ -164,7 +164,7 @@ impl ChannelEnd { /// Creates a new ChannelEnd in state Uninitialized and other fields parametrized. pub fn new( state: State, - ordering: Order, + ordering: Ordering, remote: Counterparty, connection_hops: Vec, version: Version, @@ -200,7 +200,7 @@ impl ChannelEnd { &self.state } - pub fn ordering(&self) -> &Order { + pub fn ordering(&self) -> &Ordering { &self.ordering } @@ -232,7 +232,7 @@ impl ChannelEnd { } /// Helper function to compare the order of this end with another order. - pub fn order_matches(&self, other: &Order) -> bool { + pub fn order_matches(&self, other: &Ordering) -> bool { self.ordering.eq(other) } @@ -324,24 +324,24 @@ impl From for RawCounterparty { } #[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize, Default)] -pub enum Order { - None = 0, +pub enum Ordering { + Uninitialized = 0, #[default] Unordered = 1, Ordered = 2, } -impl Display for Order { +impl Display for Ordering { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { write!(f, "{}", self.as_str()) } } -impl Order { +impl Ordering { /// Yields the Order as a string pub fn as_str(&self) -> &'static str { match self { - Self::None => "UNINITIALIZED", + Self::Uninitialized => "UNINITIALIZED", Self::Unordered => "ORDER_UNORDERED", Self::Ordered => "ORDER_ORDERED", } @@ -350,20 +350,21 @@ impl Order { // Parses the Order out from a i32. pub fn from_i32(nr: i32) -> Result { match nr { - 0 => Ok(Self::None), + 0 => Ok(Self::Uninitialized), 1 => Ok(Self::Unordered), 2 => Ok(Self::Ordered), + _ => Err(Error::unknown_order_type(nr.to_string())), } } } -impl FromStr for Order { +impl FromStr for Ordering { type Err = Error; fn from_str(s: &str) -> Result { match s.to_lowercase().trim_start_matches("order_") { - "uninitialized" => Ok(Self::None), + "uninitialized" => Ok(Self::Uninitialized), "unordered" => Ok(Self::Unordered), "ordered" => Ok(Self::Ordered), _ => Err(Error::unknown_order_type(s.to_string())), @@ -566,45 +567,37 @@ mod tests { #[test] fn parse_channel_ordering_type() { - use super::Order; + use super::Ordering; struct Test { ordering: &'static str, - want_res: Order, - want_err: bool, + want_res: Option, } let tests: Vec = vec![ Test { ordering: "UNINITIALIZED", - want_res: Order::None, - want_err: false, + want_res: Some(Ordering::Uninitialized), }, Test { ordering: "UNORDERED", - want_res: Order::Unordered, - want_err: false, + want_res: Some(Ordering::Unordered), }, Test { ordering: "ORDERED", - want_res: Order::Ordered, - want_err: false, + want_res: Some(Ordering::Ordered), }, Test { ordering: "UNKNOWN_ORDER", - want_res: Order::None, - want_err: true, + want_res: None, }, ] .into_iter() .collect(); for test in tests { - match Order::from_str(test.ordering) { - Ok(res) => { - assert!(!test.want_err); - assert_eq!(test.want_res, res); - } - Err(_) => assert!(test.want_err, "parse failed"), + match Ordering::from_str(test.ordering) { + Ok(res) => assert_eq!(test.want_res, Some(res)), + Err(_) => assert!(test.want_res.is_none(), "parse failed"), } } } diff --git a/crates/relayer-types/src/core/ics23_commitment/merkle.rs b/crates/relayer-types/src/core/ics23_commitment/merkle.rs index bb9683d424..365b0e5554 100644 --- a/crates/relayer-types/src/core/ics23_commitment/merkle.rs +++ b/crates/relayer-types/src/core/ics23_commitment/merkle.rs @@ -28,7 +28,7 @@ impl From for MerkleRoot { } } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq)] pub struct MerkleProof { pub proofs: Vec, } diff --git a/crates/relayer-types/src/core/ics23_commitment/specs.rs b/crates/relayer-types/src/core/ics23_commitment/specs.rs index 53e45a5912..afbcb77bf3 100644 --- a/crates/relayer-types/src/core/ics23_commitment/specs.rs +++ b/crates/relayer-types/src/core/ics23_commitment/specs.rs @@ -80,11 +80,13 @@ impl From for ProofSpec { impl From for Ics23ProofSpec { fn from(spec: ProofSpec) -> Self { let spec = spec.0; + Ics23ProofSpec { leaf_spec: spec.leaf_spec.map(|lop| LeafOp(lop).into()), inner_spec: spec.inner_spec.map(|ispec| InnerSpec(ispec).into()), max_depth: spec.max_depth, min_depth: spec.min_depth, + prehash_key_before_comparison: false, } } } diff --git a/crates/relayer/Cargo.toml b/crates/relayer/Cargo.toml index c67bf7b5db..eed540f979 100644 --- a/crates/relayer/Cargo.toml +++ b/crates/relayer/Cargo.toml @@ -30,7 +30,7 @@ humantime-serde = "1.1.1" serde = "1.0" serde_derive = "1.0" thiserror = "1.0.40" -toml = "0.5" +toml = "0.7" tracing = "0.1.36" tokio = { version = "1.0", features = ["rt-multi-thread", "time", "sync"] } serde_json = { version = "1" } diff --git a/crates/relayer/src/chain/cosmos.rs b/crates/relayer/src/chain/cosmos.rs index ed3d9a7fee..bdfeedac7b 100644 --- a/crates/relayer/src/chain/cosmos.rs +++ b/crates/relayer/src/chain/cosmos.rs @@ -773,9 +773,13 @@ impl ChainEndpoint for CosmosSdkChain { let light_client = TmLightClient::from_config(&config, node_info.id)?; // Initialize key store and load key - let keybase = - KeyRing::new_secp256k1(config.key_store_type, &config.account_prefix, &config.id) - .map_err(Error::key_base)?; + let keybase = KeyRing::new_secp256k1( + config.key_store_type, + &config.account_prefix, + &config.id, + &config.key_store_folder, + ) + .map_err(Error::key_base)?; let grpc_addr = Uri::from_str(&config.grpc_addr.to_string()) .map_err(|e| Error::invalid_uri(config.grpc_addr.to_string(), e))?; diff --git a/crates/relayer/src/chain/cosmos/batch.rs b/crates/relayer/src/chain/cosmos/batch.rs index f1c60c1f30..f4eb7ad01f 100644 --- a/crates/relayer/src/chain/cosmos/batch.rs +++ b/crates/relayer/src/chain/cosmos/batch.rs @@ -339,7 +339,13 @@ mod tests { "/tests/config/fixtures/relayer-seed.json" ); let seed_file_content = fs::read_to_string(path).unwrap(); - let _keyring = KeyRing::new_secp256k1(keyring::Store::Memory, "cosmos", &chain_id).unwrap(); + let _keyring = KeyRing::new_secp256k1( + keyring::Store::Memory, + "cosmos", + &chain_id, + &chain_config.key_store_folder, + ) + .unwrap(); let hd_path = COSMOS_HD_PATH.parse().unwrap(); let key_pair = Secp256k1KeyPair::from_seed_file(&seed_file_content, &hd_path).unwrap(); diff --git a/crates/relayer/src/chain/cosmos/query.rs b/crates/relayer/src/chain/cosmos/query.rs index ebb67e3d82..4869056b7b 100644 --- a/crates/relayer/src/chain/cosmos/query.rs +++ b/crates/relayer/src/chain/cosmos/query.rs @@ -24,7 +24,7 @@ pub mod status; pub mod tx; /// Generic query response type -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq)] pub struct QueryResponse { pub value: Vec, pub proof: Option, diff --git a/crates/relayer/src/channel.rs b/crates/relayer/src/channel.rs index c97d09ce34..84bce4470e 100644 --- a/crates/relayer/src/channel.rs +++ b/crates/relayer/src/channel.rs @@ -7,7 +7,7 @@ use tracing::{debug, error, info, warn}; pub use error::ChannelError; use ibc_relayer_types::core::ics04_channel::channel::{ - ChannelEnd, Counterparty, IdentifiedChannelEnd, Order, State, + ChannelEnd, Counterparty, IdentifiedChannelEnd, Ordering, State, }; use ibc_relayer_types::core::ics04_channel::msgs::chan_close_confirm::MsgChannelCloseConfirm; use ibc_relayer_types::core::ics04_channel::msgs::chan_close_init::MsgChannelCloseInit; @@ -164,7 +164,7 @@ impl ChannelSide { #[derive(Clone, Debug, Serialize)] #[serde(bound(serialize = "(): Serialize"))] pub struct Channel { - pub ordering: Order, + pub ordering: Ordering, pub a_side: ChannelSide, pub b_side: ChannelSide, pub connection_delay: Duration, @@ -188,7 +188,7 @@ impl Channel { /// set-up on both sides of the connection, this functions also fulfils the channel handshake. pub fn new( connection: Connection, - ordering: Order, + ordering: Ordering, a_port: PortId, b_port: PortId, version: Option, diff --git a/crates/relayer/src/config.rs b/crates/relayer/src/config.rs index 506481467d..3b000ec0a4 100644 --- a/crates/relayer/src/config.rs +++ b/crates/relayer/src/config.rs @@ -13,10 +13,12 @@ use core::{ str::FromStr, time::Duration, }; -use std::{fs, fs::File, io::Write, path::Path}; - -use serde_derive::{Deserialize, Serialize}; - +use std::{ + fs, + fs::File, + io::Write, + path::{Path, PathBuf}, +}; use tendermint::block::Height as BlockHeight; use tendermint_light_client::verifier::types::TrustThreshold; use tendermint_rpc::{Url, WebSocketClientUrl}; @@ -262,7 +264,7 @@ impl Default for ModeConfig { clients: Clients { enabled: true, refresh: true, - misbehaviour: false, + misbehaviour: true, }, connections: Connections { enabled: false }, channels: Channels { enabled: false }, @@ -449,6 +451,7 @@ pub struct ChainConfig { pub key_name: String, #[serde(default)] pub key_store_type: Store, + pub key_store_folder: Option, pub store_prefix: String, pub default_gas: Option, pub max_gas: Option, diff --git a/crates/relayer/src/keyring.rs b/crates/relayer/src/keyring.rs index 4949f20d03..b5967b24a7 100644 --- a/crates/relayer/src/keyring.rs +++ b/crates/relayer/src/keyring.rs @@ -16,7 +16,7 @@ mod signing_key_pair; use alloc::collections::btree_map::BTreeMap as HashMap; use std::ffi::OsStr; use std::fs::{self, File}; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use ibc_relayer_types::core::ics24_host::identifier::ChainId; use serde::{Deserialize, Serialize}; @@ -200,12 +200,17 @@ pub enum KeyRing { } impl KeyRing { - pub fn new(store: Store, account_prefix: &str, chain_id: &ChainId) -> Result { + pub fn new( + store: Store, + account_prefix: &str, + chain_id: &ChainId, + ks_folder: &Option, + ) -> Result { match store { Store::Memory => Ok(Self::Memory(Memory::new(account_prefix.to_string()))), Store::Test => { - let keys_folder = disk_store_path(chain_id.as_str())?; + let keys_folder = disk_store_path(chain_id.as_str(), ks_folder)?; // Create keys folder if it does not exist fs::create_dir_all(&keys_folder).map_err(|e| { @@ -265,8 +270,9 @@ impl KeyRing { store: Store, account_prefix: &str, chain_id: &ChainId, + ks_folder: &Option, ) -> Result { - Self::new(store, account_prefix, chain_id) + Self::new(store, account_prefix, chain_id, ks_folder) } } @@ -275,15 +281,21 @@ impl KeyRing { store: Store, account_prefix: &str, chain_id: &ChainId, + ks_folder: &Option, ) -> Result { - Self::new(store, account_prefix, chain_id) + Self::new(store, account_prefix, chain_id, ks_folder) } } pub fn list_keys(config: &ChainConfig) -> Result, Error> { let keys = match config.r#type { ChainType::CosmosSdk => { - let keyring = KeyRing::new_secp256k1(Store::Test, &config.account_prefix, &config.id)?; + let keyring = KeyRing::new_secp256k1( + Store::Test, + &config.account_prefix, + &config.id, + &config.key_store_folder, + )?; keyring .keys()? .into_iter() @@ -294,13 +306,16 @@ pub fn list_keys(config: &ChainConfig) -> Result Result { - let home = dirs_next::home_dir().ok_or_else(Error::home_location_unavailable)?; +fn disk_store_path(folder_name: &str, keystore_folder: &Option) -> Result { + let ks_folder = match keystore_folder { + Some(folder) => folder.to_owned(), + None => { + let home = dirs_next::home_dir().ok_or_else(Error::home_location_unavailable)?; + home.join(KEYSTORE_DEFAULT_FOLDER) + } + }; - let folder = Path::new(home.as_path()) - .join(KEYSTORE_DEFAULT_FOLDER) - .join(folder_name) - .join(KEYSTORE_DISK_BACKEND); + let folder = ks_folder.join(folder_name).join(KEYSTORE_DISK_BACKEND); Ok(folder) } diff --git a/crates/relayer/src/link/relay_path.rs b/crates/relayer/src/link/relay_path.rs index d0f56d77f0..de51f21908 100644 --- a/crates/relayer/src/link/relay_path.rs +++ b/crates/relayer/src/link/relay_path.rs @@ -8,7 +8,9 @@ use itertools::Itertools; use tracing::{debug, error, info, span, trace, warn, Level}; use ibc_relayer_types::core::ics02_client::events::ClientMisbehaviour as ClientMisbehaviourEvent; -use ibc_relayer_types::core::ics04_channel::channel::{ChannelEnd, Order, State as ChannelState}; +use ibc_relayer_types::core::ics04_channel::channel::{ + ChannelEnd, Ordering, State as ChannelState, +}; use ibc_relayer_types::core::ics04_channel::events::{SendPacket, WriteAcknowledgement}; use ibc_relayer_types::core::ics04_channel::msgs::{ acknowledgement::MsgAcknowledgement, chan_close_confirm::MsgChannelCloseConfirm, @@ -304,11 +306,11 @@ impl RelayPath { } fn unordered_channel(&self) -> bool { - self.channel.ordering == Order::Unordered + self.channel.ordering == Ordering::Unordered } fn ordered_channel(&self) -> bool { - self.channel.ordering == Order::Ordered + self.channel.ordering == Ordering::Ordered } pub fn build_update_client_on_dst(&self, height: Height) -> Result, LinkError> { diff --git a/crates/relayer/src/worker.rs b/crates/relayer/src/worker.rs index 04754ba8ed..571be7792a 100644 --- a/crates/relayer/src/worker.rs +++ b/crates/relayer/src/worker.rs @@ -1,6 +1,6 @@ use alloc::sync::Arc; use core::fmt::{Display, Error as FmtError, Formatter}; -use ibc_relayer_types::core::ics04_channel::channel::Order; +use ibc_relayer_types::core::ics04_channel::channel::Ordering; use serde::{Deserialize, Serialize}; use std::sync::Mutex; use tracing::error; @@ -126,7 +126,7 @@ pub fn spawn_worker_tasks( Ok(link) => { let channel_ordering = link.a_to_b.channel().ordering; let should_clear_on_start = - packets_config.clear_on_start || channel_ordering == Order::Ordered; + packets_config.clear_on_start || channel_ordering == Ordering::Ordered; let (cmd_tx, cmd_rx) = crossbeam_channel::unbounded(); let link = Arc::new(Mutex::new(link)); diff --git a/docs/spec/README.md b/docs/spec/README.md index 6adf6bb24d..420e352f92 100644 --- a/docs/spec/README.md +++ b/docs/spec/README.md @@ -1,7 +1,5 @@ # Specification and verification of IBC protocols * [tla](./tla) comprises TLA+ specification for the IBC specification. - - * [connection-handshake](./connection-handshake) [Deprecated] contains English and TLA+ specifications for the IBC Connection Handshake Protocol (ICS 003). - * [relayer](./relayer) contains English specification of the relayer. + * [connection-handshake](./connection-handshake) [Deprecated] contains English and TLA+ specifications for the IBC Connection Handshake Protocol (ICS 003). diff --git a/docs/spec/relayer/Data-Requirements.md b/docs/spec/relayer/Data-Requirements.md new file mode 100644 index 0000000000..328200f764 --- /dev/null +++ b/docs/spec/relayer/Data-Requirements.md @@ -0,0 +1,153 @@ +# Hermes IBC Relayer Data Requirements + +## Table of Contents + +- [CometBFT RPC](#cometbft-rpc) + * [`/health`](#--health-) + * [`/consensus_params`](#--consensus-params-) + * [`/status`](#--status-) + * [`/header`](#--header-) + * [`/abci_query`](#--abci-query-) + * [`/tx_search`](#--tx-search-) + * [`/block_search`](#--block-search-) + * [`/block_results`](#--block-results-) + * [`/broadcast_tx_sync`](#--broadcast-tx-sync-) +- [CometBFT WebSocket](#cometbft-websocket) + +## CometBFT RPC + +The following endpoints (or equivalent) are necessary for operating the relayer. +They are ordered from lowest to highest impact roughly, i.e., the first endpoint in the list is the least important and least frequently required. + +### `/health` + +- Needed for basic check to assess node health. +- Not needed for IBC relaying strictly speaking. +- Only used once, at relayer startup during health check. + +### `/consensus_params` + +- Needed for basic check to validate relayer configuration. +- Specifically, used for fetching `consensus_params.block.max_bytes` and `consensus_params.block.max_gas` parameters. +- Not needed for IBC relaying strictly speaking. +- Only used once, at relayer startup during health check. +- **Response fields used:** + - `block.max_bytes` + - `block.max_gas` + +### `/status` + +Used in two situations: + +1. At relayer startup to fetch `node_info.id`, for initializing the light client component. + - Also at startup to fetch `node_info.other.tx_index`, during health check. + - Also at startup to fetch `node_info.network`, i.e., the network identifier, during health check. + - Also at startup to assert that `sync_info.catching_up` is false, during health check. +2. To fetch `sync_info.latest_block_time` and `sync_info.latest_block_height` and `sync_info.catching_up` used in many methods, often alongside `node_info.network`, for example: + a. As a dependency, because the `latest_block_height` parameter is necessary in calling the `/consensus_params` RPC, during health check. + b. Needed in channel handshake (open try, ack, confirm; close confirm). + c. In connection handshake (open try, ack, confirm), for both the source chain (to update client), and destination chain (to construct proofs). Note: It seems like we bombard the node with /status queries, but most of the queries hit the Hermes in-process cache. + d. For updating clients during everyday IBC relaying. In case there is non-zero connection delay, we again bombard the node with /status queries. + +### `/header` + +- To pull the header in the latest block that the application committed, in order to compute the latest app height and app timestamp +- To get the a block header at a specific/latest height and extract the consensus state from it + +### `/abci_query` + +Used in two situations: +1. To obtain the client upgraded state, while the relayer is handling chain upgrades. +2. To construct proofs for every IBC message relayed. + - This method is used very frequently and is critical for IBC relaying! + - Does not seem to impact performance of relaying, i.e., this method does not seem particularly slow or problematic. + +> Note: We use `/header` and `/abci_query` together (see https://github.com/tendermint/tendermint/issues/8248) + +### `/tx_search` + +In four situations: + +1. Query to obtain transaction events, for confirming if packets are committed to the blockchain. + - Not needed on the critical path of packet relaying. Used very often as part of packet confirmation. + - Pattern: `tx.hash == XYZ` +2. Query to obtain client update events: (a) for the misbehavior detection task, and (b) for relaying packets on connections that have non-zero delay. + - Used rarely in practice because all connections have 0 delay and often misbehavior detection is disabled. + - Pattern: `update_client.client_id == 07-tendermint-X && update_client.consensus_height == X-Y` +3. Query for the success/error status of a transaction immediately after it was broadcast. + - Used rarely: at bootstrap (to register counterparty payee address for fees) or when transactions need to be sent sequentially (eg workaround for priority mempool or corner cases to avoid sequence mismatch). + - Pattern: `tx.hash == XYZ` +4. Query to obtain packet events that occurred at or before a specified height. Required because application state does not store the full packet data which is needed to build and relay the packet messages. + - Pattern: `send_packet.packet_src_channel == X && send_packet.packet_src_port == X && send_packet.packet_dst_channel == X && send_packet.packet_dst_port == X && send_packet.packet_sequence == X`. Also for `write_acknowledgement` packet events. + - Used relatively often, on start and then for every `z` blocks, where `clear_interval = z` (default `z = 100`). + +**Response fields used**: +- `txs[].height` +- `txs[].tx_result.events` + +### `/block_search` + +The use-case is similar to point (4) from `/tx_search`. We use it to obtain packet events from block data, used relatively often, on start and then for every `z` blocks, where `clear_interval = z` (default `z = 100`). + +#### Pattern +`send_packet.packet_src_channel == X && send_packet.packet_src_port == X && send_packet.packet_dst_channel == X && send_packet.packet_dst_port == X && send_packet.packet_sequence == X`. +Also for `write_acknowledgement` packet events. + +**Note:** Always used in conjunction with `block_results`. + The `block_search` is used to determine the `Block` that included a packet event. Then `block_search` is used with the block's height to extract the packet event. + +**Response fields used:** +- `blocks[].block.header.height` + +### `/block_results` + +Used in two situations ([diagram for reference](https://app.excalidraw.com/l/4XqkU6POmGI/9jbKsT6mHxf)): + +1. Similar to point (4) from `/tx_search`: Used In conjunction with `block_search` and `tx_search` for periodic packet clearing. + - Pattern: `/block_results?height=X` where X is a specific height, obtained with `block_results`, where a block has relevant packet events. Only `begin_block_events` and `end_block_events` are used in this case. +2. For CLIs `tx packet-recv` and `tx packet-ack` when the user passes the flag `--packet-data-query-height=X`. + +**Response fields used:** +- `begin_block_events` +- `end_block_events` +- `height` +- `tx_results[].events` + +### `/broadcast_tx_sync` + +- For submitting transactions into the mempool. + +__Note__: The above list is partly inspired from [cosmos-sdk/#11012](https://github.com/cosmos/cosmos-sdk/issues/11012) but extended and updated. + +## CometBFT WebSocket + +The relayer connects to the node's CometBFT websocket interface and subscribes to the following events: +- for events that have type `NewBlock` +- for events that have type `Tx` and are IBC client, connection, and channel, i.e., + - `message.module == "ibc_client"` + - `message.module == "ibc_connection"` + - `message.module == "ibc_channel"` +- eventually the relayer should avoid using the non-standard, ibc-go specific `message.module` key and instead use the following queries: + - `EXISTS create_client` + - `EXISTS update_client` + - `EXISTS client_misbehaviour` + - `EXISTS connection_open_init` + - `EXISTS connection_open_try` + - `EXISTS connection_open_ack` + - `EXISTS connection_open_confirm` + - `EXISTS channel_open_init` + - `EXISTS channel_open_try` + - `EXISTS channel_open_ack` + - `EXISTS channel_open_confirm` + - `EXISTS channel_close_init` + - `EXISTS channel_close_confirm` + - `EXISTS channel_upgrade_init` + - `EXISTS channel_upgrade_try` + - `EXISTS channel_upgrade_ack` + - `EXISTS channel_upgrade_confirm` + - `EXISTS send_packet` + - `EXISTS recv_packet` + - `EXISTS write_acknowledgement` + - `EXISTS acknowledge_packet` + - `EXISTS timeout_packet` + diff --git a/flake.lock b/flake.lock index c329a9719d..d05fcb0dcf 100644 --- a/flake.lock +++ b/flake.lock @@ -89,11 +89,11 @@ "wasmvm_1_beta7-src": "wasmvm_1_beta7-src" }, "locked": { - "lastModified": 1679572441, - "narHash": "sha256-CyA/MR9ZAf0VjcfOnIZR1vcpwLWRtDwFHZm5+5nQ4Tw=", + "lastModified": 1682517170, + "narHash": "sha256-ihtdPwOghbNsBpeqiN8H5KGzghh4qfoJLat4evfTo4o=", "owner": "informalsystems", "repo": "cosmos.nix", - "rev": "8e7042b2989bae0152288c9ed7fbba061c9617eb", + "rev": "853f16ea63d2b94e6c81c0f86b88f2c180f03f43", "type": "github" }, "original": { @@ -139,16 +139,16 @@ "evmos-src": { "flake": false, "locked": { - "lastModified": 1657722808, - "narHash": "sha256-WHo4DEaTwJXs3QGSGIRxqkaJFS6D96/zyXVmkaH867s=", + "lastModified": 1666728289, + "narHash": "sha256-hMry1q+31jqSe0krg880LIMcz0xgftB3mwfywWoLX3w=", "owner": "tharsis", "repo": "evmos", - "rev": "5f59c0f8393e15ff5894e6450567b534c498a428", + "rev": "80c38f659a65a983b221e2a568c6172b8ac3bffc", "type": "github" }, "original": { "owner": "tharsis", - "ref": "v6.0.2", + "ref": "v9.1.0", "repo": "evmos", "type": "github" } @@ -200,12 +200,15 @@ } }, "flake-utils_3": { + "inputs": { + "systems": "systems" + }, "locked": { - "lastModified": 1678901627, - "narHash": "sha256-U02riOqrKKzwjsxc/400XnElV+UtPUQWpANPlyazjH0=", + "lastModified": 1681202837, + "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", "owner": "numtide", "repo": "flake-utils", - "rev": "93a2b84fc4b70d9e089d029deacc3583435c2ed6", + "rev": "cfacdce06f30d2b68473a46042957675eebb3401", "type": "github" }, "original": { @@ -318,16 +321,16 @@ "gaia9-src": { "flake": false, "locked": { - "lastModified": 1678387146, - "narHash": "sha256-xE6jZKIgmZ+/bFUWrdoyOy73fsC1VdYfhxH9u4tD7HI=", + "lastModified": 1681924944, + "narHash": "sha256-UIM6yfqs1yZZ2BO/bBB43pPYSW1IzaYsk2f500tDYzA=", "owner": "cosmos", "repo": "gaia", - "rev": "4b14265197d9beeb6c8b0d407433c852a5af6422", + "rev": "05b6b87d3c9121e933eab437772ea56f33ae268f", "type": "github" }, "original": { "owner": "cosmos", - "ref": "v9.0.1", + "ref": "v9.0.3", "repo": "gaia", "type": "github" } @@ -442,17 +445,17 @@ "ibc-go-v7-src": { "flake": false, "locked": { - "lastModified": 1674120235, - "narHash": "sha256-y2BRN5Ig4XSeT360LdwtsPtHud4JB33R3vXl/J+FHNM=", + "lastModified": 1678970403, + "narHash": "sha256-vdsDqLHpP0Bp0j8gtDOdouzyQXKioZsxJA+znkQw6JY=", "owner": "cosmos", "repo": "ibc-go", - "rev": "0a427c6d93e8f9d20c61b45e36f6e1fe73e37f37", + "rev": "7fb65c76000f207ece1b83d8950e3aaff3dfc0e7", "type": "github" }, "original": { "owner": "cosmos", + "ref": "v7.0.0", "repo": "ibc-go", - "rev": "0a427c6d93e8f9d20c61b45e36f6e1fe73e37f37", "type": "github" } }, @@ -560,16 +563,16 @@ "juno-src": { "flake": false, "locked": { - "lastModified": 1647987514, - "narHash": "sha256-Mtiin+GOH/dyrr7cO+18er+uwYjCpQDY8xhA+kkzniM=", + "lastModified": 1679292088, + "narHash": "sha256-9xWOnlqjJWY7dyICYjl1Fmqi27352TF9ihcbZBI/Dps=", "owner": "CosmosContracts", "repo": "juno", - "rev": "9a1c32f508e6314fb73e57db35313cb329639424", + "rev": "1f392744afd9829f3f7837fe6f13800a19bad961", "type": "github" }, "original": { "owner": "CosmosContracts", - "ref": "v2.3.0-beta.2", + "ref": "v13.0.1", "repo": "juno", "type": "github" } @@ -639,11 +642,11 @@ }, "nixpkgs_3": { "locked": { - "lastModified": 1679410443, - "narHash": "sha256-xDHO/jixWD+y5pmW5+2q4Z4O/I/nA4MAa30svnZKK+M=", + "lastModified": 1682109806, + "narHash": "sha256-d9g7RKNShMLboTWwukM+RObDWWpHKaqTYXB48clBWXI=", "owner": "nixos", "repo": "nixpkgs", - "rev": "c9ece0059f42e0ab53ac870104ca4049df41b133", + "rev": "2362848adf8def2866fabbffc50462e929d7fffb", "type": "github" }, "original": { @@ -910,20 +913,35 @@ "stride-src": { "flake": false, "locked": { - "lastModified": 1678771112, - "narHash": "sha256-c971YXdUSVhpEQFDuBNsG1DooOus1ps0jw4x6haTSdU=", + "lastModified": 1679819302, + "narHash": "sha256-fdjnFHPBZNnhDyVoMuPfqNb6YUYRdcMO73FlZHjIuzA=", "owner": "Stride-Labs", "repo": "stride", - "rev": "ef4808d4095c3da3c4f35e1b37495b5813624d14", + "rev": "3c69e7644859981b1fd9313eb1f0c5e5886e4a0d", "type": "github" }, "original": { "owner": "Stride-Labs", - "ref": "v7.0.0", + "ref": "v8.0.0", "repo": "stride", "type": "github" } }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, "terra-src": { "flake": false, "locked": { diff --git a/flake.nix b/flake.nix index cb25469a1a..25d936aff4 100644 --- a/flake.nix +++ b/flake.nix @@ -46,6 +46,7 @@ ibc-go-v7-simapp apalache evmos + juno stride stride-no-admin ; diff --git a/guide/src/templates/files/hermes/production/config.toml b/guide/src/templates/files/hermes/production/config.toml index 88ac93bf2c..bc6ad8265b 100644 --- a/guide/src/templates/files/hermes/production/config.toml +++ b/guide/src/templates/files/hermes/production/config.toml @@ -3,7 +3,7 @@ log_level = 'info' [mode.clients] enabled = true refresh = true -misbehaviour = false +misbehaviour = true [mode.connections] enabled = false diff --git a/tools/integration-test/Cargo.toml b/tools/integration-test/Cargo.toml index b5a12a0b95..f60d3b2599 100644 --- a/tools/integration-test/Cargo.toml +++ b/tools/integration-test/Cargo.toml @@ -21,7 +21,7 @@ http = "0.2.9" prost = { version = "0.11" } serde_json = "1" time = "0.3" -toml = "0.5" +toml = "0.7" tonic = { version = "0.9", features = ["tls", "tls-roots"] } serde = "1.0.149" diff --git a/tools/integration-test/src/tests/clear_packet.rs b/tools/integration-test/src/tests/clear_packet.rs index 791218e5a7..383dfed8a8 100644 --- a/tools/integration-test/src/tests/clear_packet.rs +++ b/tools/integration-test/src/tests/clear_packet.rs @@ -27,8 +27,8 @@ impl TestOverrides for ClearPacketTest { } // Unordered channel: will permit gaps in the sequence of relayed packets - fn channel_order(&self) -> Order { - Order::Unordered + fn channel_order(&self) -> Ordering { + Ordering::Unordered } } diff --git a/tools/integration-test/src/tests/client_refresh.rs b/tools/integration-test/src/tests/client_refresh.rs index bd7204aedf..c5e79c2e71 100644 --- a/tools/integration-test/src/tests/client_refresh.rs +++ b/tools/integration-test/src/tests/client_refresh.rs @@ -119,15 +119,19 @@ impl TestOverrides for ClientFailsTest { impl BinaryChainTest for ClientFailsTest { fn run( &self, - _config: &TestConfig, + config: &TestConfig, _relayer: RelayerDriver, chains: ConnectedChains, ) -> Result<(), Error> { // Override the configuration in order to use a small `gas_multiplier` which will cause the update client to fail. - let chains2 = override_connected_chains(chains, |config| { - config.chains[0].gas_multiplier = Some(GasMultiplier::unsafe_new(0.8)); - config.chains[1].gas_multiplier = Some(GasMultiplier::unsafe_new(0.8)); - })?; + let chains2 = override_connected_chains( + chains, + |config| { + config.chains[0].gas_multiplier = Some(GasMultiplier::unsafe_new(0.8)); + config.chains[1].gas_multiplier = Some(GasMultiplier::unsafe_new(0.8)); + }, + config, + )?; // Use chains with misconfiguration in order to trigger a ChainError when submitting `MsgClientUpdate` // during the refresh call. @@ -156,6 +160,7 @@ impl BinaryChainTest for ClientFailsTest { fn override_connected_chains( chains: ConnectedChains, config_modifier: impl FnOnce(&mut Config), + test_config: &TestConfig, ) -> Result, Error> where ChainA: ChainHandle, @@ -163,8 +168,8 @@ where { let mut config = Config::default(); - add_chain_config(&mut config, chains.node_a.value())?; - add_chain_config(&mut config, chains.node_b.value())?; + add_chain_config(&mut config, chains.node_a.value(), test_config)?; + add_chain_config(&mut config, chains.node_b.value(), test_config)?; config_modifier(&mut config); diff --git a/tools/integration-test/src/tests/ordered_channel.rs b/tools/integration-test/src/tests/ordered_channel.rs index 09df932e97..25177b4ee8 100644 --- a/tools/integration-test/src/tests/ordered_channel.rs +++ b/tools/integration-test/src/tests/ordered_channel.rs @@ -36,8 +36,8 @@ impl TestOverrides for OrderedChannelTest { false } - fn channel_order(&self) -> Order { - Order::Ordered + fn channel_order(&self) -> Ordering { + Ordering::Ordered } } diff --git a/tools/integration-test/src/tests/ordered_channel_clear.rs b/tools/integration-test/src/tests/ordered_channel_clear.rs index 521085365b..5590812164 100644 --- a/tools/integration-test/src/tests/ordered_channel_clear.rs +++ b/tools/integration-test/src/tests/ordered_channel_clear.rs @@ -56,8 +56,8 @@ impl TestOverrides for OrderedChannelClearTest { false } - fn channel_order(&self) -> Order { - Order::Ordered + fn channel_order(&self) -> Ordering { + Ordering::Ordered } } @@ -183,8 +183,8 @@ impl TestOverrides for OrderedChannelClearEqualCLITest { false } - fn channel_order(&self) -> Order { - Order::Ordered + fn channel_order(&self) -> Ordering { + Ordering::Ordered } } diff --git a/tools/test-framework/Cargo.toml b/tools/test-framework/Cargo.toml index 8b681f7417..11d9381cbf 100644 --- a/tools/test-framework/Cargo.toml +++ b/tools/test-framework/Cargo.toml @@ -32,7 +32,7 @@ serde = "1.0" serde_json = "1" serde_yaml = "0.9.16" itertools = "0.10" -toml = "0.5" +toml = "0.7" subtle-encoding = "0.5.1" sha2 = "0.10.6" crossbeam-channel = "0.5.8" diff --git a/tools/test-framework/src/bootstrap/binary/chain.rs b/tools/test-framework/src/bootstrap/binary/chain.rs index 5ed3029807..5ec10402d2 100644 --- a/tools/test-framework/src/bootstrap/binary/chain.rs +++ b/tools/test-framework/src/bootstrap/binary/chain.rs @@ -55,8 +55,8 @@ pub fn bootstrap_chains_with_full_nodes( > { let mut config = Config::default(); - add_chain_config(&mut config, &node_a)?; - add_chain_config(&mut config, &node_b)?; + add_chain_config(&mut config, &node_a, test_config)?; + add_chain_config(&mut config, &node_b, test_config)?; config_modifier(&mut config); @@ -249,8 +249,13 @@ pub fn new_registry(config: Config) -> SharedRegistry Result<(), Error> { - let chain_config = running_node.generate_chain_config(&running_node.chain_driver.chain_type)?; +pub fn add_chain_config( + config: &mut Config, + running_node: &FullNode, + test_config: &TestConfig, +) -> Result<(), Error> { + let chain_config = + running_node.generate_chain_config(&running_node.chain_driver.chain_type, test_config)?; config.chains.push(chain_config); Ok(()) diff --git a/tools/test-framework/src/bootstrap/binary/channel.rs b/tools/test-framework/src/bootstrap/binary/channel.rs index 9624937c88..4b1439568a 100644 --- a/tools/test-framework/src/bootstrap/binary/channel.rs +++ b/tools/test-framework/src/bootstrap/binary/channel.rs @@ -5,7 +5,7 @@ use eyre::{eyre, Report as Error}; use ibc_relayer::chain::handle::ChainHandle; use ibc_relayer::channel::{Channel, ChannelSide}; -use ibc_relayer_types::core::ics04_channel::channel::Order; +use ibc_relayer_types::core::ics04_channel::channel::Ordering; use ibc_relayer_types::core::ics04_channel::version::Version; use ibc_relayer_types::core::ics24_host::identifier::PortId; use tracing::{debug, info}; @@ -20,7 +20,7 @@ use crate::types::tagged::*; use crate::util::random::random_u64_range; pub struct BootstrapChannelOptions { - pub order: Order, + pub order: Ordering, pub version: Version, pub pad_channel_id_a: u64, pub pad_channel_id_b: u64, @@ -171,7 +171,7 @@ pub fn pad_channel_id( ); let channel: Channel = Channel { - ordering: Order::Unordered, + ordering: Ordering::Unordered, a_side: ChannelSide::new( chain_b.clone(), client_id_b.value().clone(), @@ -200,7 +200,7 @@ pub fn pad_channel_id( impl Default for BootstrapChannelOptions { fn default() -> Self { Self { - order: Order::Unordered, + order: Ordering::Unordered, version: Version::ics20(), pad_channel_id_a: 0, pad_channel_id_b: 1, @@ -209,7 +209,7 @@ impl Default for BootstrapChannelOptions { } impl BootstrapChannelOptions { - pub fn order(mut self, order: Order) -> Self { + pub fn order(mut self, order: Ordering) -> Self { self.order = order; self } diff --git a/tools/test-framework/src/bootstrap/nary/chain.rs b/tools/test-framework/src/bootstrap/nary/chain.rs index 30b2188266..b0233ecdf5 100644 --- a/tools/test-framework/src/bootstrap/nary/chain.rs +++ b/tools/test-framework/src/bootstrap/nary/chain.rs @@ -60,7 +60,7 @@ pub fn boostrap_chains_with_any_nodes( let mut config = Config::default(); for node in full_nodes.iter() { - add_chain_config(&mut config, node)?; + add_chain_config(&mut config, node, test_config)?; } config_modifier(&mut config); diff --git a/tools/test-framework/src/bootstrap/nary/channel.rs b/tools/test-framework/src/bootstrap/nary/channel.rs index 910ccfdc23..e2d2697b88 100644 --- a/tools/test-framework/src/bootstrap/nary/channel.rs +++ b/tools/test-framework/src/bootstrap/nary/channel.rs @@ -5,7 +5,7 @@ use core::convert::TryInto; use core::time::Duration; use ibc_relayer::chain::handle::ChainHandle; -use ibc_relayer_types::core::ics04_channel::channel::Order; +use ibc_relayer_types::core::ics04_channel::channel::Ordering; use ibc_relayer_types::core::ics24_host::identifier::PortId; use crate::bootstrap::binary::channel::{ @@ -28,7 +28,7 @@ pub fn bootstrap_channels_with_connections_dynamic( connections: DynamicConnectedConnections, chains: &Vec, ports: &Vec>, - order: Order, + order: Ordering, bootstrap_with_random_ids: bool, ) -> Result, Error> { let size = chains.len(); @@ -85,7 +85,7 @@ pub fn bootstrap_channels_with_connections, chains: [Handle; SIZE], ports: [[PortId; SIZE]; SIZE], - order: Order, + order: Ordering, bootstrap_with_random_ids: bool, ) -> Result, Error> { let channels = bootstrap_channels_with_connections_dynamic( @@ -108,7 +108,7 @@ pub fn bootstrap_channels_and_connections_dynamic( chains: &DynamicConnectedChains, ports: &Vec>, connection_delay: Duration, - order: Order, + order: Ordering, bootstrap_with_random_ids: bool, ) -> Result, Error> { let connections = bootstrap_connections_dynamic( @@ -134,7 +134,7 @@ pub fn bootstrap_channels_and_connections, ports: [[PortId; SIZE]; SIZE], connection_delay: Duration, - order: Order, + order: Ordering, bootstrap_with_random_ids: bool, ) -> Result, Error> { let channels = bootstrap_channels_and_connections_dynamic( diff --git a/tools/test-framework/src/docs/walkthroughs/ordered_channel.rs b/tools/test-framework/src/docs/walkthroughs/ordered_channel.rs index ef2ee3ecc5..c4ef2c4616 100644 --- a/tools/test-framework/src/docs/walkthroughs/ordered_channel.rs +++ b/tools/test-framework/src/docs/walkthroughs/ordered_channel.rs @@ -34,8 +34,8 @@ //! false //! } //! -//! fn channel_order(&self) -> Order { -//! Order::Ordered +//! fn channel_order(&self) -> Ordering { +//! Ordering::Ordered //! } //! } //! diff --git a/tools/test-framework/src/framework/binary/channel.rs b/tools/test-framework/src/framework/binary/channel.rs index e4f173d816..7380249464 100644 --- a/tools/test-framework/src/framework/binary/channel.rs +++ b/tools/test-framework/src/framework/binary/channel.rs @@ -7,7 +7,7 @@ use tracing::info; use ibc_relayer::chain::handle::ChainHandle; -use ibc_relayer_types::core::ics04_channel::channel::Order; +use ibc_relayer_types::core::ics04_channel::channel::Ordering; use ibc_relayer_types::core::ics04_channel::version::Version; use ibc_relayer_types::core::ics24_host::identifier::PortId; @@ -134,9 +134,9 @@ pub trait PortsOverride { */ pub trait ChannelOrderOverride { /** - Return the channel ordering as [`Order`]. + Return the channel ordering as [`Ordering`]. */ - fn channel_order(&self) -> Order; + fn channel_order(&self) -> Ordering; } /** Facility for overriding the channel version */ diff --git a/tools/test-framework/src/framework/overrides.rs b/tools/test-framework/src/framework/overrides.rs index b20a22be3a..0338224469 100644 --- a/tools/test-framework/src/framework/overrides.rs +++ b/tools/test-framework/src/framework/overrides.rs @@ -6,7 +6,7 @@ use core::time::Duration; use ibc_relayer::config::default::connection_delay as default_connection_delay; use ibc_relayer::config::Config; use ibc_relayer::foreign_client::CreateOptions as ClientOptions; -use ibc_relayer_types::core::ics04_channel::channel::Order; +use ibc_relayer_types::core::ics04_channel::channel::Ordering; use ibc_relayer_types::core::ics04_channel::version::Version; use ibc_relayer_types::core::ics24_host::identifier::PortId; @@ -127,13 +127,13 @@ pub trait TestOverrides { } /** - Return the channel ordering used for creating channels as [`Order`]. - Defaults to [`Order::Unordered`]. + Return the channel ordering used for creating channels as [`Ordering`]. + Defaults to [`Ordering::Unordered`]. Implemented for [`ChannelOrderOverride`]. */ - fn channel_order(&self) -> Order { - Order::Unordered + fn channel_order(&self) -> Ordering { + Ordering::Unordered } /** @@ -212,7 +212,7 @@ impl PortsOverride for Test { } impl ChannelOrderOverride for Test { - fn channel_order(&self) -> Order { + fn channel_order(&self) -> Ordering { TestOverrides::channel_order(self) } } diff --git a/tools/test-framework/src/prelude.rs b/tools/test-framework/src/prelude.rs index edc5837592..cf84da30f0 100644 --- a/tools/test-framework/src/prelude.rs +++ b/tools/test-framework/src/prelude.rs @@ -9,7 +9,7 @@ pub use ibc_relayer::config::Config; pub use ibc_relayer::foreign_client::ForeignClient; pub use ibc_relayer::registry::SharedRegistry; pub use ibc_relayer::supervisor::SupervisorHandle; -pub use ibc_relayer_types::core::ics04_channel::channel::Order; +pub use ibc_relayer_types::core::ics04_channel::channel::Ordering; pub use ibc_relayer_types::core::ics24_host::identifier::{ ChainId, ChannelId, ClientId, ConnectionId, PortId, }; diff --git a/tools/test-framework/src/relayer/channel.rs b/tools/test-framework/src/relayer/channel.rs index 91d9043270..5dc01da72d 100644 --- a/tools/test-framework/src/relayer/channel.rs +++ b/tools/test-framework/src/relayer/channel.rs @@ -4,7 +4,7 @@ use ibc_relayer::chain::handle::ChainHandle; use ibc_relayer::chain::requests::{IncludeProof, QueryChannelRequest, QueryHeight}; use ibc_relayer::channel::{extract_channel_id, Channel, ChannelSide}; use ibc_relayer_types::core::ics04_channel::channel::State as ChannelState; -use ibc_relayer_types::core::ics04_channel::channel::{ChannelEnd, IdentifiedChannelEnd, Order}; +use ibc_relayer_types::core::ics04_channel::channel::{ChannelEnd, IdentifiedChannelEnd, Ordering}; use ibc_relayer_types::core::ics24_host::identifier::ConnectionId; use crate::error::Error; @@ -45,7 +45,7 @@ pub fn init_channel( ) -> Result<(TaggedChannelId, Channel), Error> { let channel = Channel { connection_delay: Default::default(), - ordering: Order::Unordered, + ordering: Ordering::Unordered, a_side: ChannelSide::new( handle_a.clone(), client_id_a.cloned_value(), @@ -82,7 +82,7 @@ pub fn init_channel_optimistic( ) -> Result, Error> { let channel = Channel { connection_delay: Default::default(), - ordering: Order::Unordered, + ordering: Ordering::Unordered, a_side: ChannelSide::new( handle_a.clone(), client_id_a.cloned_value(), diff --git a/tools/test-framework/src/types/single/node.rs b/tools/test-framework/src/types/single/node.rs index 9facdb0b0a..65a366c5d1 100644 --- a/tools/test-framework/src/types/single/node.rs +++ b/tools/test-framework/src/types/single/node.rs @@ -18,6 +18,7 @@ use tendermint_rpc::WebSocketClientUrl; use crate::chain::chain_type::ChainType as TestedChainType; use crate::chain::driver::ChainDriver; use crate::ibc::denom::Denom; +use crate::prelude::TestConfig; use crate::types::env::{prefix_writer, EnvWriter, ExportEnv}; use crate::types::process::ChildProcess; use crate::types::tagged::*; @@ -124,7 +125,14 @@ impl FullNode { pub fn generate_chain_config( &self, chain_type: &TestedChainType, + test_config: &TestConfig, ) -> Result { + let hermes_keystore_dir = test_config + .chain_store_dir + .join("hermes_keyring") + .as_path() + .display() + .to_string(); Ok(config::ChainConfig { id: self.chain_driver.chain_id.clone(), r#type: ChainType::CosmosSdk, @@ -135,12 +143,8 @@ impl FullNode { genesis_restart: None, account_prefix: self.chain_driver.account_prefix.clone(), key_name: self.wallets.relayer.id.0.clone(), - - // By default we use in-memory key store to avoid polluting - // ~/.hermes/keys. See - // https://github.com/informalsystems/hermes/issues/1541 - key_store_type: Store::Memory, - + key_store_type: Store::Test, + key_store_folder: Some(hermes_keystore_dir.into()), store_prefix: "ibc".to_string(), default_gas: None, max_gas: Some(3000000),