diff --git a/.changelog/unreleased/breaking-changes/3548-cometbft-0.38.md b/.changelog/unreleased/breaking-changes/3548-cometbft-0.38.md deleted file mode 100644 index d2b1f2e5bf..0000000000 --- a/.changelog/unreleased/breaking-changes/3548-cometbft-0.38.md +++ /dev/null @@ -1,2 +0,0 @@ -- Update to tendermint-rs 0.33 and ibc-proto 0.33 - ([\#3548](https://github.com/informalsystems/hermes/issues/3548)) diff --git a/.changelog/unreleased/breaking-changes/ibc-relayer-cli/3636-config-chain-type.md b/.changelog/unreleased/breaking-changes/ibc-relayer-cli/3636-config-chain-type.md new file mode 100644 index 0000000000..601455dec7 --- /dev/null +++ b/.changelog/unreleased/breaking-changes/ibc-relayer-cli/3636-config-chain-type.md @@ -0,0 +1,8 @@ +- The `type` key in the `[[chains]]` section is now required. ([\#3636](https://github.com/informalsystems/hermes/issues/3636)) + If you previously did not specify that key, you must now set it to `type = "CosmosSdk"`, eg. + + ```rust + [[chains]] + id = "osmosis-1" + type = "CosmosSdk" + ``` diff --git a/.changelog/unreleased/improvements/ibc-relayer/3636-config-enum.md b/.changelog/unreleased/improvements/ibc-relayer/3636-config-enum.md new file mode 100644 index 0000000000..95e1f50230 --- /dev/null +++ b/.changelog/unreleased/improvements/ibc-relayer/3636-config-enum.md @@ -0,0 +1,3 @@ +- Change config format to scope configs by type. This enables adding support for + more types of chain, even when those have different config options than each + other. ([\#3636](https://github.com/informalsystems/hermes/issues/3636)) \ No newline at end of file diff --git a/.changelog/unreleased/bug-fixes/ibc-relayer-cli/3580-docker-uid-gid.md b/.changelog/v1.7.0/bug-fixes/ibc-relayer-cli/3580-docker-uid-gid.md similarity index 100% rename from .changelog/unreleased/bug-fixes/ibc-relayer-cli/3580-docker-uid-gid.md rename to .changelog/v1.7.0/bug-fixes/ibc-relayer-cli/3580-docker-uid-gid.md diff --git a/.changelog/unreleased/bug-fixes/ibc-relayer-types/3549-ibc-relayer-types-docs.md b/.changelog/v1.7.0/bug-fixes/ibc-relayer-types/3549-ibc-relayer-types-docs.md similarity index 100% rename from .changelog/unreleased/bug-fixes/ibc-relayer-types/3549-ibc-relayer-types-docs.md rename to .changelog/v1.7.0/bug-fixes/ibc-relayer-types/3549-ibc-relayer-types-docs.md diff --git a/.changelog/unreleased/features/ibc-relayer-cli/3398-clear-packet-endpoint.md b/.changelog/v1.7.0/features/ibc-relayer-cli/3398-clear-packet-endpoint.md similarity index 100% rename from .changelog/unreleased/features/ibc-relayer-cli/3398-clear-packet-endpoint.md rename to .changelog/v1.7.0/features/ibc-relayer-cli/3398-clear-packet-endpoint.md diff --git a/.changelog/v1.7.0/features/ibc-relayer-cli/3456-evidence-command.md b/.changelog/v1.7.0/features/ibc-relayer-cli/3456-evidence-command.md new file mode 100644 index 0000000000..8daa96e334 --- /dev/null +++ b/.changelog/v1.7.0/features/ibc-relayer-cli/3456-evidence-command.md @@ -0,0 +1,4 @@ +- Add a new `evidence` command for monitoring the blocks emitted + by a chain for the presence of a misbehaviour evidence, and + report that evidence to all counteparty clients of that chain. + ([\#3456](https://github.com/informalsystems/hermes/pull/3456)) diff --git a/.changelog/unreleased/features/ibc-relayer-cli/3564-tracing-filter.md b/.changelog/v1.7.0/features/ibc-relayer-cli/3564-tracing-filter.md similarity index 100% rename from .changelog/unreleased/features/ibc-relayer-cli/3564-tracing-filter.md rename to .changelog/v1.7.0/features/ibc-relayer-cli/3564-tracing-filter.md diff --git a/.changelog/unreleased/improvements/ibc-relayer-cli/3501-listen-pull.md b/.changelog/v1.7.0/improvements/ibc-relayer-cli/3501-listen-pull.md similarity index 100% rename from .changelog/unreleased/improvements/ibc-relayer-cli/3501-listen-pull.md rename to .changelog/v1.7.0/improvements/ibc-relayer-cli/3501-listen-pull.md diff --git a/.changelog/v1.7.0/improvements/ibc-relayer/3219-ics-consumer-misbehavior.md b/.changelog/v1.7.0/improvements/ibc-relayer/3219-ics-consumer-misbehavior.md new file mode 100644 index 0000000000..eaec421cc8 --- /dev/null +++ b/.changelog/v1.7.0/improvements/ibc-relayer/3219-ics-consumer-misbehavior.md @@ -0,0 +1,4 @@ +- When Hermes detects a misbehaviour on a chain that is CCV + consumer, it will now send the misbehaviour evidence to the + provider chain using the new `IcsConsumerMisbehaviour` message. + ([\#3219](https://github.com/informalsystems/hermes/issues/3219)) \ No newline at end of file diff --git a/.changelog/v1.7.0/improvements/ibc-relayer/3223-submit-misbehavior-all-clients.md b/.changelog/v1.7.0/improvements/ibc-relayer/3223-submit-misbehavior-all-clients.md new file mode 100644 index 0000000000..c76ebb57d8 --- /dev/null +++ b/.changelog/v1.7.0/improvements/ibc-relayer/3223-submit-misbehavior-all-clients.md @@ -0,0 +1,5 @@ +- When Hermes detects a misbehaviour from a on-chain client, eg. a light + client attack or a double-sign, it will now submit the misbehaviour + evidence to all counterparty clients of the misbehaving chain + instead of to the counterparty client of the misbehaving client only. + ([\#3223](https://github.com/informalsystems/hermes/issues/3223)) \ No newline at end of file diff --git a/.changelog/unreleased/improvements/ibc-relayer/3531-fix-3531.md b/.changelog/v1.7.0/improvements/ibc-relayer/3531-fix-3531.md similarity index 100% rename from .changelog/unreleased/improvements/ibc-relayer/3531-fix-3531.md rename to .changelog/v1.7.0/improvements/ibc-relayer/3531-fix-3531.md diff --git a/.changelog/unreleased/improvements/ibc-relayer/3548-cometbft-0.38.md b/.changelog/v1.7.0/improvements/ibc-relayer/3548-cometbft-0.38.md similarity index 100% rename from .changelog/unreleased/improvements/ibc-relayer/3548-cometbft-0.38.md rename to .changelog/v1.7.0/improvements/ibc-relayer/3548-cometbft-0.38.md diff --git a/.changelog/v1.7.0/improvements/ibc-relayer/3666-default-compat-mode-to-v034.md b/.changelog/v1.7.0/improvements/ibc-relayer/3666-default-compat-mode-to-v034.md new file mode 100644 index 0000000000..b018b03a95 --- /dev/null +++ b/.changelog/v1.7.0/improvements/ibc-relayer/3666-default-compat-mode-to-v034.md @@ -0,0 +1,2 @@ +- Change fallback compatibility version for CometBFT from v0.37 to v0.34 + ([\#3666](https://github.com/informalsystems/hermes/issues/3666)) \ No newline at end of file diff --git a/.changelog/v1.7.0/summary.md b/.changelog/v1.7.0/summary.md new file mode 100644 index 0000000000..a7ebc13805 --- /dev/null +++ b/.changelog/v1.7.0/summary.md @@ -0,0 +1,25 @@ +*October 20th, 2023* + +This v1.7 release introduces new features and improvements to Hermes. + +One of the key highlights is the addition of new misbehavior detection features. + +Hermes now includes a new command called `evidence`, which monitors the blocks emitted by a chain for any presence of misbehavior evidence. + +If misbehavior is detected, the CLI will report that evidence to all counterparty clients of that chain. +On top of that, misbehavior evidence detected on a chain that is a CCV (Cross-Chain Validation) consumer +is now sent to its provider chain, alerting it directly of the misbehaving consumer chain. + +Furthermore, when misbehavior is detected from an on-chain client, such as a light client attack or a double-sign, +the evidence is now submitted to all counterparty clients of the misbehaving chain, rather than just the +counterparty client of the misbehaving client. + +In addition, the REST server of Hermes now has a `/clear_packets` endpoint which allows triggering +packet clearing for a specific chain or all chains if no specific chain is provided. + +Another notable improvement is the ability to change `tracing` directives at runtime. +This feature lets users adjust tracing settings dynamically as needed, providing a more +customizable and efficient debugging experience. + +Overall, the new misbehavior detection features in Hermes contribute to a more robust and secure environment, +enabling timely identification and response to potential misbehaving actors. diff --git a/.github/workflows/misbehaviour.yml b/.github/workflows/misbehaviour.yml index 8a4c4c819f..577455c35c 100644 --- a/.github/workflows/misbehaviour.yml +++ b/.github/workflows/misbehaviour.yml @@ -36,7 +36,7 @@ concurrency: cancel-in-progress: true jobs: - misbehaviour: + light-client-attack: runs-on: ubuntu-20.04 timeout-minutes: 20 strategy: @@ -91,3 +91,166 @@ jobs: run: | nix shell .#${{ matrix.chain.package }} -c bash misbehaviour_test.sh + ics-light-client-attack: + runs-on: ubuntu-20.04 + timeout-minutes: 20 + strategy: + fail-fast: false + matrix: + chain: + - package: interchain-security + account_prefix: cosmos + steps: + - uses: actions/checkout@v4 + - name: Install Nix + uses: cachix/install-nix-action@v22 + with: + extra_nix_config: | + experimental-features = nix-command flakes + - name: Use cachix cache + uses: cachix/cachix-action@v12 + with: + name: cosmos + - name: Install sconfig + uses: jaxxstorm/action-install-gh-release@v1.10.0 + with: + repo: freshautomations/sconfig + platform: linux + arch: amd64 + extension-matching: disable + rename-to: sconfig + chmod: 0755 + - name: Install stoml + uses: jaxxstorm/action-install-gh-release@v1.10.0 + with: + repo: freshautomations/stoml + platform: linux + arch: amd64 + extension-matching: disable + rename-to: stoml + chmod: 0755 + - name: Install Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + - name: Use Rust cache + uses: Swatinem/rust-cache@v2 + - name: Build Hermes + uses: actions-rs/cargo@v1 + with: + command: build + - name: Run test + working-directory: ci/misbehaviour-ics + run: | + nix shell .#cometbft .#${{ matrix.chain.package }} -c bash light_client_attack_test.sh + + ics-light-client-attack-freeze: + runs-on: ubuntu-20.04 + timeout-minutes: 20 + strategy: + fail-fast: false + matrix: + chain: + - package: interchain-security + account_prefix: cosmos + steps: + - uses: actions/checkout@v4 + - name: Install Nix + uses: cachix/install-nix-action@v22 + with: + extra_nix_config: | + experimental-features = nix-command flakes + - name: Use cachix cache + uses: cachix/cachix-action@v12 + with: + name: cosmos + - name: Install sconfig + uses: jaxxstorm/action-install-gh-release@v1.10.0 + with: + repo: freshautomations/sconfig + platform: linux + arch: amd64 + extension-matching: disable + rename-to: sconfig + chmod: 0755 + - name: Install stoml + uses: jaxxstorm/action-install-gh-release@v1.10.0 + with: + repo: freshautomations/stoml + platform: linux + arch: amd64 + extension-matching: disable + rename-to: stoml + chmod: 0755 + - name: Install Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + - name: Use Rust cache + uses: Swatinem/rust-cache@v2 + - name: Build Hermes + uses: actions-rs/cargo@v1 + with: + command: build + - name: Run test + working-directory: ci/misbehaviour-ics + run: | + nix shell .#${{ matrix.chain.package }} -c bash light_client_attack_freeze_test.sh + + + ics-double-sign: + runs-on: ubuntu-20.04 + timeout-minutes: 20 + strategy: + fail-fast: false + matrix: + chain: + - package: interchain-security + account_prefix: cosmos + steps: + - uses: actions/checkout@v4 + - name: Install Nix + uses: cachix/install-nix-action@v22 + with: + extra_nix_config: | + experimental-features = nix-command flakes + - name: Use cachix cache + uses: cachix/cachix-action@v12 + with: + name: cosmos + - name: Install sconfig + uses: jaxxstorm/action-install-gh-release@v1.10.0 + with: + repo: freshautomations/sconfig + platform: linux + arch: amd64 + extension-matching: disable + rename-to: sconfig + chmod: 0755 + - name: Install stoml + uses: jaxxstorm/action-install-gh-release@v1.10.0 + with: + repo: freshautomations/stoml + platform: linux + arch: amd64 + extension-matching: disable + rename-to: stoml + chmod: 0755 + - name: Install Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + - name: Use Rust cache + uses: Swatinem/rust-cache@v2 + - name: Build Hermes + uses: actions-rs/cargo@v1 + with: + command: build + - name: Run test + working-directory: ci/misbehaviour-ics + run: | + nix shell .#${{ matrix.chain.package }} -c bash double_sign_test.sh + diff --git a/.gitignore b/.gitignore index 2e9b0e8816..edd589a061 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,6 @@ mc.log # Ignore OSX .DS_Store file .DS_Store + +# Ignore tooling Cargo.lock +tools/check-guide/Cargo.lock diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ee3332ca6..7604939159 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,81 @@ # CHANGELOG +## v1.7.0 + +*October 20th, 2023* + +This v1.7 release introduces new features and improvements to Hermes. + +One of the key highlights is the addition of new misbehavior detection features. + +- Hermes now includes a new command called `evidence`, which monitors the blocks emitted by a chain for any presence of misbehavior evidence. +- If misbehavior is detected, the CLI will report that evidence to all counterparty clients of that chain. +On top of that, misbehavior evidence detected on a chain that is a CCV (Cross-Chain Validation) consumer +is now sent to its provider chain, alerting it directly of the misbehaving consumer chain. +- Furthermore, when misbehavior is detected from an on-chain client, such as a light client attack or a double-sign, +the evidence is now submitted to all counterparty clients of the misbehaving chain, rather than just the +counterparty client of the misbehaving client. + +In addition, the REST server of Hermes now has a `/clear_packets` endpoint which allows triggering +packet clearing for a specific chain or all chains if no specific chain is provided. + +Another notable improvement is the ability to change `tracing` directives at runtime. +This feature lets users adjust tracing settings dynamically as needed, providing a more +customizable and efficient debugging experience. + +Overall, the new misbehavior detection features in Hermes contribute to a more robust and secure environment, +enabling timely identification and response to potential misbehaving actors. + +### FEATURES + +- [Relayer CLI](relayer-cli) + - Add a new `evidence` command for monitoring the blocks emitted + by a chain for the presence of a misbehaviour evidence, and + report that evidence to all counteparty clients of that chain. + ([\#3456](https://github.com/informalsystems/hermes/pull/3456)) + - Add a `/clear_packets?chain=CHAIN_ID` endpoint to the built-in + REST server to trigger packet clear for the chain specified in the + chain query param or for all chains if the query param is omitted. + ([\#3398](https://github.com/informalsystems/hermes/issues/3398)) + - Add support for changing `tracing` directives at runtime. + Please see the [corresponding page in the Hermes guide][tracing-guide] for more information. + ([\#3564](https://github.com/informalsystems/hermes/issues/3564)) + + [tracing-guide]: https://hermes.informal.systems/advanced/troubleshooting/log-level.html + + +### IMPROVEMENTS + +- [Relayer Library](relayer) + - When Hermes detects a misbehaviour on a chain that is CCV + consumer, it will now send the misbehaviour evidence to the + provider chain using the new `IcsConsumerMisbehaviour` message. + ([\#3219](https://github.com/informalsystems/hermes/issues/3219)) + - When Hermes detects a misbehaviour from a on-chain client, eg. a light + client attack or a double-sign, it will now submit the misbehaviour + evidence to all counterparty clients of the misbehaving chain + instead of to the counterparty client of the misbehaving client only. + ([\#3223](https://github.com/informalsystems/hermes/issues/3223)) + - Improve error message when scanning unsupported client + ([\#3531](https://github.com/informalsystems/hermes/issues/3531)) + - Regard the `finalize_block_events` field of the `block_results` RPC endpoint, added in CometBFT 0.38 + ([\#3548](https://github.com/informalsystems/hermes/issues/3548)) + - Change fallback compatibility version for CometBFT from v0.37 to v0.34 + ([\#3666](https://github.com/informalsystems/hermes/issues/3666)) +- [Relayer CLI](relayer-cli) + - The `listen` command now works with both `push` and `pull` event sources + ([\#3501](https://github.com/informalsystems/hermes/issues/3501)) + +### BUG FIXES + +- [Relayer CLI](relayer-cli) + - Revert Docker image to Ubuntu LTS and set the UID and GID explicitly + ([\#3580](https://github.com/informalsystems/hermes/issues/3580)) +- [IBC Data structures](relayer-types) + - Fix build of `ibc-relayer-types` documentation on docs.rs + ([\#3549](https://github.com/informalsystems/hermes/issues/3549)) + + ## v1.6.0 *July 19th, 2023* diff --git a/Cargo.lock b/Cargo.lock index 4281f75f95..42bfbf1661 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,9 +43,9 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ "gimli", ] @@ -58,18 +58,18 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aho-corasick" -version = "1.0.2" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ "memchr", ] [[package]] name = "anyhow" -version = "1.0.71" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "arc-swap" @@ -96,18 +96,18 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.38", ] [[package]] name = "async-trait" -version = "0.1.72" +version = "0.1.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.38", ] [[package]] @@ -145,9 +145,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "axum" -version = "0.6.18" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8175979259124331c1d7bf6586ee7e0da434155e4b2d48ec2c8386281d8df39" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" dependencies = [ "async-trait", "axum-core", @@ -194,9 +194,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", @@ -221,9 +221,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.2" +version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" [[package]] name = "base64ct" @@ -275,9 +275,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.3" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" [[package]] name = "block-buffer" @@ -308,9 +308,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "byte-unit" @@ -324,21 +324,21 @@ dependencies = [ [[package]] name = "bytecount" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c" +checksum = "ad152d03a2c813c80bb94fedbf3a3f02b28f793e39e7c214c8a0bcc196343de7" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" dependencies = [ "serde", ] @@ -360,9 +360,9 @@ checksum = "e6e9e01327e6c86e92ec72b1c798d4a94810f147209bbe3ffab6a86954937a6f" [[package]] name = "cargo-platform" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27" +checksum = "12024c4645c97566567129c204f65d5815a8c9aecf30fcbe682b2fe034996d36" dependencies = [ "serde", ] @@ -382,9 +382,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.79" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -488,9 +491,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "795bc6e66a8e340f075fcf6227e417a2dc976b92b91f3cdc778bb858778b6747" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "contracts" @@ -589,9 +592,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4c2f4e1afd912bc40bfd6fed5d9dc1f288e0ba01bfcc835cc5bc3eb13efe15" +checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" dependencies = [ "generic-array", "rand_core", @@ -611,9 +614,9 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.0.0" +version = "4.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f711ade317dd348950a9910f81c5947e3d8907ebd2b83f76203ff1807e6a2bc2" +checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" dependencies = [ "cfg-if 1.0.0", "cpufeatures", @@ -634,7 +637,7 @@ checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.38", ] [[package]] @@ -652,12 +655,12 @@ dependencies = [ [[package]] name = "dashmap" -version = "5.5.0" +version = "5.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6943ae99c34386c84a470c499d3414f66502a41340aa895406e0d2e4a207b91d" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if 1.0.0", - "hashbrown 0.14.0", + "hashbrown 0.14.1", "lock_api", "once_cell", "parking_lot_core", @@ -671,14 +674,23 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "der" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7ed52955ce76b1554f509074bb357d3fb8ac9b51288a65a3fd480d1dfba946" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", "zeroize", ] +[[package]] +name = "deranged" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +dependencies = [ + "powerfmt", +] + [[package]] name = "derivation-path" version = "0.2.0" @@ -750,17 +762,11 @@ dependencies = [ "winapi", ] -[[package]] -name = "dyn-clone" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "304e6508efa593091e97a9abbc10f90aa7ca635b6d2784feff3c89d41dd12272" - [[package]] name = "ecdsa" -version = "0.16.7" +version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0997c976637b606099b9985693efa3581e84e41f5c11ba5255f88711058ad428" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" dependencies = [ "der", "digest 0.10.7", @@ -772,9 +778,9 @@ dependencies = [ [[package]] name = "ed25519" -version = "2.2.2" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60f6d271ca33075c88028be6f04d502853d63a5ece419d269c15315d4fc1cf1d" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ "pkcs8", "serde", @@ -804,7 +810,7 @@ dependencies = [ "ed25519", "rand_core", "serde", - "sha2 0.10.7", + "sha2 0.10.8", "zeroize", ] @@ -817,20 +823,20 @@ dependencies = [ "derivation-path", "ed25519-dalek", "hmac", - "sha2 0.10.7", + "sha2 0.10.8", ] [[package]] name = "either" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "elliptic-curve" -version = "0.13.5" +version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" +checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" dependencies = [ "base16ct", "crypto-bigint", @@ -853,9 +859,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.32" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" dependencies = [ "cfg-if 1.0.0", ] @@ -879,36 +885,16 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" -[[package]] -name = "erased-serde" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da96524cc884f6558f1769b6c46686af2fe8e8b4cd253bd5a3cdba8181b8e070" -dependencies = [ - "serde", -] - [[package]] name = "errno" -version = "0.3.1" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" dependencies = [ - "errno-dragonfly", "libc", "windows-sys 0.48.0", ] -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] - [[package]] name = "error-chain" version = "0.12.4" @@ -930,12 +916,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.9.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" [[package]] name = "ff" @@ -949,9 +932,9 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.1.20" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77" +checksum = "d0870c84016d4b481be5c9f323c24f65e31e901ae618f0e80f4308fb00de1d2d" [[package]] name = "fixed-hash" @@ -1050,7 +1033,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.38", ] [[package]] @@ -1109,9 +1092,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.3" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "glob" @@ -1152,9 +1135,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.20" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" +checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" dependencies = [ "bytes", "fnv", @@ -1183,9 +1166,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" [[package]] name = "hdpath" @@ -1213,9 +1196,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" [[package]] name = "hex" @@ -1268,9 +1251,9 @@ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "humantime" @@ -1305,7 +1288,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2", + "socket2 0.4.9", "tokio", "tower-service", "tracing", @@ -1340,7 +1323,7 @@ dependencies = [ [[package]] name = "ibc-chain-registry" -version = "0.25.0" +version = "0.26.0" dependencies = [ "async-trait", "flex-error", @@ -1348,7 +1331,7 @@ dependencies = [ "http", "ibc-proto", "ibc-relayer-types", - "itertools", + "itertools 0.10.5", "reqwest", "serde", "serde_json", @@ -1359,7 +1342,7 @@ dependencies = [ [[package]] name = "ibc-integration-test" -version = "0.25.0" +version = "0.26.0" dependencies = [ "http", "ibc-relayer", @@ -1370,17 +1353,17 @@ dependencies = [ "serde_json", "tempfile", "time", - "toml 0.7.6", + "toml 0.7.8", "tonic", ] [[package]] name = "ibc-proto" -version = "0.37.0" +version = "0.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "725fd83c94e9859fd967cd706996679799171eba940740f071f0046fb6f6e031" +checksum = "93cbf4cbe9e5113cc7c70f3208a7029b2205c629502cbb2ae7ea0a09a97d3005" dependencies = [ - "base64 0.21.2", + "base64 0.21.4", "bytes", "flex-error", "ics23", @@ -1393,7 +1376,7 @@ dependencies = [ [[package]] name = "ibc-relayer" -version = "0.25.0" +version = "0.26.0" dependencies = [ "anyhow", "async-stream", @@ -1420,7 +1403,7 @@ dependencies = [ "ibc-proto", "ibc-relayer-types", "ibc-telemetry", - "itertools", + "itertools 0.10.5", "moka", "num-bigint", "num-rational", @@ -1435,13 +1418,15 @@ dependencies = [ "serde_derive", "serde_json", "serial_test", - "sha2 0.10.7", + "sha2 0.10.8", "signature", "strum", "subtle-encoding", "tendermint", "tendermint-light-client", "tendermint-light-client-detector", + "tendermint-light-client-verifier", + "tendermint-proto", "tendermint-rpc", "tendermint-testgen", "test-log", @@ -1450,16 +1435,16 @@ dependencies = [ "tiny-keccak", "tokio", "tokio-stream", - "toml 0.7.6", + "toml 0.7.8", "tonic", "tracing", "tracing-subscriber", - "uuid 1.4.0", + "uuid 1.5.0", ] [[package]] name = "ibc-relayer-cli" -version = "1.6.0" +version = "1.7.0" dependencies = [ "abscissa_core", "clap", @@ -1480,7 +1465,7 @@ dependencies = [ "ibc-relayer-rest", "ibc-relayer-types", "ibc-telemetry", - "itertools", + "itertools 0.10.5", "once_cell", "oneline-eyre", "regex", @@ -1500,7 +1485,7 @@ dependencies = [ [[package]] name = "ibc-relayer-rest" -version = "0.25.0" +version = "0.26.0" dependencies = [ "axum", "crossbeam-channel 0.5.8", @@ -1509,23 +1494,21 @@ dependencies = [ "reqwest", "serde", "tokio", - "toml 0.7.6", + "toml 0.7.8", "tracing", ] [[package]] name = "ibc-relayer-types" -version = "0.25.0" +version = "0.26.0" dependencies = [ "bytes", "derive_more", - "dyn-clone", "env_logger", - "erased-serde", "flex-error", "ibc-proto", "ics23", - "itertools", + "itertools 0.10.5", "num-rational", "primitive-types", "prost", @@ -1548,7 +1531,7 @@ dependencies = [ [[package]] name = "ibc-telemetry" -version = "0.25.0" +version = "0.26.0" dependencies = [ "axum", "dashmap", @@ -1567,7 +1550,7 @@ dependencies = [ [[package]] name = "ibc-test-framework" -version = "0.25.0" +version = "0.26.0" dependencies = [ "color-eyre", "crossbeam-channel 0.5.8", @@ -1580,7 +1563,7 @@ dependencies = [ "ibc-relayer", "ibc-relayer-cli", "ibc-relayer-types", - "itertools", + "itertools 0.10.5", "once_cell", "prost", "rand", @@ -1588,11 +1571,11 @@ dependencies = [ "serde", "serde_json", "serde_yaml", - "sha2 0.10.7", + "sha2 0.10.8", "subtle-encoding", "tendermint-rpc", "tokio", - "toml 0.7.6", + "toml 0.7.8", "tonic", "tracing", "tracing-subscriber", @@ -1611,7 +1594,7 @@ dependencies = [ "prost", "ripemd", "serde", - "sha2 0.10.7", + "sha2 0.10.8", "sha3", ] @@ -1658,12 +1641,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" dependencies = [ "equivalent", - "hashbrown 0.14.0", + "hashbrown 0.14.1", ] [[package]] @@ -1676,26 +1659,6 @@ dependencies = [ "serde", ] -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi 0.3.2", - "libc", - "windows-sys 0.48.0", -] - [[package]] name = "ipnet" version = "2.8.0" @@ -1708,8 +1671,8 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ - "hermit-abi 0.3.2", - "rustix 0.38.4", + "hermit-abi 0.3.3", + "rustix", "windows-sys 0.48.0", ] @@ -1722,11 +1685,20 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + [[package]] name = "itoa" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "js-sys" @@ -1746,7 +1718,7 @@ dependencies = [ "cfg-if 1.0.0", "ecdsa", "elliptic-curve", - "sha2 0.10.7", + "sha2 0.10.8", ] [[package]] @@ -1766,27 +1738,21 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.147" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" - -[[package]] -name = "linux-raw-sys" -version = "0.3.8" +version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "linux-raw-sys" -version = "0.4.3" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ "autocfg", "scopeguard", @@ -1794,9 +1760,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "mach2" @@ -1818,9 +1784,9 @@ dependencies = [ [[package]] name = "matchit" -version = "0.7.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" [[package]] name = "maybe-uninit" @@ -1830,9 +1796,9 @@ checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" [[package]] name = "memchr" -version = "2.6.3" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memoffset" @@ -1871,9 +1837,9 @@ dependencies = [ [[package]] name = "moka" -version = "0.11.3" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa6e72583bf6830c956235bff0d5afec8cf2952f579ebad18ae7821a917d950f" +checksum = "d8017ec3548ffe7d4cef7ac0e12b044c01164a74c0f3119420faeaf13490ad8b" dependencies = [ "crossbeam-channel 0.5.8", "crossbeam-epoch", @@ -1882,13 +1848,12 @@ dependencies = [ "parking_lot", "quanta", "rustc_version", - "scheduled-thread-pool", "skeptic", "smallvec", "tagptr", "thiserror", "triomphe", - "uuid 1.4.0", + "uuid 1.5.0", ] [[package]] @@ -1903,9 +1868,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" dependencies = [ "autocfg", "num-integer", @@ -1949,9 +1914,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", ] @@ -1962,15 +1927,15 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.3.2", + "hermit-abi 0.3.3", "libc", ] [[package]] name = "object" -version = "0.31.1" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] @@ -2061,9 +2026,9 @@ dependencies = [ [[package]] name = "os_str_bytes" -version = "6.5.1" +version = "6.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d5d9eb14b174ee9aa2ef96dc2b94637a2d4b6e7cb873c7e171f0c20c6cf3eac" +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" [[package]] name = "overload" @@ -2089,22 +2054,22 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall 0.3.5", + "redox_syscall 0.4.1", "smallvec", - "windows-targets 0.48.1", + "windows-targets 0.48.5", ] [[package]] name = "paste" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4b27ab7be369122c218afc2079489cdcb4b517c0a3fc386ff11e1fedfcc2b35" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "pbkdf2" @@ -2150,29 +2115,29 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.38", ] [[package]] name = "pin-project-lite" -version = "0.2.10" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -2192,9 +2157,15 @@ dependencies = [ [[package]] name = "platforms" -version = "3.0.2" +version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d7ddaed09e0eb771a79ab0fd64609ba0afb0a8366421957936ad14cbd13630" +checksum = "4503fa043bf02cee09a9582e9554b4c6403b2ef55e4612e96561d294419429f8" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" @@ -2204,9 +2175,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "primitive-types" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f3486ccba82358b11a77516035647c34ba167dfa53312630de83b12bd4f3d66" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" dependencies = [ "fixed-hash", "impl-serde", @@ -2239,9 +2210,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.64" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -2278,10 +2249,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "265baba7fabd416cf5078179f7d2cbeca4ce7a9041111900675ea7c4cb8a4c32" dependencies = [ "anyhow", - "itertools", + "itertools 0.11.0", "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.38", ] [[package]] @@ -2328,9 +2299,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.29" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -2392,6 +2363,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "redox_users" version = "0.4.3" @@ -2405,14 +2385,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.5" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.3.8", - "regex-syntax 0.7.5", + "regex-automata 0.4.3", + "regex-syntax 0.8.2", ] [[package]] @@ -2426,13 +2406,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.8" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.7.5", + "regex-syntax 0.8.2", ] [[package]] @@ -2443,17 +2423,17 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.5" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "reqwest" -version = "0.11.21" +version = "0.11.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78fdbab6a7e1d7b13cc8ff10197f47986b41c639300cc3c8158cac7847c9bbef" +checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" dependencies = [ - "base64 0.21.2", + "base64 0.21.4", "bytes", "encoding_rs", "futures-core", @@ -2551,28 +2531,14 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" -dependencies = [ - "bitflags 1.3.2", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys 0.3.8", - "windows-sys 0.48.0", -] - -[[package]] -name = "rustix" -version = "0.38.4" +version = "0.38.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" +checksum = "745ecfa778e66b2b63c88a61cb36e0eea109e803b0b86bf9879fbc77c70e86ed" dependencies = [ - "bitflags 2.3.3", + "bitflags 2.4.1", "errno", "libc", - "linux-raw-sys 0.4.3", + "linux-raw-sys", "windows-sys 0.48.0", ] @@ -2606,14 +2572,14 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.2", + "base64 0.21.4", ] [[package]] name = "rustls-webpki" -version = "0.101.4" +version = "0.101.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d93931baf2d282fff8d3a532bbfd7653f734643161b87e3e01e59a04439bf0d" +checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe" dependencies = [ "ring", "untrusted", @@ -2621,15 +2587,15 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc31bd9b61a32c31f9650d18add92aa83a49ba979c143eefd27fe7177b05bd5f" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "ryu" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "same-file" @@ -2649,20 +2615,11 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "scheduled-thread-pool" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19" -dependencies = [ - "parking_lot", -] - [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sct" @@ -2676,9 +2633,9 @@ dependencies = [ [[package]] name = "sec1" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0aec48e813d6b90b15f0b8948af3c63483992dee44c03e9930b3eebdabe046e" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", "der", @@ -2721,9 +2678,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.1" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -2734,9 +2691,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" dependencies = [ "core-foundation-sys", "libc", @@ -2744,27 +2701,27 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.17" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" dependencies = [ "serde", ] [[package]] name = "serde" -version = "1.0.171" +version = "1.0.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9" +checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.11" +version = "0.11.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a16be4fe5320ade08736447e3198294a5ea9a6d44dde6f35f0a5e06859c427a" +checksum = "ab33ec92f677585af6d88c65593ae2375adde54efdbf16d597f2cbc7a6d368ff" dependencies = [ "serde", ] @@ -2781,20 +2738,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.171" +version = "1.0.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" +checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.38", ] [[package]] name = "serde_json" -version = "1.0.102" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5062a995d481b2308b6064e9af76011f2921c35f97b0468811ed9f6cd91dfed" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" dependencies = [ "itoa", "ryu", @@ -2803,9 +2760,9 @@ dependencies = [ [[package]] name = "serde_path_to_error" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc4422959dd87a76cb117c191dcbffc20467f06c9100b76721dab370f24d3a" +checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335" dependencies = [ "itoa", "serde", @@ -2813,13 +2770,13 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.14" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d89a8107374290037607734c0b73a85db7ed80cae314b3c5791f192a496e731" +checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.38", ] [[package]] @@ -2845,11 +2802,11 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.9.22" +version = "0.9.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "452e67b9c20c37fa79df53201dc03839651086ed9bbe92b3ca585ca9fdaa7d85" +checksum = "1a49e178e4452f45cb61d0cd8cebc1b0fafd3e41929e996cef79aa3aca91f574" dependencies = [ - "indexmap 2.0.0", + "indexmap 2.0.2", "itoa", "ryu", "serde", @@ -2878,14 +2835,14 @@ checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.38", ] [[package]] name = "sha1" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if 1.0.0", "cpufeatures", @@ -2907,9 +2864,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if 1.0.0", "cpufeatures", @@ -2928,9 +2885,9 @@ dependencies = [ [[package]] name = "sharded-slab" -version = "0.1.4" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ "lazy_static", ] @@ -2993,18 +2950,18 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] [[package]] name = "smallvec" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "socket2" @@ -3016,6 +2973,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "socket2" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "spin" version = "0.5.2" @@ -3055,15 +3022,15 @@ dependencies = [ [[package]] name = "strum_macros" -version = "0.25.1" +version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6069ca09d878a33f883cc06aaa9718ede171841d3832450354410b718b097232" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" dependencies = [ "heck", "proc-macro2", "quote", "rustversion", - "syn 2.0.25", + "syn 2.0.38", ] [[package]] @@ -3100,9 +3067,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.25" +version = "2.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e3fc8c0c74267e2df136e5e5fb656a464158aa57624053375eb9c8c6e25ae2" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" dependencies = [ "proc-macro2", "quote", @@ -3156,15 +3123,14 @@ checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" [[package]] name = "tempfile" -version = "3.6.0" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ - "autocfg", "cfg-if 1.0.0", "fastrand", "redox_syscall 0.3.5", - "rustix 0.37.23", + "rustix", "windows-sys 0.48.0", ] @@ -3190,7 +3156,7 @@ dependencies = [ "serde_bytes", "serde_json", "serde_repr", - "sha2 0.10.7", + "sha2 0.10.8", "signature", "subtle", "subtle-encoding", @@ -3344,22 +3310,22 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64" dependencies = [ "winapi-util", ] [[package]] name = "test-log" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9601d162c1d77e62c1ea0bc8116cd1caf143ce3af947536c3c9052a1677fe0c" +checksum = "f66edd6b6cd810743c0c71e1d085e92b01ce6a72782032e3f794c8284fe4bcdd" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.38", ] [[package]] @@ -3370,22 +3336,22 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" -version = "1.0.43" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" +checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.43" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" +checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.38", ] [[package]] @@ -3400,10 +3366,12 @@ dependencies = [ [[package]] name = "time" -version = "0.3.22" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" +checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" dependencies = [ + "deranged", + "powerfmt", "serde", "time-core", "time-macros", @@ -3411,15 +3379,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.9" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" dependencies = [ "time-core", ] @@ -3436,7 +3404,7 @@ dependencies = [ "pbkdf2", "rand", "rustc-hash", - "sha2 0.10.7", + "sha2 0.10.8", "thiserror", "unicode-normalization", "wasm-bindgen", @@ -3469,11 +3437,10 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.29.1" +version = "1.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" +checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" dependencies = [ - "autocfg", "backtrace", "bytes", "libc", @@ -3482,7 +3449,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.5.4", "tokio-macros", "windows-sys 0.48.0", ] @@ -3505,7 +3472,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.38", ] [[package]] @@ -3531,9 +3498,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d" dependencies = [ "bytes", "futures-core", @@ -3554,9 +3521,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" dependencies = [ "serde", "serde_spanned", @@ -3575,11 +3542,11 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.19.12" +version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c500344a19072298cd05a7224b3c0c629348b78692bf48466c5238656e315a78" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.0.0", + "indexmap 2.0.2", "serde", "serde_spanned", "toml_datetime", @@ -3595,7 +3562,7 @@ dependencies = [ "async-stream", "async-trait", "axum", - "base64 0.21.2", + "base64 0.21.4", "bytes", "h2", "http", @@ -3651,11 +3618,10 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if 1.0.0", "log", "pin-project-lite", "tracing-attributes", @@ -3664,20 +3630,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.38", ] [[package]] name = "tracing-core" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", "valuable", @@ -3769,9 +3735,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "uint" @@ -3787,9 +3753,9 @@ dependencies = [ [[package]] name = "unicase" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" dependencies = [ "version_check", ] @@ -3802,9 +3768,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.10" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" @@ -3817,9 +3783,9 @@ dependencies = [ [[package]] name = "unicode-width" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" [[package]] name = "unicode-xid" @@ -3829,9 +3795,9 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "unsafe-libyaml" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1865806a559042e51ab5414598446a5871b561d21b6764f2eabb0dd481d880a6" +checksum = "f28467d3e1d3c6586d8f25fa243f544f5800fec42d97032474e17222c2b75cfa" [[package]] name = "untrusted" @@ -3852,9 +3818,9 @@ dependencies = [ [[package]] name = "urlencoding" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8db7427f936968176eaa7cdf81b7f98b980b18495ec28f1b5791ac3bfe3eea9" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" [[package]] name = "utf-8" @@ -3876,9 +3842,9 @@ checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" [[package]] name = "uuid" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d023da39d1fde5a8a3fe1f3e01ca9632ada0a63e9797de55a879d6e2236277be" +checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" dependencies = [ "getrandom", ] @@ -3906,9 +3872,9 @@ dependencies = [ [[package]] name = "walkdir" -version = "2.3.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" dependencies = [ "same-file", "winapi-util", @@ -3950,7 +3916,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.38", "wasm-bindgen-shared", ] @@ -3984,7 +3950,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.38", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4029,9 +3995,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi", ] @@ -4057,7 +4023,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.1", + "windows-targets 0.48.5", ] [[package]] @@ -4077,17 +4043,17 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.1" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] @@ -4098,9 +4064,9 @@ checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" @@ -4110,9 +4076,9 @@ checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" @@ -4122,9 +4088,9 @@ checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" @@ -4134,9 +4100,9 @@ checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" @@ -4146,9 +4112,9 @@ checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" @@ -4158,9 +4124,9 @@ checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" @@ -4170,15 +4136,15 @@ checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "winnow" -version = "0.4.9" +version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81a2094c43cc94775293eaa0e499fbc30048a6d824ac82c0351a8c0bf9112529" +checksum = "a3b801d0e0a6726477cc207f60162da452f3a95adb368399bef20a946e06f65c" dependencies = [ "memchr", ] @@ -4210,5 +4176,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.38", ] diff --git a/README.md b/README.md index 4c6bda0434..0ffea32109 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Cosmos ecosystem][cosmos-shield]][cosmos-link] [![Build Status][build-image]][build-link] -[![End to End testing][e2e-image]][e2e-link] +[![Integration tests][test-image]][test-link] [![Apache 2.0 Licensed][license-image]][license-link] ![Rust Stable][rustc-image] ![Rust 1.70+][rustc-version] @@ -116,8 +116,8 @@ Unless required by applicable law or agreed to in writing, software distributed [build-image]: https://github.com/informalsystems/hermes/workflows/Rust/badge.svg [build-link]: https://github.com/informalsystems/hermes/actions?query=workflow%3ARust -[e2e-image]: https://github.com/informalsystems/hermes/workflows/End%20to%20End%20testing/badge.svg -[e2e-link]: https://github.com/informalsystems/hermes/actions?query=workflow%3A%22End+to+End+testing%22 +[test-image]: https://github.com/informalsystems/hermes/workflows/Integration/badge.svg +[test-link]: https://github.com/informalsystems/hermes/actions?query=workflow%3A%22Integration%22 [license-image]: https://img.shields.io/badge/license-Apache_2.0-blue.svg [license-link]: https://github.com/informalsystems/hermes/blob/master/LICENSE [rustc-image]: https://img.shields.io/badge/rustc-stable-blue.svg diff --git a/ci/misbehaviour-ics/double_sign_test.sh b/ci/misbehaviour-ics/double_sign_test.sh new file mode 100644 index 0000000000..e38319e7f8 --- /dev/null +++ b/ci/misbehaviour-ics/double_sign_test.sh @@ -0,0 +1,585 @@ +#!/bin/bash +# shellcheck disable=2086,2004 + +set -eu + +DEBUG=${DEBUG:-false} + +if [ "$DEBUG" = true ]; then + set -x +fi + +# User balance of stake tokens +USER_COINS="100000000000stake" +# Amount of stake tokens staked +STAKE="100000000stake" +# Node IP address +NODE_IP="127.0.0.1" + +# Home directory +HOME_DIR="/tmp/hermes-ics-double-sign" + +# Hermes debug +if [ "$DEBUG" = true ]; then + HERMES_DEBUG="--debug=rpc" +else + HERMES_DEBUG="" +fi +# Hermes config +HERMES_CONFIG="$HOME_DIR/hermes.toml" +# Hermes binary +HERMES_BIN="cargo run -q --bin hermes -- $HERMES_DEBUG --config $HERMES_CONFIG" + +# Validator moniker +MONIKERS=("coordinator" "alice" "bob") +LEAD_VALIDATOR_MONIKER="coordinator" + +# Hermes will connect to this node on both provider and consumer +HERMES_VALIDATOR_MONIKER="bob" + +PROV_NODES_ROOT_DIR=${HOME_DIR}/nodes/provider +CONS_NODES_ROOT_DIR=${HOME_DIR}/nodes/consumer + +# Base port. Ports assigned after these ports sequentially by nodes. +RPC_LADDR_BASEPORT=29170 +P2P_LADDR_BASEPORT=29180 +GRPC_LADDR_BASEPORT=29190 +NODE_ADDRESS_BASEPORT=29200 +PPROF_LADDR_BASEPORT=29210 +CLIENT_BASEPORT=29220 + + +# Clean start +pkill -f interchain-security-pd &> /dev/null || true +pkill -f interchain-security-cd &> /dev/null || true +pkill -f hermes &> /dev/null || true +sleep 1 + +mkdir -p "${HOME_DIR}" +rm -rf "${PROV_NODES_ROOT_DIR}" +rm -rf "${CONS_NODES_ROOT_DIR}" + +# Let lead validator create genesis file +LEAD_VALIDATOR_PROV_DIR=${PROV_NODES_ROOT_DIR}/provider-${LEAD_VALIDATOR_MONIKER} +LEAD_VALIDATOR_CONS_DIR=${CONS_NODES_ROOT_DIR}/consumer-${LEAD_VALIDATOR_MONIKER} +LEAD_PROV_KEY=${LEAD_VALIDATOR_MONIKER}-key +LEAD_PROV_LISTEN_ADDR=tcp://${NODE_IP}:${RPC_LADDR_BASEPORT} + +for index in "${!MONIKERS[@]}" +do + MONIKER=${MONIKERS[$index]} + # validator key + PROV_KEY=${MONIKER}-key + PROV_KEY2=${MONIKER}-key2 + + # home directory of this validator on provider + PROV_NODE_DIR=${PROV_NODES_ROOT_DIR}/provider-${MONIKER} + + # home directory of this validator on consumer + CONS_NODE_DIR=${CONS_NODES_ROOT_DIR}/consumer-${MONIKER} + + # Build genesis file and node directory structure + interchain-security-pd init $MONIKER --chain-id provider --home ${PROV_NODE_DIR} + jq ".app_state.gov.voting_params.voting_period = \"10s\" | .app_state.staking.params.unbonding_time = \"86400s\"" \ + ${PROV_NODE_DIR}/config/genesis.json > \ + ${PROV_NODE_DIR}/edited_genesis.json && mv ${PROV_NODE_DIR}/edited_genesis.json ${PROV_NODE_DIR}/config/genesis.json + + + sleep 1 + + # Create account keypair + interchain-security-pd keys add $PROV_KEY --home ${PROV_NODE_DIR} --keyring-backend test --output json > ${PROV_NODE_DIR}/${PROV_KEY}.json 2>&1 + interchain-security-pd keys add $PROV_KEY2 --home ${PROV_NODE_DIR} --keyring-backend test --output json > ${PROV_NODE_DIR}/${PROV_KEY2}.json 2>&1 + sleep 1 + + # copy genesis in, unless this validator is the lead validator + if [ $MONIKER != $LEAD_VALIDATOR_MONIKER ]; then + cp ${LEAD_VALIDATOR_PROV_DIR}/config/genesis.json ${PROV_NODE_DIR}/config/genesis.json + fi + + # Add stake to user + PROV_ACCOUNT_ADDR=$(jq -r '.address' ${PROV_NODE_DIR}/${PROV_KEY}.json) + interchain-security-pd add-genesis-account $PROV_ACCOUNT_ADDR $USER_COINS --home ${PROV_NODE_DIR} --keyring-backend test + + PROV_ACCOUNT_ADDR2=$(jq -r '.address' ${PROV_NODE_DIR}/${PROV_KEY2}.json) + interchain-security-pd add-genesis-account $PROV_ACCOUNT_ADDR2 $USER_COINS --home ${PROV_NODE_DIR} --keyring-backend test + sleep 1 + + # copy genesis out, unless this validator is the lead validator + if [ $MONIKER != $LEAD_VALIDATOR_MONIKER ]; then + cp ${PROV_NODE_DIR}/config/genesis.json ${LEAD_VALIDATOR_PROV_DIR}/config/genesis.json + fi + + PPROF_LADDR=${NODE_IP}:$(($PPROF_LADDR_BASEPORT + $index)) + P2P_LADDR_PORT=$(($P2P_LADDR_BASEPORT + $index)) + + # adjust configs of this node + sed -i -r 's/timeout_commit = "5s"/timeout_commit = "3s"/g' ${PROV_NODE_DIR}/config/config.toml + sed -i -r 's/timeout_propose = "3s"/timeout_propose = "1s"/g' ${PROV_NODE_DIR}/config/config.toml + + # make address book non-strict. necessary for this setup + sed -i -r 's/addr_book_strict = true/addr_book_strict = false/g' ${PROV_NODE_DIR}/config/config.toml + + # avoid port double binding + sed -i -r "s/pprof_laddr = \"localhost:6060\"/pprof_laddr = \"${PPROF_LADDR}\"/g" ${PROV_NODE_DIR}/config/config.toml + + # allow duplicate IP addresses (all nodes are on the same machine) + sed -i -r 's/allow_duplicate_ip = false/allow_duplicate_ip = true/g' ${PROV_NODE_DIR}/config/config.toml +done + +for MONIKER in "${MONIKERS[@]}" +do + # validator key + PROV_KEY=${MONIKER}-key + + # home directory of this validator on provider + PROV_NODE_DIR=${PROV_NODES_ROOT_DIR}/provider-${MONIKER} + + # copy genesis in, unless this validator is the lead validator + if [ $MONIKER != $LEAD_VALIDATOR_MONIKER ]; then + cp ${LEAD_VALIDATOR_PROV_DIR}/config/genesis.json* ${PROV_NODE_DIR}/config/genesis.json + fi + + # Stake 1/1000 user's coins + interchain-security-pd gentx $PROV_KEY $STAKE --chain-id provider --home ${PROV_NODE_DIR} --keyring-backend test --moniker $MONIKER + sleep 1 + + # Copy gentxs to the lead validator for possible future collection. + # Obviously we don't need to copy the first validator's gentx to itself + if [ $MONIKER != $LEAD_VALIDATOR_MONIKER ]; then + cp ${PROV_NODE_DIR}/config/gentx/* ${LEAD_VALIDATOR_PROV_DIR}/config/gentx/ + fi +done + +# Collect genesis transactions with lead validator +interchain-security-pd collect-gentxs --home ${LEAD_VALIDATOR_PROV_DIR} --gentx-dir ${LEAD_VALIDATOR_PROV_DIR}/config/gentx/ + +sleep 1 + + +for index in "${!MONIKERS[@]}" +do + MONIKER=${MONIKERS[$index]} + + PERSISTENT_PEERS="" + + for peer_index in "${!MONIKERS[@]}" + do + if [ $index == $peer_index ]; then + continue + fi + PEER_MONIKER=${MONIKERS[$peer_index]} + + PEER_PROV_NODE_DIR=${PROV_NODES_ROOT_DIR}/provider-${PEER_MONIKER} + + PEER_NODE_ID=$(interchain-security-pd tendermint show-node-id --home ${PEER_PROV_NODE_DIR}) + + PEER_P2P_LADDR_PORT=$(($P2P_LADDR_BASEPORT + $peer_index)) + PERSISTENT_PEERS="$PERSISTENT_PEERS,$PEER_NODE_ID@${NODE_IP}:${PEER_P2P_LADDR_PORT}" + done + + # remove trailing comma from persistent peers + PERSISTENT_PEERS=${PERSISTENT_PEERS:1} + + # validator key + PROV_KEY=${MONIKER}-key + PROV_KEY2=${MONIKER}-key2 + + # home directory of this validator on provider + PROV_NODE_DIR=${PROV_NODES_ROOT_DIR}/provider-${MONIKER} + + # home directory of this validator on consumer + CONS_NODE_DIR=${PROV_NODES_ROOT_DIR}/consumer-${MONIKER} + + # copy genesis in, unless this validator is already the lead validator and thus it already has its genesis + if [ $MONIKER != $LEAD_VALIDATOR_MONIKER ]; then + cp ${LEAD_VALIDATOR_PROV_DIR}/config/genesis.json ${PROV_NODE_DIR}/config/genesis.json + fi + + RPC_LADDR_PORT=$(($RPC_LADDR_BASEPORT + $index)) + P2P_LADDR_PORT=$(($P2P_LADDR_BASEPORT + $index)) + GRPC_LADDR_PORT=$(($GRPC_LADDR_BASEPORT + $index)) + NODE_ADDRESS_PORT=$(($NODE_ADDRESS_BASEPORT + $index)) + + if [ $MONIKER == $HERMES_VALIDATOR_MONIKER ]; then + PRPC_LADDR_PORT=$RPC_LADDR_PORT + PGRPC_LADDR_PORT=$GRPC_LADDR_PORT + fi + # Start gaia + interchain-security-pd start \ + --home ${PROV_NODE_DIR} \ + --p2p.persistent_peers ${PERSISTENT_PEERS} \ + --rpc.laddr tcp://${NODE_IP}:${RPC_LADDR_PORT} \ + --grpc.address ${NODE_IP}:${GRPC_LADDR_PORT} \ + --address tcp://${NODE_IP}:${NODE_ADDRESS_PORT} \ + --p2p.laddr tcp://${NODE_IP}:${P2P_LADDR_PORT} \ + --grpc-web.enable=false &> ${PROV_NODE_DIR}/logs & + + sleep 5 +done + +# Build consumer chain proposal file +tee ${LEAD_VALIDATOR_PROV_DIR}/consumer-proposal.json< ${CONS_NODE_DIR}/${PROV_KEY}.json 2>&1 + interchain-security-cd keys add $PROV_KEY2 --home ${CONS_NODE_DIR} --keyring-backend test --output json > ${CONS_NODE_DIR}/${PROV_KEY2}.json 2>&1 + sleep 1 + + # copy genesis in, unless this validator is the lead validator + if [ $MONIKER != $LEAD_VALIDATOR_MONIKER ]; then + cp ${LEAD_VALIDATOR_CONS_DIR}/config/genesis.json ${CONS_NODE_DIR}/config/genesis.json + fi + + # Add stake to user + CONS_ACCOUNT_ADDR=$(jq -r '.address' ${CONS_NODE_DIR}/${PROV_KEY}.json) + interchain-security-cd add-genesis-account $CONS_ACCOUNT_ADDR $USER_COINS --home ${CONS_NODE_DIR} + CONS_ACCOUNT_ADDR2=$(jq -r '.address' ${CONS_NODE_DIR}/${PROV_KEY2}.json) + interchain-security-cd add-genesis-account $CONS_ACCOUNT_ADDR2 $USER_COINS --home ${CONS_NODE_DIR} + sleep 10 + + ### this probably doesnt have to be done for each node + # Add consumer genesis states to genesis file + RPC_LADDR_PORT=$(($RPC_LADDR_BASEPORT + $index)) + RPC_LADDR=tcp://${NODE_IP}:${RPC_LADDR_PORT} + interchain-security-pd query provider consumer-genesis consumer --home ${PROV_NODE_DIR} --node ${RPC_LADDR} -o json > consumer_gen.json + jq -s '.[0].app_state.ccvconsumer = .[1] | .[0]' ${CONS_NODE_DIR}/config/genesis.json consumer_gen.json > ${CONS_NODE_DIR}/edited_genesis.json \ + && mv ${CONS_NODE_DIR}/edited_genesis.json ${CONS_NODE_DIR}/config/genesis.json + rm consumer_gen.json + ### + + # copy genesis out, unless this validator is the lead validator + if [ $MONIKER != $LEAD_VALIDATOR_MONIKER ]; then + cp ${CONS_NODE_DIR}/config/genesis.json ${LEAD_VALIDATOR_CONS_DIR}/config/genesis.json + fi + + PPROF_LADDR=${NODE_IP}:$(($PPROF_LADDR_BASEPORT + ${#MONIKERS[@]} + $index)) + P2P_LADDR_PORT=$(($P2P_LADDR_BASEPORT + ${#MONIKERS[@]} + $index)) + + # adjust configs of this node + sed -i -r 's/timeout_commit = "5s"/timeout_commit = "3s"/g' ${CONS_NODE_DIR}/config/config.toml + sed -i -r 's/timeout_propose = "3s"/timeout_propose = "1s"/g' ${CONS_NODE_DIR}/config/config.toml + + # make address book non-strict. necessary for this setup + sed -i -r 's/addr_book_strict = true/addr_book_strict = false/g' ${CONS_NODE_DIR}/config/config.toml + + # avoid port double binding + sed -i -r "s/pprof_laddr = \"localhost:6060\"/pprof_laddr = \"${PPROF_LADDR}\"/g" ${CONS_NODE_DIR}/config/config.toml + + # allow duplicate IP addresses (all nodes are on the same machine) + sed -i -r 's/allow_duplicate_ip = false/allow_duplicate_ip = true/g' ${CONS_NODE_DIR}/config/config.toml + + # Create validator states + echo '{"height": "0","round": 0,"step": 0}' > ${CONS_NODE_DIR}/data/priv_validator_state.json + + # Copy validator key files + cp ${PROV_NODE_DIR}/config/priv_validator_key.json ${CONS_NODE_DIR}/config/priv_validator_key.json + cp ${PROV_NODE_DIR}/config/node_key.json ${CONS_NODE_DIR}/config/node_key.json + + # Set default client port + CLIENT_PORT=$(($CLIENT_BASEPORT + ${#MONIKERS[@]} + $index)) + sed -i -r "/node =/ s/= .*/= \"tcp:\/\/${NODE_IP}:${CLIENT_PORT}\"/" ${CONS_NODE_DIR}/config/client.toml + +done + +sleep 1 + + +for index in "${!MONIKERS[@]}" +do + MONIKER=${MONIKERS[$index]} + + PERSISTENT_PEERS="" + + for peer_index in "${!MONIKERS[@]}" + do + if [ $index == $peer_index ]; then + continue + fi + PEER_MONIKER=${MONIKERS[$peer_index]} + + PEER_CONS_NODE_DIR=${CONS_NODES_ROOT_DIR}/consumer-${PEER_MONIKER} + + PEER_NODE_ID=$(interchain-security-pd tendermint show-node-id --home ${PEER_CONS_NODE_DIR}) + + PEER_P2P_LADDR_PORT=$(($P2P_LADDR_BASEPORT + ${#MONIKERS[@]} + $peer_index)) + PERSISTENT_PEERS="$PERSISTENT_PEERS,$PEER_NODE_ID@${NODE_IP}:${PEER_P2P_LADDR_PORT}" + done + + # remove trailing comma from persistent peers + PERSISTENT_PEERS=${PERSISTENT_PEERS:1} + + # validator key + PROV_KEY=${MONIKER}-key + + # home directory of this validator on provider + PROV_NODE_DIR=${PROV_NODES_ROOT_DIR}/provider-${MONIKER} + + # home directory of this validator on consumer + CONS_NODE_DIR=${CONS_NODES_ROOT_DIR}/consumer-${MONIKER} + + # copy genesis in, unless this validator is already the lead validator and thus it already has its genesis + if [ $MONIKER != $LEAD_VALIDATOR_MONIKER ]; then + cp ${LEAD_VALIDATOR_CONS_DIR}/config/genesis.json ${CONS_NODE_DIR}/config/genesis.json + fi + + RPC_LADDR_PORT=$(($RPC_LADDR_BASEPORT + ${#MONIKERS[@]} + $index)) + P2P_LADDR_PORT=$(($P2P_LADDR_BASEPORT + ${#MONIKERS[@]} + $index)) + GRPC_LADDR_PORT=$(($GRPC_LADDR_BASEPORT + ${#MONIKERS[@]} + $index)) + NODE_ADDRESS_PORT=$(($NODE_ADDRESS_BASEPORT + ${#MONIKERS[@]} + $index)) + + if [ $MONIKER == $HERMES_VALIDATOR_MONIKER ]; then + CRPC_LADDR_PORT=$RPC_LADDR_PORT + CGRPC_LADDR_PORT=$GRPC_LADDR_PORT + fi + # Start gaia + interchain-security-cd start \ + --home ${CONS_NODE_DIR} \ + --p2p.persistent_peers ${PERSISTENT_PEERS} \ + --rpc.laddr tcp://${NODE_IP}:${RPC_LADDR_PORT} \ + --grpc.address ${NODE_IP}:${GRPC_LADDR_PORT} \ + --address tcp://${NODE_IP}:${NODE_ADDRESS_PORT} \ + --p2p.laddr tcp://${NODE_IP}:${P2P_LADDR_PORT} \ + --grpc-web.enable=false &> ${CONS_NODE_DIR}/logs & + + sleep 6 +done + +## Cause double signing + +# create directory for double signing node +mkdir $CONS_NODES_ROOT_DIR/consumer-bob-sybil/ +cp -r $CONS_NODES_ROOT_DIR/consumer-bob/* $CONS_NODES_ROOT_DIR/consumer-bob-sybil + +# clear state in consumer-bob-sybil +echo '{"height": "0","round": 0,"step": 0,"signature":"","signbytes":""}' > $CONS_NODES_ROOT_DIR/consumer-bob-sybil/data/priv_validator_state.json + +# add new node key to sybil +# key was generated using gaiad init +# if the node key is not unique, double signing cannot be achieved +# and errors such as this can be seen in the terminal +# 5:54PM ERR found conflicting vote from ourselves; did you unsafe_reset a validator? height=1961 module=consensus round=0 type=2 +# 5:54PM ERR failed to process message err="conflicting votes from validator C888306A908A217B9A943D1DAD8790044D0947A4" +echo '{"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"tj55by/yYwruSz4NxsOG9y9k2WrPvKLXKQdz/9jL9Uptmi647OYpcisjwf92TyA+wCUYVDOgW7D53Q+638l9/w=="}}' > $CONS_NODES_ROOT_DIR/consumer-bob-sybil/config/node_key.json + +# does not use persistent peers; will do a lookup in genesis.json to find peers +#ARGS="--address tcp://$CHAIN_PREFIX.252:26655 --rpc.laddr tcp://$CHAIN_PREFIX.252:26658 --grpc.address $CHAIN_PREFIX.252:9091 --log_level trace --p2p.laddr tcp://$CHAIN_PREFIX.252:26656 --grpc-web.enable=false" + +# start double signing node - it should not talk to the node with the same key +#ip netns exec $HOME/nodes/consumer/consumer-bob-sybil $BIN $ARGS --home $HOME/nodes/consumer/consumer-bob-sybil start &> $HOME/nodes/consumer/consumer-bob-sybil/logs & + +# Start gaia +interchain-security-cd start \ + --home $CONS_NODES_ROOT_DIR/consumer-bob-sybil \ + --p2p.persistent_peers ${PERSISTENT_PEERS} \ + --rpc.laddr tcp://${NODE_IP}:29179 \ + --grpc.address ${NODE_IP}:29199 \ + --address tcp://${NODE_IP}:29209 \ + --p2p.laddr tcp://${NODE_IP}:29189 \ + --grpc-web.enable=false &> $CONS_NODES_ROOT_DIR/consumer-bob-sybil/logs & + +# Setup Hermes config file + +tee $HERMES_CONFIG< $HOME_DIR/hermes-start-logs.txt & + +$HERMES_BIN evidence --chain consumer --key-name evidence &> $HOME_DIR/hermes-evidence-logs.txt & + +for _ in $(seq 1 10) +do + sleep 5 + + MSG="successfully submitted double voting evidence to chain" + + if grep -c "$MSG" $HOME_DIR/hermes-evidence-logs.txt; then + echo "[SUCCESS] Successfully submitted double voting evidence to provider chain" + exit 0 + fi +done + +echo "[ERROR] Failed to submit double voting evidence to provider chain" +echo "" +echo "---------------------------------------------------------------" +echo "Hermes start logs:" +cat $HOME_DIR/hermes-start-logs.txt +echo "---------------------------------------------------------------" +echo "Hermes evidence logs:" +cat $HOME_DIR/hermes-evidence-logs.txt +echo "---------------------------------------------------------------" + +exit 1 + diff --git a/ci/misbehaviour-ics/light_client_attack_freeze_test.sh b/ci/misbehaviour-ics/light_client_attack_freeze_test.sh new file mode 100644 index 0000000000..5545dddead --- /dev/null +++ b/ci/misbehaviour-ics/light_client_attack_freeze_test.sh @@ -0,0 +1,512 @@ +#!/bin/bash +# shellcheck disable=2086 + +set -eu + +DEBUG=${DEBUG:-false} + +if [ "$DEBUG" = true ]; then + set -x +fi + +diag() { + echo ">> +>> $* +>>" 1>&2 +} + +waiting() { + secs=$1 + shift + msg="$*" + while [ $secs -gt 0 ] + do + echo -ne "|| Waiting $msg (${secs}s)\033[0K\r" + sleep 1 + : $((secs--)) + done + echo "|| Waiting $msg (done)" +} + + +# User balance of stake tokens +USER_COINS="100000000000stake" +# Amount of stake tokens staked +STAKE="100000000stake" +# Amount of stake tokens staked +STAKE2="4000000stake" +# Node IP address +NODE_IP="127.0.0.1" + +# Home directory +HOME_DIR="/tmp/hermes-ics-misbehaviour" + +# Hermes debug +if [ "$DEBUG" = true ]; then + HERMES_DEBUG="--debug=rpc" +else + HERMES_DEBUG="" +fi + +# Hermes config +HERMES_CONFIG="$HOME_DIR/hermes.toml" +HERMES_CONFIG_FORK="$HOME_DIR/hermes-fork.toml" +# Hermes binary +HERMES_BIN="cargo run -q --bin hermes -- $HERMES_DEBUG --config $HERMES_CONFIG" +HERMES_BIN_FORK="cargo run -q --bin hermes -- $HERMES_DEBUG --config $HERMES_CONFIG_FORK" + +# Validator moniker +MONIKER="coordinator" +MONIKER_SUB="sub" + +# Validator directory +PROV_NODE_DIR=${HOME_DIR}/provider-${MONIKER} +PROV_NODE_SUB_DIR=${HOME_DIR}/provider-${MONIKER_SUB} +CONS_NODE_DIR=${HOME_DIR}/consumer-${MONIKER} +CONS_NODE_SUB_DIR=${HOME_DIR}/consumer-${MONIKER_SUB} +CONS_FORK_NODE_DIR=${HOME_DIR}/consumer-fork-${MONIKER} + +# Coordinator key +PROV_KEY=${MONIKER}-key +PROV_KEY_SUB=${MONIKER_SUB}-key + + +# Clean start +pkill -f interchain-security-pd &> /dev/null || true +pkill -f interchain-security-cd &> /dev/null || true +pkill -f hermes &> /dev/null || true + +mkdir -p "${HOME_DIR}" +rm -rf "${PROV_NODE_DIR}" +rm -rf "${PROV_NODE_SUB_DIR}" +rm -rf "${CONS_NODE_DIR}" +rm -rf "${CONS_NODE_SUB_DIR}" +rm -rf "${CONS_FORK_NODE_DIR}" + +# Build genesis file and node directory structure +interchain-security-pd init $MONIKER --chain-id provider --home ${PROV_NODE_DIR} +jq ".app_state.gov.voting_params.voting_period = \"3s\" | .app_state.staking.params.unbonding_time = \"86400s\"" \ + ${PROV_NODE_DIR}/config/genesis.json > \ + ${PROV_NODE_DIR}/edited_genesis.json && mv ${PROV_NODE_DIR}/edited_genesis.json ${PROV_NODE_DIR}/config/genesis.json + +# Create account keypair +interchain-security-pd keys add $PROV_KEY --home ${PROV_NODE_DIR} --keyring-backend test --output json > ${PROV_NODE_DIR}/${PROV_KEY}.json 2>&1 + +# Add stake to user +PROV_ACCOUNT_ADDR=$(jq -r '.address' ${PROV_NODE_DIR}/${PROV_KEY}.json) +interchain-security-pd add-genesis-account "$PROV_ACCOUNT_ADDR" $USER_COINS --home ${PROV_NODE_DIR} --keyring-backend test + +# Stake 1/1000 user's coins +interchain-security-pd gentx $PROV_KEY $STAKE --chain-id provider --home ${PROV_NODE_DIR} --keyring-backend test --moniker $MONIKER + +## config second node + +rm -rf ${PROV_NODE_SUB_DIR} + +# Build genesis file and node directory structure +interchain-security-pd init $MONIKER_SUB --chain-id provider --home ${PROV_NODE_SUB_DIR} + +# Create account keypair +interchain-security-pd keys add $PROV_KEY_SUB --home ${PROV_NODE_SUB_DIR} --keyring-backend test --output json > ${PROV_NODE_SUB_DIR}/${PROV_KEY_SUB}.json 2>&1 + +cp ${PROV_NODE_DIR}/config/genesis.json ${PROV_NODE_SUB_DIR}/config/genesis.json + +# Add stake to user +PROV_ACCOUNT_ADDR=$(jq -r '.address' ${PROV_NODE_SUB_DIR}/${PROV_KEY_SUB}.json) +interchain-security-pd add-genesis-account "$PROV_ACCOUNT_ADDR" $USER_COINS --home ${PROV_NODE_SUB_DIR} --keyring-backend test + +cp -r ${PROV_NODE_DIR}/config/gentx/ ${PROV_NODE_SUB_DIR}/config/gentx/ + +# # Stake 1/1000 user's coins +interchain-security-pd gentx $PROV_KEY_SUB $STAKE2 --chain-id provider --home ${PROV_NODE_SUB_DIR} --keyring-backend test --moniker $MONIKER_SUB + +interchain-security-pd collect-gentxs --home ${PROV_NODE_SUB_DIR} --gentx-dir ${PROV_NODE_SUB_DIR}/config/gentx/ + +cp ${PROV_NODE_SUB_DIR}/config/genesis.json ${PROV_NODE_DIR}/config/genesis.json + + +# Start nodes + +sed -i -r "/node =/ s/= .*/= \"tcp:\/\/${NODE_IP}:26658\"/" ${PROV_NODE_DIR}/config/client.toml +sed -i -r 's/timeout_commit = "5s"/timeout_commit = "3s"/g' ${PROV_NODE_DIR}/config/config.toml +sed -i -r 's/timeout_propose = "3s"/timeout_propose = "1s"/g' ${PROV_NODE_DIR}/config/config.toml +sed -i -r 's/fast_sync = true/fast_sync = false/g' ${PROV_NODE_DIR}/config/config.toml + +# Start gaia +interchain-security-pd start \ + --home ${PROV_NODE_DIR} \ + --rpc.laddr tcp://${NODE_IP}:26658 \ + --grpc.address ${NODE_IP}:9091 \ + --address tcp://${NODE_IP}:26655 \ + --p2p.laddr tcp://${NODE_IP}:26656 \ + --grpc-web.enable=false &> ${PROV_NODE_DIR}/logs & + +waiting 10 "for provider node to start" + +sed -i -r "/node =/ s/= .*/= \"tcp:\/\/${NODE_IP}:26628\"/" ${PROV_NODE_SUB_DIR}/config/client.toml +sed -i -r 's/timeout_commit = "5s"/timeout_commit = "3s"/g' ${PROV_NODE_SUB_DIR}/config/config.toml +sed -i -r 's/timeout_propose = "3s"/timeout_propose = "1s"/g' ${PROV_NODE_SUB_DIR}/config/config.toml +sed -i -r 's/fast_sync = true/fast_sync = false/g' ${PROV_NODE_SUB_DIR}/config/config.toml + +# Start gaia +interchain-security-pd start \ + --home ${PROV_NODE_SUB_DIR} \ + --rpc.laddr tcp://${NODE_IP}:26628 \ + --grpc.address ${NODE_IP}:9021 \ + --address tcp://${NODE_IP}:26625 \ + --p2p.laddr tcp://${NODE_IP}:26626 \ + --grpc-web.enable=false &> ${PROV_NODE_SUB_DIR}/logs & + +waiting 10 "for provider sub-node to start" + +# Build consumer chain proposal file +tee ${PROV_NODE_DIR}/consumer-proposal.json< ${CONS_NODE_DIR}/${PROV_KEY}.json 2>&1 + +# Add stake to user account +CONS_ACCOUNT_ADDR=$(jq -r '.address' ${CONS_NODE_DIR}/${PROV_KEY}.json) +interchain-security-cd add-genesis-account "$CONS_ACCOUNT_ADDR" 1000000000stake --home ${CONS_NODE_DIR} + +# Add consumer genesis states to genesis file +interchain-security-pd query provider consumer-genesis consumer --home ${PROV_NODE_DIR} -o json > consumer_gen.json +jq -s '.[0].app_state.ccvconsumer = .[1] | .[0]' ${CONS_NODE_DIR}/config/genesis.json consumer_gen.json > ${CONS_NODE_DIR}/edited_genesis.json \ +&& mv ${CONS_NODE_DIR}/edited_genesis.json ${CONS_NODE_DIR}/config/genesis.json +rm consumer_gen.json + +# Create validator states +echo '{"height": "0","round": 0,"step": 0}' > ${CONS_NODE_DIR}/data/priv_validator_state.json + +# Copy validator key files +cp ${PROV_NODE_DIR}/config/priv_validator_key.json ${CONS_NODE_DIR}/config/priv_validator_key.json +cp ${PROV_NODE_DIR}/config/node_key.json ${CONS_NODE_DIR}/config/node_key.json + +# Set default client port +sed -i -r "/node =/ s/= .*/= \"tcp:\/\/${NODE_IP}:26648\"/" ${CONS_NODE_DIR}/config/client.toml +sed -i -r 's/fast_sync = true/fast_sync = false/g' ${CONS_NODE_DIR}/config/config.toml + + +# Start gaia +interchain-security-cd start --home ${CONS_NODE_DIR} \ + --rpc.laddr tcp://${NODE_IP}:26648 \ + --grpc.address ${NODE_IP}:9081 \ + --address tcp://${NODE_IP}:26645 \ + --p2p.laddr tcp://${NODE_IP}:26646 \ + --grpc-web.enable=false \ + &> ${CONS_NODE_DIR}/logs & + +waiting 20 "for consumer node to start" + +tee ${HERMES_CONFIG}< Height: ${height}, Hash: ${hash}" + +cp -r ${CONS_NODE_DIR} ${CONS_FORK_NODE_DIR} +# Set default client port +sed -i -r "/node =/ s/= .*/= \"tcp:\/\/${NODE_IP}:26638\"/" ${CONS_FORK_NODE_DIR}/config/client.toml +sed -i -r 's/fast_sync = true/fast_sync = false/g' ${CONS_FORK_NODE_DIR}/config/config.toml + + +# Start gaia +interchain-security-cd start --home ${CONS_FORK_NODE_DIR} \ + --rpc.laddr tcp://${NODE_IP}:26638 \ + --grpc.address ${NODE_IP}:9071 \ + --address tcp://${NODE_IP}:26635 \ + --p2p.laddr tcp://${NODE_IP}:26636 \ + --grpc-web.enable=false \ + &> ${CONS_FORK_NODE_DIR}/logs & + +waiting 5 "for forked consumer node to start" + +diag "Start Hermes relayer multi-chain mode" + +$HERMES_BIN start &> ${HOME_DIR}/hermes-start-logs.txt & + +# If we sleep 5 here and below, we end up on the forked block later +waiting 10 "for Hermes relayer to start" + +diag "Running Hermes relayer evidence command" + +# Run hermes in evidence mode +$HERMES_BIN evidence --chain consumer &> ${HOME_DIR}/hermes-evidence-logs.txt & + +# If we sleep 5 here and above, we end up on the forked block later +waiting 10 "for Hermes evidence monitor to start" + +diag "Updating client on forked chain using trusted height $TRUSTED_HEIGHT" +$HERMES_BIN_FORK update client --client 07-tendermint-0 --host-chain provider --trusted-height "$TRUSTED_HEIGHT" + +waiting 20 "for Hermes to detect and submit evidence" + +# Check the client state on provider and verify it is frozen +FROZEN_HEIGHT=$($HERMES_BIN --json query client state --chain provider --client 07-tendermint-0 | tail -n 1 | jq '.result.frozen_height.revision_height') + +diag "Frozen height: $FROZEN_HEIGHT" + +if [ "$FROZEN_HEIGHT" != "null" ]; then + diag "Client is frozen, as expected." +else + diag "Client is not frozen, aborting." + exit 1 +fi + +if grep -q "found light client attack evidence" ${HOME_DIR}/hermes-evidence-logs.txt; then + diag "Evidence found, proceeding." +else + diag "Evidence not found, aborting." + exit 1 +fi + +waiting 20 "for Hermes to submit evidence and freeze client" + +if grep -q "successfully submitted light client attack evidence" ${HOME_DIR}/hermes-evidence-logs.txt; then + diag "Evidence successfully submitted, success!" +else + if grep -q "provider is frozen" ${HOME_DIR}/hermes-evidence-logs.txt; then + diag "Client on provider is already frozen, as expected. Success!" + exit 0 + elif grep -q "client is frozen and does not have a consensus state at height" ${HOME_DIR}/hermes-evidence-logs.txt; then + diag "Client already frozen and does not have a consensus state at common height, cannot do anything." + exit 0 + else + diag "Evidence not submitted, failed." + echo "" + + diag "Hermes evidence logs:" + cat ${HOME_DIR}/hermes-evidence-logs.txt + + exit 1 + fi +fi + diff --git a/ci/misbehaviour-ics/light_client_attack_test.sh b/ci/misbehaviour-ics/light_client_attack_test.sh new file mode 100644 index 0000000000..2ad46fcea9 --- /dev/null +++ b/ci/misbehaviour-ics/light_client_attack_test.sh @@ -0,0 +1,559 @@ +#!/bin/bash +# shellcheck disable=2086 + +set -eu + +DEBUG=${DEBUG:-false} + +if [ "$DEBUG" = true ]; then + set -x +fi + +diag() { + echo ">> +>> $* +>>" 1>&2 +} + +waiting() { + secs=$1 + shift + msg="$*" + while [ $secs -gt 0 ] + do + echo -ne "|| Waiting $msg (${secs}s)\033[0K\r" + sleep 1 + : $((secs--)) + done + echo "|| Waiting $msg (done)" +} + + +# User balance of stake tokens +USER_COINS="100000000000stake" +# Amount of stake tokens staked +STAKE="100000000stake" +# Amount of stake tokens staked +STAKE2="4000000stake" +# Node IP address +NODE_IP="127.0.0.1" + +# Home directory +HOME_DIR="/tmp/hermes-ics-misbehaviour" + +# Hermes debug +if [ "$DEBUG" = true ]; then + HERMES_DEBUG="--debug=rpc" +else + HERMES_DEBUG="" +fi + +# Hermes config +HERMES_CONFIG="$HOME_DIR/hermes.toml" +HERMES_CONFIG_FORK="$HOME_DIR/hermes-fork.toml" +# Hermes binary +HERMES_BIN="cargo run -q --bin hermes -- $HERMES_DEBUG --config $HERMES_CONFIG" +HERMES_BIN_FORK="cargo run -q --bin hermes -- $HERMES_DEBUG --config $HERMES_CONFIG_FORK" + +# Validator moniker +MONIKER="coordinator" +MONIKER_SUB="sub" + +# Validator directory +PROV_NODE_DIR=${HOME_DIR}/provider-${MONIKER} +PROV_NODE_SUB_DIR=${HOME_DIR}/provider-${MONIKER_SUB} +CONS_NODE_DIR=${HOME_DIR}/consumer-${MONIKER} +CONS_NODE_SUB_DIR=${HOME_DIR}/consumer-${MONIKER_SUB} +CONS_FORK_NODE_DIR=${HOME_DIR}/consumer-fork-${MONIKER} + +# Coordinator key +PROV_KEY=${MONIKER}-key +PROV_KEY_SUB=${MONIKER_SUB}-key + + +# Clean start +pkill -f interchain-security-pd &> /dev/null || true +pkill -f interchain-security-cd &> /dev/null || true +pkill -f hermes &> /dev/null || true + +mkdir -p "${HOME_DIR}" +rm -rf "${PROV_NODE_DIR}" +rm -rf "${PROV_NODE_SUB_DIR}" +rm -rf "${CONS_NODE_DIR}" +rm -rf "${CONS_NODE_SUB_DIR}" +rm -rf "${CONS_FORK_NODE_DIR}" + +# Build genesis file and node directory structure +interchain-security-pd init $MONIKER --chain-id provider --home ${PROV_NODE_DIR} +jq ".app_state.gov.voting_params.voting_period = \"3s\" | .app_state.staking.params.unbonding_time = \"86400s\"" \ + ${PROV_NODE_DIR}/config/genesis.json > \ + ${PROV_NODE_DIR}/edited_genesis.json && mv ${PROV_NODE_DIR}/edited_genesis.json ${PROV_NODE_DIR}/config/genesis.json + +# Create account keypair +interchain-security-pd keys add $PROV_KEY --home ${PROV_NODE_DIR} --keyring-backend test --output json > ${PROV_NODE_DIR}/${PROV_KEY}.json 2>&1 + +# Add stake to user +PROV_ACCOUNT_ADDR=$(jq -r '.address' ${PROV_NODE_DIR}/${PROV_KEY}.json) +interchain-security-pd add-genesis-account "$PROV_ACCOUNT_ADDR" $USER_COINS --home ${PROV_NODE_DIR} --keyring-backend test + +# Stake 1/1000 user's coins +interchain-security-pd gentx $PROV_KEY $STAKE --chain-id provider --home ${PROV_NODE_DIR} --keyring-backend test --moniker $MONIKER + +## config second node + +rm -rf ${PROV_NODE_SUB_DIR} + +# Build genesis file and node directory structure +interchain-security-pd init $MONIKER_SUB --chain-id provider --home ${PROV_NODE_SUB_DIR} + +waiting 1 "" + +# Create account keypair +interchain-security-pd keys add $PROV_KEY_SUB --home ${PROV_NODE_SUB_DIR} --keyring-backend test --output json > ${PROV_NODE_SUB_DIR}/${PROV_KEY_SUB}.json 2>&1 +waiting 1 "" + +cp ${PROV_NODE_DIR}/config/genesis.json ${PROV_NODE_SUB_DIR}/config/genesis.json + +# Add stake to user +PROV_ACCOUNT_ADDR=$(jq -r '.address' ${PROV_NODE_SUB_DIR}/${PROV_KEY_SUB}.json) +interchain-security-pd add-genesis-account "$PROV_ACCOUNT_ADDR" $USER_COINS --home ${PROV_NODE_SUB_DIR} --keyring-backend test +waiting 1 "" + + + +cp -r ${PROV_NODE_DIR}/config/gentx/ ${PROV_NODE_SUB_DIR}/config/gentx/ + +# # Stake 1/1000 user's coins +interchain-security-pd gentx $PROV_KEY_SUB $STAKE2 --chain-id provider --home ${PROV_NODE_SUB_DIR} --keyring-backend test --moniker $MONIKER_SUB +waiting 1 "" + + +interchain-security-pd collect-gentxs --home ${PROV_NODE_SUB_DIR} --gentx-dir ${PROV_NODE_SUB_DIR}/config/gentx/ + +cp ${PROV_NODE_SUB_DIR}/config/genesis.json ${PROV_NODE_DIR}/config/genesis.json + + + +# Start nodes + +sed -i -r "/node =/ s/= .*/= \"tcp:\/\/${NODE_IP}:26658\"/" ${PROV_NODE_DIR}/config/client.toml +sed -i -r 's/timeout_commit = "5s"/timeout_commit = "3s"/g' ${PROV_NODE_DIR}/config/config.toml +sed -i -r 's/timeout_propose = "3s"/timeout_propose = "1s"/g' ${PROV_NODE_DIR}/config/config.toml +sed -i -r 's/fast_sync = true/fast_sync = false/g' ${PROV_NODE_DIR}/config/config.toml + + + +# Start gaia +interchain-security-pd start \ + --home ${PROV_NODE_DIR} \ + --rpc.laddr tcp://${NODE_IP}:26658 \ + --grpc.address ${NODE_IP}:9091 \ + --address tcp://${NODE_IP}:26655 \ + --p2p.laddr tcp://${NODE_IP}:26656 \ + --grpc-web.enable=false &> ${PROV_NODE_DIR}/logs & + +waiting 5 "for provider node to start" + +sed -i -r "/node =/ s/= .*/= \"tcp:\/\/${NODE_IP}:26628\"/" ${PROV_NODE_SUB_DIR}/config/client.toml +sed -i -r 's/timeout_commit = "5s"/timeout_commit = "3s"/g' ${PROV_NODE_SUB_DIR}/config/config.toml +sed -i -r 's/timeout_propose = "3s"/timeout_propose = "1s"/g' ${PROV_NODE_SUB_DIR}/config/config.toml +sed -i -r 's/fast_sync = true/fast_sync = false/g' ${PROV_NODE_SUB_DIR}/config/config.toml + + + +# # Start gaia +interchain-security-pd start \ + --home ${PROV_NODE_SUB_DIR} \ + --rpc.laddr tcp://${NODE_IP}:26628 \ + --grpc.address ${NODE_IP}:9021 \ + --address tcp://${NODE_IP}:26625 \ + --p2p.laddr tcp://${NODE_IP}:26626 \ + --grpc-web.enable=false &> ${PROV_NODE_SUB_DIR}/logs & + +waiting 5 "for provider sub-node to start" + +# Build consumer chain proposal file +tee ${PROV_NODE_DIR}/consumer-proposal.json< ${CONS_NODE_DIR}/${PROV_KEY}.json 2>&1 + +# Add stake to user account +CONS_ACCOUNT_ADDR=$(jq -r '.address' ${CONS_NODE_DIR}/${PROV_KEY}.json) +interchain-security-cd add-genesis-account "$CONS_ACCOUNT_ADDR" 1000000000stake --home ${CONS_NODE_DIR} + +# Add consumer genesis states to genesis file +interchain-security-pd query provider consumer-genesis consumer --home ${PROV_NODE_DIR} -o json > consumer_gen.json +jq -s '.[0].app_state.ccvconsumer = .[1] | .[0]' ${CONS_NODE_DIR}/config/genesis.json consumer_gen.json > ${CONS_NODE_DIR}/edited_genesis.json \ +&& mv ${CONS_NODE_DIR}/edited_genesis.json ${CONS_NODE_DIR}/config/genesis.json +rm consumer_gen.json + +# Create validator states +echo '{"height": "0","round": 0,"step": 0}' > ${CONS_NODE_DIR}/data/priv_validator_state.json + +# Copy validator key files +cp ${PROV_NODE_DIR}/config/priv_validator_key.json ${CONS_NODE_DIR}/config/priv_validator_key.json +cp ${PROV_NODE_DIR}/config/node_key.json ${CONS_NODE_DIR}/config/node_key.json + +# Set default client port +sed -i -r "/node =/ s/= .*/= \"tcp:\/\/${NODE_IP}:26648\"/" ${CONS_NODE_DIR}/config/client.toml +sed -i -r 's/fast_sync = true/fast_sync = false/g' ${CONS_NODE_DIR}/config/config.toml + + +# Start gaia +interchain-security-cd start --home ${CONS_NODE_DIR} \ + --rpc.laddr tcp://${NODE_IP}:26648 \ + --grpc.address ${NODE_IP}:9081 \ + --address tcp://${NODE_IP}:26645 \ + --p2p.laddr tcp://${NODE_IP}:26646 \ + --grpc-web.enable=false \ + &> ${CONS_NODE_DIR}/logs & + +waiting 20 "for consumer node to start" + +tee ${HERMES_CONFIG}< Height: ${height}, Hash: ${hash}" + +cp -r ${CONS_NODE_DIR} ${CONS_FORK_NODE_DIR} +# Set default client port +sed -i -r "/node =/ s/= .*/= \"tcp:\/\/${NODE_IP}:26638\"/" ${CONS_FORK_NODE_DIR}/config/client.toml +sed -i -r 's/fast_sync = true/fast_sync = false/g' ${CONS_FORK_NODE_DIR}/config/config.toml + + +# Start gaia +interchain-security-cd start --home ${CONS_FORK_NODE_DIR} \ + --rpc.laddr tcp://${NODE_IP}:26638 \ + --grpc.address ${NODE_IP}:9071 \ + --address tcp://${NODE_IP}:26635 \ + --p2p.laddr tcp://${NODE_IP}:26636 \ + --grpc-web.enable=false \ + &> ${CONS_FORK_NODE_DIR}/logs & + +waiting 5 "for forked consumer node to start" + +diag "Start Hermes relayer multi-chain mode" + +$HERMES_BIN start &> ${HOME_DIR}/hermes-start-logs.txt & + +# If we sleep 5 here and below, we end up on the forked block later +waiting 10 "for Hermes relayer to start" + +diag "Running Hermes relayer evidence command" + +# Run hermes in evidence mode +$HERMES_BIN evidence --chain consumer &> ${HOME_DIR}/hermes-evidence-logs.txt & + +# If we sleep 5 here and above, we end up on the forked block later +waiting 10 "for Hermes evidence monitor to start" + +read -r CD_HEIGHT < <( + curl -s "localhost:26638"/commit \ + | jq -r '(.result//.).signed_header.header.height') + +diag "Running light client between primary and fork as witness using trusted height $CD_TRUSTED_HEIGHT and hash $CD_TRUSTED_HASH at height $CD_HEIGHT" + +# Rust light client +# tendermint-light-client-cli \ +# --chain-id consumer \ +# --primary "http://$NODE_IP:26638" \ +# --witnesses "http://$NODE_IP:26648" \ +# --trusted-height $CD_TRUSTED_HEIGHT \ +# --trusted-hash $CD_TRUSTED_HASH \ +# --height $CD_HEIGHT + +# Go light client +rm -rf $HOME/.cometbft-light/ +cometbft light consumer \ + --primary "http://$NODE_IP:26638" \ + --witnesses "http://$NODE_IP:26648" \ + --height $CD_TRUSTED_HEIGHT \ + --hash $CD_TRUSTED_HASH > ${HOME_DIR}/light-client-logs.txt 2>&1 & + +echo $! > ${HOME_DIR}/light-client.pid + +waiting 5 "for light client to start" +BLOCK="$(curl -s "localhost:8888/block?height=$CD_HEIGHT" | jq)" +echo $BLOCK +waiting 1 "before killing light client" + +kill -9 "$(cat ${HOME_DIR}/light-client.pid)" + +waiting 20 "for Hermes to detect evidence" + +if grep -q "found light client attack evidence" ${HOME_DIR}/hermes-evidence-logs.txt; then + diag "Evidence found, proceeding!" +else + diag "Evidence not found, aborting." + exit 1 +fi + +waiting 20 "for Hermes to submit evidence and freeze client" + +if grep -q "successfully submitted light client attack evidence" ${HOME_DIR}/hermes-evidence-logs.txt; then + diag "Evidence successfully submitted, success!" +else + if grep -q "provider is frozen" ${HOME_DIR}/hermes-evidence-logs.txt; then + diag "Client on provider is already frozen, cannot do anything." + exit 0 + elif grep -q "client is frozen and does not have a consensus state at height" ${HOME_DIR}/hermes-evidence-logs.txt; then + diag "Client already frozen and does not have a consensus state at common height, cannot do anything." + exit 0 + else + diag "Evidence not submitted, failed." + echo "" + + diag "Hermes evidence logs:" + cat ${HOME_DIR}/hermes-evidence-logs.txt + + exit 1 + fi +fi + diff --git a/ci/misbehaviour/config.toml b/ci/misbehaviour/config.toml index 12bc01922c..4db30c36be 100644 --- a/ci/misbehaviour/config.toml +++ b/ci/misbehaviour/config.toml @@ -112,6 +112,9 @@ port = 3001 # Specify the chain ID. Required id = 'ibc-0' +# Specify the type of chain, currently only "CosmosSdk" is supported. +type = "CosmosSdk" + # Specify the RPC address and port where the chain RPC server listens on. Required rpc_addr = 'http://127.0.0.1:26657' @@ -299,6 +302,7 @@ memo_prefix = '' [[chains]] id = 'ibc-1' +type = "CosmosSdk" rpc_addr = 'http://127.0.0.1:26557' grpc_addr = 'http://127.0.0.1:9091' event_source = { mode = 'push', url = 'ws://127.0.0.1:26557/websocket', batch_delay = '500ms' } diff --git a/ci/misbehaviour/config_fork.toml b/ci/misbehaviour/config_fork.toml index d911b14798..a8ff8ee836 100644 --- a/ci/misbehaviour/config_fork.toml +++ b/ci/misbehaviour/config_fork.toml @@ -112,6 +112,9 @@ port = 3001 # Specify the chain ID. Required id = 'ibc-0' +# Specify the chain type, currently only 'CosmosSdk' is supported. +type = 'CosmosSdk' + # Specify the RPC address and port where the chain RPC server listens on. Required rpc_addr = 'http://127.0.0.1:26657' @@ -298,6 +301,7 @@ memo_prefix = '' [[chains]] id = 'ibc-1' +type = 'CosmosSdk' rpc_addr = 'http://127.0.0.1:26457' grpc_addr = 'http://127.0.0.1:9092' event_source = { mode = 'push', url = 'ws://127.0.0.1:26457/websocket', batch_delay = '500ms' } diff --git a/ci/misbehaviour/misbehaviour_test.sh b/ci/misbehaviour/misbehaviour_test.sh index d79b8ca854..32d91a23c3 100755 --- a/ci/misbehaviour/misbehaviour_test.sh +++ b/ci/misbehaviour/misbehaviour_test.sh @@ -42,7 +42,7 @@ info "Update client on ibc-0 against the forked chain ibc-1-f" $HERMES --config config_fork.toml update client --client 07-tendermint-0 --host-chain ibc-0 info "Wait for chain ibc-1 to stop..." -sleep 5 +sleep 10 info "Killing Hermes" kill -9 "$HERMES_PID" diff --git a/config.toml b/config.toml index ce371027e6..17592ffeab 100644 --- a/config.toml +++ b/config.toml @@ -140,6 +140,9 @@ port = 5555 # Specify the chain ID. Required id = 'ibc-0' +# Specify the chain type, currently only `"CosmosSdk"` is supported. +type = "CosmosSdk" + # Whether or not this is a CCV consumer chain. Default: false # Only specifiy true for CCV consumer chain, but NOT for sovereign chains. ccv_consumer_chain = false @@ -154,7 +157,7 @@ grpc_addr = 'http://127.0.0.1:9090' # # This setting can take two types of values, as an inline table: # -# a) Push: for receiving IBC events over WebSocket +# a) Push: for receiving IBC events over WebSocket. # # `{ mode = 'push', url = 'ws://127.0.0.1:26657/websocket', batch_delay = '500ms' }` # @@ -169,7 +172,7 @@ grpc_addr = 'http://127.0.0.1:9090' # processing, increasing the latency of Hermes, but are more likely to batch events together. # The default value provides good latency while minimizing the number of client updates needed. -# b) Pull: for polling for IBC events via the `/block_results` RPC endpoint +# b) Pull: for polling for IBC events via the `/block_results` RPC endpoint. # # `{ mode = 'pull', interval = '1s' }` # @@ -177,6 +180,11 @@ grpc_addr = 'http://127.0.0.1:9090' # # - `interval` is the interval at which to poll for blocks. Default: 1s # +# This mode should only be used in situations where Hermes misses events that it should be +# receiving, such as when relaying for CosmWasm-enabled chains which emit IBC events without +# the `message` attribute. Without this attribute, the WebSocket is not able to catch these +# events, so the `/block_results` RPC must be used instead. +# event_source = { mode = 'push', url = 'ws://127.0.0.1:26657/websocket', batch_delay = '500ms' } # Specify the maximum amount of time (duration) that the RPC requests should @@ -263,7 +271,7 @@ max_gas = 400000 # paid for each unit of gas per transaction. # # Required -gas_price = { price = 0.001, denom = 'stake' } +gas_price = { price = 0.025, denom = 'stake' } # Multiply this amount with the gas estimate, used to compute the fee # and account for potential estimation error. @@ -374,6 +382,7 @@ memo_prefix = '' [[chains]] id = 'ibc-1' +type = "CosmosSdk" rpc_addr = 'http://127.0.0.1:26557' grpc_addr = 'http://127.0.0.1:9091' event_source = { mode = 'push', url = 'ws://127.0.0.1:26557/websocket', batch_delay = '500ms' } @@ -384,7 +393,7 @@ key_name = 'testkey' store_prefix = 'ibc' default_gas = 100000 max_gas = 400000 -gas_price = { price = 0.001, denom = 'stake' } +gas_price = { price = 0.025, denom = 'stake' } gas_multiplier = 1.1 max_msg_num = 30 max_tx_size = 2097152 diff --git a/crates/chain-registry/Cargo.toml b/crates/chain-registry/Cargo.toml index 78d394b9d0..1129e78ff9 100644 --- a/crates/chain-registry/Cargo.toml +++ b/crates/chain-registry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ibc-chain-registry" -version = "0.25.0" +version = "0.26.0" edition = "2021" license = "Apache-2.0" keywords = ["cosmos", "ibc", "relayer", "chain", "registry"] @@ -12,12 +12,9 @@ description = """ """ [dependencies] -ibc-proto = { version = "0.37.0", features = ["serde"] } -ibc-relayer-types = { version = "0.25.0", path = "../relayer-types" } -tendermint-rpc = { version = "0.34.0", features = [ - "http-client", - "websocket-client", -] } +ibc-relayer-types = { version = "0.26.0", path = "../relayer-types" } +ibc-proto = { version = "0.38.0", features = ["serde"] } +tendermint-rpc = { version = "0.34.0", features = ["http-client", "websocket-client"] } async-trait = "0.1.72" flex-error = { version = "0.4.4", default-features = false } diff --git a/crates/relayer-cli/Cargo.toml b/crates/relayer-cli/Cargo.toml index d672b3855d..fcc25c93c1 100644 --- a/crates/relayer-cli/Cargo.toml +++ b/crates/relayer-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ibc-relayer-cli" -version = "1.6.0" +version = "1.7.0" edition = "2021" license = "Apache-2.0" readme = "README.md" @@ -25,11 +25,11 @@ telemetry = ["ibc-relayer/telemetry", "ibc-telemetry"] rest-server = ["ibc-relayer-rest"] [dependencies] -ibc-relayer-types = { version = "0.25.0", path = "../relayer-types" } -ibc-relayer = { version = "0.25.0", path = "../relayer" } -ibc-telemetry = { version = "0.25.0", path = "../telemetry", optional = true } -ibc-relayer-rest = { version = "0.25.0", path = "../relayer-rest", optional = true } -ibc-chain-registry = { version = "0.25.0" , path = "../chain-registry" } +ibc-relayer-types = { version = "0.26.0", path = "../relayer-types" } +ibc-relayer = { version = "0.26.0", path = "../relayer" } +ibc-telemetry = { version = "0.26.0", path = "../telemetry", optional = true } +ibc-relayer-rest = { version = "0.26.0", path = "../relayer-rest", optional = true } +ibc-chain-registry = { version = "0.26.0" , path = "../chain-registry" } clap = { version = "3.2", features = ["cargo"] } clap_complete = "3.2" diff --git a/crates/relayer-cli/src/application.rs b/crates/relayer-cli/src/application.rs index 1dadc513e7..e7d524bf96 100644 --- a/crates/relayer-cli/src/application.rs +++ b/crates/relayer-cli/src/application.rs @@ -18,7 +18,6 @@ use ibc_relayer::{ use crate::{ commands::CliCmd, components::{JsonTracing, PrettyTracing}, - config::validate_config, entry::EntryPoint, tracing_handle::{spawn_reload_handler, ReloadHandle}, }; @@ -134,13 +133,13 @@ impl Application for CliApp { /// time in app lifecycle when configuration would be loaded if /// possible. fn after_config(&mut self, config: Self::Cfg) -> Result<(), FrameworkError> { - use crate::config::Diagnostic; + use ibc_relayer::config::Diagnostic; // Configure components let mut components = self.state.components_mut(); components.after_config(&config)?; - if let Err(diagnostic) = validate_config(&config) { + if let Err(diagnostic) = config.validate_config() { match diagnostic { Diagnostic::Warning(e) => { tracing::warn!("relayer may be misconfigured: {}", e); diff --git a/crates/relayer-cli/src/chain_registry.rs b/crates/relayer-cli/src/chain_registry.rs index 305a8d615a..51ab28829d 100644 --- a/crates/relayer-cli/src/chain_registry.rs +++ b/crates/relayer-cli/src/chain_registry.rs @@ -16,6 +16,7 @@ use ibc_chain_registry::fetchable::Fetchable; use ibc_chain_registry::formatter::{SimpleGrpcFormatter, UriFormatter}; use ibc_chain_registry::paths::IBCPath; use ibc_chain_registry::querier::*; +use ibc_relayer::chain::cosmos::config::CosmosSdkConfig; use ibc_relayer::config::filter::{FilterPattern, PacketFilter}; use ibc_relayer::config::gas_multiplier::GasMultiplier; use ibc_relayer::config::types::{MaxMsgNum, MaxTxSize, Memo}; @@ -120,9 +121,8 @@ where 0.1 }; - Ok(ChainConfig { + Ok(ChainConfig::CosmosSdk(CosmosSdkConfig { id: chain_data.chain_id, - r#type: default::chain_type(), rpc_addr: rpc_data.rpc_address, grpc_addr: grpc_address, event_source: EventSourceMode::Push { @@ -160,7 +160,7 @@ where address_type: AddressType::default(), sequential_batch_tx: false, extension_options: Vec::new(), - }) + })) } /// Concurrent `query_healthy` might fail, this is a helper function which will retry a failed query a fixed @@ -341,7 +341,10 @@ mod tests { for config in configs { match config { Ok(config) => { - assert_eq!(config.packet_filter.channel_policy, ChannelPolicy::AllowAll); + assert_eq!( + config.packet_filter().channel_policy, + ChannelPolicy::AllowAll + ); } Err(e) => panic!( "Encountered an unexpected error in chain registry test: {}", @@ -367,9 +370,9 @@ mod tests { for config in configs { match config { - Ok(config) => match config.packet_filter.channel_policy { + Ok(config) => match &config.packet_filter().channel_policy { ChannelPolicy::Allow(channel_filter) => { - if config.id.as_str().contains("cosmoshub") { + if config.id().as_str().contains("cosmoshub") { assert!(channel_filter.is_exact()); let cosmoshub_juno = ( @@ -385,7 +388,7 @@ mod tests { assert!(channel_filter.matches(cosmoshub_juno)); assert!(channel_filter.matches(cosmoshub_osmosis)); assert!(channel_filter.len() == 2); - } else if config.id.as_str().contains("juno") { + } else if config.id().as_str().contains("juno") { assert!(channel_filter.is_exact()); let juno_cosmoshub = ( @@ -407,7 +410,7 @@ mod tests { assert!(channel_filter.matches(juno_osmosis_1)); assert!(channel_filter.matches(juno_osmosis_2)); assert!(channel_filter.len() == 3); - } else if config.id.as_str().contains("osmosis") { + } else if config.id().as_str().contains("osmosis") { assert!(channel_filter.is_exact()); let osmosis_cosmoshub = ( diff --git a/crates/relayer-cli/src/cli_utils.rs b/crates/relayer-cli/src/cli_utils.rs index 5a2aae7fc0..d96761b0a7 100644 --- a/crates/relayer-cli/src/cli_utils.rs +++ b/crates/relayer-cli/src/cli_utils.rs @@ -5,18 +5,13 @@ use eyre::eyre; use tokio::runtime::Runtime as TokioRuntime; use tracing::debug; +use ibc_relayer::chain::counterparty::{channel_connection_client, ChannelConnectionClient}; +use ibc_relayer::chain::handle::{BaseChainHandle, ChainHandle}; use ibc_relayer::chain::requests::{ IncludeProof, QueryChannelRequest, QueryClientStateRequest, QueryConnectionRequest, QueryHeight, }; -use ibc_relayer::{ - chain::{ - counterparty::{channel_connection_client, ChannelConnectionClient}, - handle::{BaseChainHandle, ChainHandle}, - }, - config::Config, - spawn, -}; -use ibc_relayer_types::core::ics02_client::client_state::ClientState; +use ibc_relayer::config::Config; +use ibc_relayer::spawn; use ibc_relayer_types::core::ics24_host::identifier::{ChainId, ChannelId, PortId}; use crate::error::Error; diff --git a/crates/relayer-cli/src/commands.rs b/crates/relayer-cli/src/commands.rs index 51e7022bd6..60879018f5 100644 --- a/crates/relayer-cli/src/commands.rs +++ b/crates/relayer-cli/src/commands.rs @@ -4,6 +4,7 @@ mod clear; mod completions; mod config; mod create; +mod evidence; mod fee; mod health; mod keys; @@ -19,9 +20,9 @@ mod version; use self::{ clear::ClearCmds, completions::CompletionsCmd, config::ConfigCmd, create::CreateCmds, - fee::FeeCmd, health::HealthCheckCmd, keys::KeysCmd, listen::ListenCmd, logs::LogsCmd, - misbehaviour::MisbehaviourCmd, query::QueryCmd, start::StartCmd, tx::TxCmd, update::UpdateCmds, - upgrade::UpgradeCmds, version::VersionCmd, + evidence::EvidenceCmd, fee::FeeCmd, health::HealthCheckCmd, keys::KeysCmd, listen::ListenCmd, + logs::LogsCmd, misbehaviour::MisbehaviourCmd, query::QueryCmd, start::StartCmd, tx::TxCmd, + update::UpdateCmds, upgrade::UpgradeCmds, version::VersionCmd, }; use core::time::Duration; @@ -32,7 +33,7 @@ use abscissa_core::{config::Override, Command, Configurable, FrameworkError, Run use tracing::{error, info}; use crate::DEFAULT_CONFIG_PATH; -use ibc_relayer::config::Config; +use ibc_relayer::config::{ChainConfig, Config}; /// Default configuration file path pub fn default_config_file() -> Option { @@ -86,12 +87,15 @@ pub enum CliCmd { /// Listen to and display IBC events emitted by a chain Listen(ListenCmd), + /// Listen to client update IBC events and handle misbehaviour + Misbehaviour(MisbehaviourCmd), + /// Update tracing log directives #[clap(subcommand)] Logs(LogsCmd), - /// Listen to client update IBC events and handles misbehaviour - Misbehaviour(MisbehaviourCmd), + /// Listen to block events and handles evidence + Evidence(EvidenceCmd), /// The `version` subcommand, retained for backward compatibility. Version(VersionCmd), @@ -145,14 +149,20 @@ impl Configurable for CliCmd { let web = "https://hermes.informal.systems"; let suffix = format!("{} {} ({})", CliCmd::name(), clap::crate_version!(), web); for ccfg in config.chains.iter_mut() { - ccfg.memo_prefix.apply_suffix(&suffix); + #[allow(irrefutable_let_patterns)] + if let ChainConfig::CosmosSdk(ref mut cosmos_ccfg) = ccfg { + cosmos_ccfg.memo_prefix.apply_suffix(&suffix); + } } // For all commands except for `start` Hermes retries // for a prolonged period of time. if !matches!(self, CliCmd::Start(_)) { for c in config.chains.iter_mut() { - c.rpc_timeout = Duration::from_secs(120); + #[allow(irrefutable_let_patterns)] + if let ChainConfig::CosmosSdk(ref mut cosmos_ccfg) = c { + cosmos_ccfg.rpc_timeout = Duration::from_secs(120); + } } } diff --git a/crates/relayer-cli/src/commands/clear.rs b/crates/relayer-cli/src/commands/clear.rs index 42149e3e65..d06bd853f6 100644 --- a/crates/relayer-cli/src/commands/clear.rs +++ b/crates/relayer-cli/src/commands/clear.rs @@ -75,7 +75,12 @@ impl Override for ClearPacketsCmd { })?; if let Some(ref key_name) = self.key_name { - chain_config.key_name = key_name.to_string(); + // Q: should the key name be required across chain types, meaning that + // key management is common to all chain types, or should key management + // be the responsibility of the backend? If key management is common + // across backends, how should it be agnostic to the key type? Can it + // just be an opaque byte string handled by the backend? + chain_config.set_key_name(key_name.to_string()); } Ok(config) @@ -101,7 +106,7 @@ impl Runnable for ClearPacketsCmd { if let Some(ref counterparty_key_name) = self.counterparty_key_name { match chains.dst.config() { Ok(mut dst_chain_cfg) => { - dst_chain_cfg.key_name = counterparty_key_name.to_string(); + dst_chain_cfg.set_key_name(counterparty_key_name.to_string()); } Err(e) => Output::error(e).exit(), } diff --git a/crates/relayer-cli/src/commands/config/auto.rs b/crates/relayer-cli/src/commands/config/auto.rs index 6736f0dd76..66fbd0969c 100644 --- a/crates/relayer-cli/src/commands/config/auto.rs +++ b/crates/relayer-cli/src/commands/config/auto.rs @@ -5,14 +5,13 @@ use abscissa_core::{Command, Runnable}; use crate::conclude::Output; use ibc_relayer::config::{store, ChainConfig, Config}; -use ibc_relayer::keyring::list_keys; use std::collections::HashSet; use std::path::PathBuf; use tracing::{info, warn}; fn find_key(chain_config: &ChainConfig) -> Option { - let keys = list_keys(chain_config).ok()?; + let keys = chain_config.list_keys().ok()?; keys.into_iter().next().map(|(name, _)| name) } @@ -117,7 +116,7 @@ impl Runnable for AutoCmd { .collect(); // Determine which chains were not fetched - let fetched_chains_set = HashSet::from_iter(chain_configs.iter().map(|c| c.id.name())); + let fetched_chains_set = HashSet::from_iter(chain_configs.iter().map(|c| c.id().name())); let missing_chains_set: HashSet<_> = sorted_names_set.difference(&fetched_chains_set).collect(); @@ -128,15 +127,15 @@ impl Runnable for AutoCmd { for (chain_config, key_option) in configs_and_keys { // If a key is provided, use it if let Some(key_name) = key_option { - info!("{}: uses key \"{}\"", &chain_config.id, &key_name); - chain_config.key_name = key_name; + info!("{}: uses key \"{}\"", &chain_config.id(), &key_name); + chain_config.set_key_name(key_name); } else { // Otherwise, find the key in the keystore - let chain_id = &chain_config.id; + let chain_id = &chain_config.id(); let key = find_key(chain_config); - if let Some(key) = key { - info!("{}: uses key '{}'", &chain_id, &key); - chain_config.key_name = key; + if let Some(key_name) = key { + info!("{}: uses key '{}'", &chain_id, &key_name); + chain_config.set_key_name(key_name); } else { // If no key is found, warn the user and continue warn!("No key found for chain: {}", chain_id); diff --git a/crates/relayer-cli/src/commands/config/validate.rs b/crates/relayer-cli/src/commands/config/validate.rs index 42f015a4f9..4414bba2ab 100644 --- a/crates/relayer-cli/src/commands/config/validate.rs +++ b/crates/relayer-cli/src/commands/config/validate.rs @@ -40,7 +40,7 @@ impl Runnable for ValidateCmd { // No need to output the underlying error, this is done already when the application boots. // See `application::CliApp::after_config`. - match config::validate_config(&config) { + match config.validate_config() { Ok(_) => Output::success("configuration is valid").exit(), Err(_) => Output::error("configuration is invalid").exit(), } diff --git a/crates/relayer-cli/src/commands/create/channel.rs b/crates/relayer-cli/src/commands/create/channel.rs index 3de03a257a..b949adff72 100644 --- a/crates/relayer-cli/src/commands/create/channel.rs +++ b/crates/relayer-cli/src/commands/create/channel.rs @@ -11,7 +11,6 @@ use ibc_relayer::chain::requests::{ use ibc_relayer::channel::Channel; 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::Ordering; use ibc_relayer_types::core::ics04_channel::version::Version; diff --git a/crates/relayer-cli/src/commands/create/connection.rs b/crates/relayer-cli/src/commands/create/connection.rs index 16c0fa1e6e..052411d069 100644 --- a/crates/relayer-cli/src/commands/create/connection.rs +++ b/crates/relayer-cli/src/commands/create/connection.rs @@ -7,7 +7,6 @@ use ibc_relayer::chain::handle::ChainHandle; use ibc_relayer::chain::requests::{IncludeProof, QueryClientStateRequest, QueryHeight}; 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::ics24_host::identifier::{ChainId, ClientId}; use crate::cli_utils::{spawn_chain_runtime, ChainHandlePair}; diff --git a/crates/relayer-cli/src/commands/evidence.rs b/crates/relayer-cli/src/commands/evidence.rs new file mode 100644 index 0000000000..1f43892b57 --- /dev/null +++ b/crates/relayer-cli/src/commands/evidence.rs @@ -0,0 +1,778 @@ +use std::collections::HashMap; +use std::ops::Deref; +use std::sync::Arc; +use std::thread::sleep; +use std::time::Duration; + +use abscissa_core::clap::Parser; +use abscissa_core::{Command, Runnable}; +use ibc_relayer::config::ChainConfig; +use tokio::runtime::Runtime as TokioRuntime; + +use tendermint::block::Height as TendermintHeight; +use tendermint::evidence::{DuplicateVoteEvidence, LightClientAttackEvidence}; +use tendermint::validator; +use tendermint_rpc::{Client, Paging}; + +use ibc_relayer::chain::cosmos::CosmosSdkChain; +use ibc_relayer::chain::endpoint::ChainEndpoint; +use ibc_relayer::chain::handle::{BaseChainHandle, ChainHandle}; +use ibc_relayer::chain::requests::{IncludeProof, PageRequest, QueryHeight}; +use ibc_relayer::chain::tracking::TrackedMsgs; +use ibc_relayer::foreign_client::ForeignClient; +use ibc_relayer::spawn::spawn_chain_runtime_with_modified_config; +use ibc_relayer_types::applications::ics28_ccv::msgs::ccv_double_voting::MsgSubmitIcsConsumerDoubleVoting; +use ibc_relayer_types::applications::ics28_ccv::msgs::ccv_misbehaviour::MsgSubmitIcsConsumerMisbehaviour; +use ibc_relayer_types::clients::ics07_tendermint::header::Header as TendermintHeader; +use ibc_relayer_types::clients::ics07_tendermint::misbehaviour::Misbehaviour as TendermintMisbehaviour; +use ibc_relayer_types::core::ics02_client::height::Height; +use ibc_relayer_types::core::ics02_client::msgs::misbehaviour::MsgSubmitMisbehaviour; +use ibc_relayer_types::core::ics24_host::identifier::{ChainId, ClientId}; +use ibc_relayer_types::events::IbcEvent; +use ibc_relayer_types::tx_msg::Msg; + +use crate::conclude::Output; +use crate::prelude::*; + +#[derive(Clone, Command, Debug, Parser, PartialEq, Eq)] +pub struct EvidenceCmd { + #[clap( + long = "chain", + required = true, + value_name = "CHAIN_ID", + help_heading = "REQUIRED", + help = "Identifier of the chain where blocks are monitored for misbehaviour" + )] + chain_id: ChainId, + + #[clap( + long = "check-past-blocks", + value_name = "NUM_BLOCKS", + help = "Check the last NUM_BLOCKS blocks for misbehaviour (default: 100)", + default_value = "100" + )] + check_past_blocks: u64, + + #[clap( + long = "key-name", + value_name = "KEY_NAME", + help = "Use the given signing key name for sending the misbehaviour evidence detected (default: `key_name` config)" + )] + key_name: Option, +} + +impl Runnable for EvidenceCmd { + fn run(&self) { + let config = app_config(); + + let mut chain_config = config + .find_chain(&self.chain_id) + .cloned() + .unwrap_or_else(|| { + Output::error(format!( + "chain `{}` not found in configuration", + self.chain_id + )) + .exit() + }); + + if !matches!(chain_config, ChainConfig::CosmosSdk(_)) { + Output::error(format!( + "chain `{}` is not a Cosmos SDK chain", + self.chain_id + )) + .exit(); + } + + if let Some(ref key_name) = self.key_name { + chain_config.set_key_name(key_name.to_string()); + } + + let rt = Arc::new( + tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .unwrap(), + ); + + let chain = CosmosSdkChain::bootstrap(chain_config, rt.clone()).unwrap(); + let res = monitor_misbehaviours(rt, chain, self.key_name.as_ref(), self.check_past_blocks); + + match res { + Ok(()) => Output::success(()).exit(), + Err(e) => Output::error(e).exit(), + } + } +} + +fn monitor_misbehaviours( + rt: Arc, + mut chain: CosmosSdkChain, + key_name: Option<&String>, + check_past_blocks: u64, +) -> eyre::Result<()> { + let subscription = chain.subscribe()?; + + // Check previous blocks for equivocation that may have been missed + let tm_latest_height = rt + .block_on(chain.rpc_client.status())? + .sync_info + .latest_block_height; + + let latest_height = Height::new(chain.id().version(), tm_latest_height.value()).unwrap(); + let target_height = { + let target = tm_latest_height.value().saturating_sub(check_past_blocks); + let height = std::cmp::max(1, target); + Height::new(chain.id().version(), height).unwrap() + }; + + info!( + "checking past {check_past_blocks} blocks for misbehaviour evidence: {}..{}", + latest_height, target_height + ); + + let mut height = latest_height; + + while height >= target_height { + debug!("checking for evidence at height {height}"); + + if let Err(e) = check_misbehaviour_at(rt.clone(), &chain, key_name, height) { + warn!("error while checking for misbehaviour at height {height}: {e}"); + } + + if height.revision_height() == 1 { + break; + } + + height = height.decrement().unwrap(); + + sleep(Duration::from_millis(100)); + } + + info!("waiting for new blocks..."); + + // process new block events + while let Ok(event_batch) = subscription.recv() { + match event_batch.deref() { + Ok(event_batch) => { + for event_with_height in &event_batch.events { + if let IbcEvent::NewBlock(new_block) = &event_with_height.event { + info!("checking for evidence at height {}", new_block.height); + + if let Err(e) = + check_misbehaviour_at(rt.clone(), &chain, key_name, new_block.height) + { + error!( + "error while checking for misbehaviour at height {}: {e}", + new_block.height + ); + } + } + } + } + Err(e) => { + error!("error while receiving event batch: {e}"); + } + } + } + + Ok(()) +} + +/// Check for misbehaviour evidence in the block at the given height. +/// If such evidence is found, handle it by submitting it to all counterparty +/// clients of the chain, freezing them. +fn check_misbehaviour_at( + rt: Arc, + chain: &CosmosSdkChain, + key_name: Option<&String>, + height: Height, +) -> eyre::Result<()> { + let block = rt + .block_on(chain.rpc_client.block(TendermintHeight::from(height)))? + .block; + + for evidence in block.evidence.into_vec() { + match evidence { + tendermint::evidence::Evidence::DuplicateVote(dv) => { + warn!("found duplicate vote evidence"); + trace!("{dv:#?}"); + + handle_duplicate_vote(rt.clone(), chain, key_name, *dv)?; + } + tendermint::evidence::Evidence::LightClientAttack(lc) => { + warn!("found light client attack evidence"); + trace!("{lc:#?}"); + + handle_light_client_attack(rt.clone(), chain, key_name, *lc)?; + } + } + } + + Ok(()) +} + +fn handle_duplicate_vote( + rt: Arc, + chain: &CosmosSdkChain, + key_name: Option<&String>, + dv: DuplicateVoteEvidence, +) -> eyre::Result<()> { + use ibc_relayer::chain::requests::QueryConsensusStateHeightsRequest; + + let config = app_config(); + + // Fetch all the counterparty clients of this chain. + let counterparty_clients = fetch_all_counterparty_clients(chain)?; + + let mut chains = HashMap::new(); + + // For each counterparty client, build the double voting evidence and submit it to the chain, + // freezing that client. + for (counterparty_chain_id, counterparty_client_id) in counterparty_clients { + if !chains.contains_key(&counterparty_chain_id) { + let chain_handle = spawn_chain_runtime_with_modified_config::( + &config, + &counterparty_chain_id, + rt.clone(), + |chain_config| { + if let Some(key_name) = key_name { + chain_config.set_key_name(key_name.to_string()); + } + }, + )?; + + chains.insert(counterparty_chain_id.clone(), chain_handle); + }; + + let counterparty_chain_handle = chains.get(&counterparty_chain_id).unwrap(); + + let signer = counterparty_chain_handle.get_signer()?; + + if !is_counterparty_provider(chain, counterparty_chain_handle, &counterparty_client_id) { + debug!("counterparty client `{counterparty_client_id}` on chain `{counterparty_chain_id}` is not a CCV client, skipping..."); + continue; + } + + let infraction_height = dv.vote_a.height; + + // Get the trusted height in the same way we do for client updates, + // ie. retrieve the consensus state at the highest height smaller than the infraction height. + // + // Note: The consensus state heights are sorted in increasing order. + let consensus_state_heights = + chain.query_consensus_state_heights(QueryConsensusStateHeightsRequest { + client_id: counterparty_client_id.clone(), + pagination: Some(PageRequest::all()), + })?; + + // Retrieve the consensus state at the highest height smaller than the infraction height. + let consensus_state_height_before_infraction_height = consensus_state_heights + .into_iter() + .filter(|height| height.revision_height() < infraction_height.value()) + .last(); + + let Some(trusted_height) = consensus_state_height_before_infraction_height else { + error!( + "cannot build infraction block header for client `{counterparty_client_id}` on chain `{counterparty_chain_id}`,\ + reason: could not find consensus state at highest height smaller than infraction height {infraction_height}" + ); + + continue; + }; + + // Construct the light client block header for the consumer chain at the infraction height + let infraction_block_header = + fetch_infraction_block_header(&rt, chain, infraction_height, trusted_height)?; + + let submit_msg = MsgSubmitIcsConsumerDoubleVoting { + submitter: signer.clone(), + duplicate_vote_evidence: dv.clone(), + infraction_block_header, + } + .to_any(); + + info!( + "submitting consumer double voting evidence to provider chain `{counterparty_chain_id}`" + ); + + let tracked_msgs = TrackedMsgs::new_static(vec![submit_msg], "double_voting_evidence"); + let responses = counterparty_chain_handle.send_messages_and_wait_check_tx(tracked_msgs)?; + + for response in responses { + if response.code.is_ok() { + info!("successfully submitted double voting evidence to chain `{counterparty_chain_id}`, tx hash: {}", response.hash); + } else { + error!( + "failed to submit double voting evidence to chain `{counterparty_chain_id}`: {response:?}" + ); + } + } + + // We have submitted the evidence to the provider, and because there can only be a single + // provider for a consumer chain, we can stop now. No need to check all the other + // counteparties. + break; + } + + Ok(()) +} + +fn fetch_infraction_block_header( + rt: &Arc, + chain: &CosmosSdkChain, + infraction_height: TendermintHeight, + trusted_height: Height, +) -> Result { + let signed_header = rt + .block_on(chain.rpc_client.commit(infraction_height))? + .signed_header; + + let validators = rt + .block_on(chain.rpc_client.validators(infraction_height, Paging::All))? + .validators; + + let validator_set = + validator::Set::with_proposer(validators, signed_header.header.proposer_address)?; + + let trusted_header = rt + .block_on(chain.rpc_client.commit(trusted_height))? + .signed_header; + + let trusted_validators = rt + .block_on(chain.rpc_client.validators(trusted_height, Paging::All))? + .validators; + + let trusted_validator_set = + validator::Set::with_proposer(trusted_validators, trusted_header.header.proposer_address)?; + + Ok(TendermintHeader { + signed_header, + validator_set, + trusted_height, + trusted_validator_set, + }) +} + +fn handle_light_client_attack( + rt: Arc, + chain: &CosmosSdkChain, + key_name: Option<&String>, + evidence: LightClientAttackEvidence, +) -> eyre::Result<()> { + let config = app_config(); + + // Build the two headers to submit as part of the `MsgSubmitMisbehaviour` message. + let (header1, header2) = build_evidence_headers(rt.clone(), chain, evidence.clone())?; + + // Fetch all the counterparty clients of this chain. + let counterparty_clients = fetch_all_counterparty_clients(chain)?; + + let mut chains = HashMap::new(); + + // For each counterparty client, build the misbehaviour evidence and submit it to the chain, + // freezing that client. + for (counterparty_chain_id, counterparty_client_id) in counterparty_clients { + let misbehaviour = TendermintMisbehaviour { + client_id: counterparty_client_id.clone(), + header1: header1.clone(), + header2: header2.clone(), + }; + + if !chains.contains_key(chain.id()) { + let chain_handle = spawn_chain_runtime_with_modified_config::( + &config, + chain.id(), + rt.clone(), + |chain_config| { + if let Some(key_name) = key_name { + chain_config.set_key_name(key_name.to_string()); + } + }, + )?; + + chains.insert(chain.id().clone(), chain_handle); + } + + if !chains.contains_key(&counterparty_chain_id) { + let chain_handle = spawn_chain_runtime_with_modified_config::( + &config, + &counterparty_chain_id, + rt.clone(), + |chain_config| { + if let Some(key_name) = key_name { + chain_config.set_key_name(key_name.to_string()); + } + }, + )?; + + chains.insert(counterparty_chain_id.clone(), chain_handle); + }; + + let chain_handle = chains.get(chain.id()).unwrap(); + let counterparty_chain_handle = chains.get(&counterparty_chain_id).unwrap(); + + let counterparty_client = ForeignClient::restore( + counterparty_client_id.clone(), + counterparty_chain_handle.clone(), + chain_handle.clone(), + ); + + let result = submit_light_client_attack_evidence( + &evidence, + chain, + counterparty_client, + counterparty_client_id, + counterparty_chain_handle, + misbehaviour, + ); + + if let Err(error) = result { + error!("{error}"); + } + } + + Ok(()) +} + +fn submit_light_client_attack_evidence( + evidence: &LightClientAttackEvidence, + chain: &CosmosSdkChain, + counterparty_client: ForeignClient, + counterparty_client_id: ClientId, + counterparty: &BaseChainHandle, + misbehaviour: TendermintMisbehaviour, +) -> Result<(), eyre::Error> { + info!( + "building light client attack evidence for client `{}` on counterparty chain `{}`", + counterparty_client_id, + counterparty.id(), + ); + + let counterparty_is_provider = + is_counterparty_provider(chain, counterparty, &counterparty_client_id); + + let counterparty_client_is_frozen = counterparty_client.is_frozen(); + + if !counterparty_is_provider && counterparty_client_is_frozen { + warn!( + "cannot submit light client attack evidence to client `{}` on counterparty chain `{}`", + counterparty_client_id, + counterparty.id() + ); + warn!("reason: client is frozen and chain is not a CCV provider chain"); + + return Ok(()); + } + + let signer = counterparty.get_signer()?; + let common_height = Height::from_tm(evidence.common_height, chain.id()); + + let counterparty_has_common_consensus_state = + has_consensus_state(counterparty, &counterparty_client_id, common_height); + + if counterparty_is_provider + && counterparty_client_is_frozen + && !counterparty_has_common_consensus_state + { + warn!( + "cannot submit light client attack evidence to client `{}` on provider chain `{}`", + counterparty_client_id, + counterparty.id() + ); + warn!("reason: client is frozen and does not have a consensus state at height {common_height}"); + + return Ok(()); + } + + let mut msgs = if counterparty_has_common_consensus_state { + info!( + "skip building update client message for client `{}` on counterparty chain `{}`", + counterparty_client_id, + counterparty.id() + ); + info!( + "reason: counterparty chain already has consensus state at common height {common_height}" + ); + + Vec::new() + } else { + match counterparty_client.wait_and_build_update_client(common_height) { + Ok(msgs) => msgs, + + Err(e) => { + warn!( + "skipping UpdateClient message for client `{}` on counterparty chain `{}`", + counterparty_client_id, + counterparty.id() + ); + warn!("reason: failed to build UpdateClient message: {e}"); + + Vec::new() + } + } + }; + + if counterparty_is_provider { + info!( + "will submit consumer light client attack evidence to client `{}` on provider chain `{}`", + counterparty_client_id, + counterparty.id(), + ); + + let msg = MsgSubmitIcsConsumerMisbehaviour { + submitter: signer.clone(), + misbehaviour: misbehaviour.clone(), + } + .to_any(); + + msgs.push(msg); + }; + + // We do not need to submit the misbehaviour if the client is already frozen. + if !counterparty_client_is_frozen { + info!( + "will submit light client attack evidence to client `{}` on counterparty chain `{}`", + counterparty_client_id, + counterparty.id(), + ); + + let msg = MsgSubmitMisbehaviour { + client_id: counterparty_client_id.clone(), + misbehaviour: misbehaviour.to_any(), + signer, + } + .to_any(); + + msgs.push(msg); + } + + if msgs.is_empty() { + warn!( + "skipping light client attack evidence for client `{}` on counterparty chain `{}`", + counterparty_client_id, + counterparty.id() + ); + + warn!("reason: no messages to submit"); + + return Ok(()); + } + + let tracked_msgs = TrackedMsgs::new_static(msgs, "light_client_attack_evidence"); + let responses = counterparty.send_messages_and_wait_check_tx(tracked_msgs)?; + + match responses.first() { + Some(response) if response.code.is_ok() => { + info!( + "successfully submitted light client attack evidence for client `{}` to counterparty chain `{}`, tx hash: {}", + counterparty_client_id, + counterparty.id(), + response.hash + ); + + Ok(()) + } + Some(response) => Err(eyre::eyre!( + "failed to submit light client attack evidence to counterparty chain `{}`: {response:?}", + counterparty.id() + )), + + None => Err(eyre::eyre!( + "failed to submit light client attack evidence to counterparty chain `{}`: no response from chain", + counterparty.id() + )), + } +} + +fn has_consensus_state( + chain: &BaseChainHandle, + client_id: &ClientId, + consensus_height: Height, +) -> bool { + use ibc_relayer::chain::requests::QueryConsensusStateRequest; + + let res = chain.query_consensus_state( + QueryConsensusStateRequest { + client_id: client_id.clone(), + consensus_height, + query_height: QueryHeight::Latest, + }, + IncludeProof::No, + ); + + res.is_ok() +} + +/// If the misbehaving chain is a CCV consumer chain, +/// then try fetch the consumer chains of the counterparty chains. +/// If that fails, then the counterparty chain is not a provider chain. +/// Otherwise, check if the misbehaving chain is a consumer of the counterparty chain, +/// which is then definitely a provider. +fn is_counterparty_provider( + chain: &CosmosSdkChain, + counterparty_chain_handle: &BaseChainHandle, + counterparty_client_id: &ClientId, +) -> bool { + if chain.config().ccv_consumer_chain { + let consumer_chains = counterparty_chain_handle + .query_consumer_chains() + .unwrap_or_default(); // If the query fails, use an empty list of consumers + + consumer_chains.iter().any(|(chain_id, client_id)| { + chain_id == chain.id() && client_id == counterparty_client_id + }) + } else { + false + } +} + +/// Fetch all the counterparty clients of the given chain. +/// A counterparty client is a client that has a connection with that chain. +/// +/// 1. Fetch all connections on the given chain +/// 2. For each connection: +/// 2.1. Fetch the client state of the counterparty client of that connection. +/// 2.2. From the client state, extract the chain id of the counterparty chain. +/// 4. Return a list of all counterparty chains and counterparty clients. +fn fetch_all_counterparty_clients( + chain: &CosmosSdkChain, +) -> eyre::Result> { + use ibc_relayer::chain::requests::{QueryClientStateRequest, QueryConnectionsRequest}; + + let connections = chain.query_connections(QueryConnectionsRequest { + pagination: Some(PageRequest::all()), + })?; + + debug!("found {} connections", connections.len()); + + let mut counterparty_clients = vec![]; + + for connection in connections { + debug!( + "fetching counterparty client state for connection `{}`", + connection.connection_id + ); + + let client_id = connection.connection_end.client_id(); + + let client_state = chain.query_client_state( + QueryClientStateRequest { + client_id: client_id.clone(), + height: QueryHeight::Latest, + }, + IncludeProof::No, + ); + + let client_state = match client_state { + Ok((client_state, _)) => client_state, + Err(e) => { + error!( + "failed to fetch client state for counterparty client `{client_id}`, skipping..." + ); + error!("reason: {e}"); + + continue; + } + }; + + let counterparty_chain_id = client_state.chain_id(); + info!("found counterparty client with id `{client_id}` on counterparty chain `{counterparty_chain_id}`"); + + counterparty_clients.push((counterparty_chain_id, client_id.clone())); + } + + Ok(counterparty_clients) +} + +/// Build the two headers to submit as part of the `MsgSubmitMisbehaviour` message. +fn build_evidence_headers( + rt: Arc, + chain: &CosmosSdkChain, + lc: LightClientAttackEvidence, +) -> eyre::Result<(TendermintHeader, TendermintHeader)> { + if lc.conflicting_block.signed_header.header.height == lc.common_height { + return Err(eyre::eyre!( + "invalid evidence: header height ({}) is equal to common height ({})! cannot submit evidence", + lc.conflicting_block.signed_header.header.height, + lc.common_height + )); + } + + let trusted_height = lc.common_height; + + let trusted_validators = rt + .block_on(chain.rpc_client.validators(trusted_height, Paging::All))? + .validators; + + let trusted_header = rt + .block_on(chain.rpc_client.commit(trusted_height))? + .signed_header; + + let trusted_proposer = trusted_header.header.proposer_address; + + let trusted_validator_set = + validator::Set::with_proposer(trusted_validators, trusted_proposer)?; + + let trusted_height = Height::from_tm(trusted_height, chain.id()); + + let header1 = { + TendermintHeader { + signed_header: lc.conflicting_block.signed_header, + validator_set: lc.conflicting_block.validator_set, + trusted_height, + trusted_validator_set: trusted_validator_set.clone(), + } + }; + + let header2 = { + let signed_header = rt + .block_on(chain.rpc_client.commit(header1.signed_header.header.height))? + .signed_header; + + let validators = rt + .block_on( + chain + .rpc_client + .validators(header1.signed_header.header.height, Paging::All), + )? + .validators; + + let validator_set = + validator::Set::with_proposer(validators, signed_header.header.proposer_address)?; + + TendermintHeader { + signed_header, + validator_set, + trusted_height, + trusted_validator_set, + } + }; + + Ok((header1, header2)) +} + +#[cfg(test)] +mod tests { + use super::EvidenceCmd; + + use abscissa_core::clap::Parser; + use ibc_relayer_types::core::ics24_host::identifier::ChainId; + + #[test] + fn test_misbehaviour() { + assert_eq!( + EvidenceCmd { + chain_id: ChainId::from_string("chain_id"), + check_past_blocks: 100, + key_name: None, + }, + EvidenceCmd::parse_from(["test", "--chain", "chain_id"]) + ) + } + + #[test] + fn test_misbehaviour_no_chain() { + assert!(EvidenceCmd::try_parse_from(["test"]).is_err()) + } +} diff --git a/crates/relayer-cli/src/commands/fee/register_counterparty_payee.rs b/crates/relayer-cli/src/commands/fee/register_counterparty_payee.rs index 2105233720..de82f5a7ec 100644 --- a/crates/relayer-cli/src/commands/fee/register_counterparty_payee.rs +++ b/crates/relayer-cli/src/commands/fee/register_counterparty_payee.rs @@ -47,7 +47,11 @@ pub struct RegisterCounterpartyPayeeCmd { required = true, value_name = "COUNTERPARTY_PAYEE_ADDRESS", help_heading = "FLAGS", - help = "Address of the counterparty payee" + help = "Address of the counterparty payee.\n\nNote that there exists a configuration \ + parameter `auto_register_counterparty_payee` that can be enabled in order to have \ + Hermes automatically register the counterparty payee on the destination chain to the \ + relayer's address on the source chain. This option can be used for simple configuration \ + of the relayer to receive fees for relaying RecvPackets on fee-enabled channels." )] counterparty_payee_address: String, } diff --git a/crates/relayer-cli/src/commands/fee/transfer.rs b/crates/relayer-cli/src/commands/fee/transfer.rs index 1d93a39978..3893a2d232 100644 --- a/crates/relayer-cli/src/commands/fee/transfer.rs +++ b/crates/relayer-cli/src/commands/fee/transfer.rs @@ -159,7 +159,7 @@ impl Override for FeeTransferCmd { })?; if let Some(ref key_name) = self.key_name { - src_chain_config.key_name = key_name.to_string(); + src_chain_config.set_key_name(key_name.to_string()); } Ok(config) diff --git a/crates/relayer-cli/src/commands/health.rs b/crates/relayer-cli/src/commands/health.rs index ebd2ecab5a..8514bb087f 100644 --- a/crates/relayer-cli/src/commands/health.rs +++ b/crates/relayer-cli/src/commands/health.rs @@ -16,12 +16,12 @@ impl Runnable for HealthCheckCmd { let config = app_config(); for ch in &config.chains { - let _span = tracing::error_span!("health_check", chain = %ch.id).entered(); + let _span = tracing::error_span!("health_check", chain = %ch.id()).entered(); info!("performing health check..."); let chain = - spawn_chain_runtime(&config, &ch.id).unwrap_or_else(exit_with_unrecoverable_error); + spawn_chain_runtime(&config, ch.id()).unwrap_or_else(exit_with_unrecoverable_error); match chain.health_check() { Ok(Healthy) => info!("chain is healthy"), diff --git a/crates/relayer-cli/src/commands/keys/add.rs b/crates/relayer-cli/src/commands/keys/add.rs index 85b528b6b2..b24514d00a 100644 --- a/crates/relayer-cli/src/commands/keys/add.rs +++ b/crates/relayer-cli/src/commands/keys/add.rs @@ -10,7 +10,6 @@ use abscissa_core::{Command, Runnable}; use eyre::eyre; use hdpath::StandardHDPath; use ibc_relayer::{ - chain::ChainType, config::{ChainConfig, Config}, keyring::{ AnySigningKeyPair, KeyRing, Secp256k1KeyPair, SigningKeyPair, SigningKeyPairSized, Store, @@ -107,7 +106,7 @@ impl KeysAddCmd { let name = self .key_name .clone() - .unwrap_or_else(|| chain_config.key_name.clone()); + .unwrap_or_else(|| chain_config.key_name().to_string()); let hd_path = StandardHDPath::from_str(&self.hd_path) .map_err(|_| eyre!("invalid derivation path: {}", self.hd_path))?; @@ -151,7 +150,7 @@ impl Runnable for KeysAddCmd { "Added key '{}' ({}) on chain {}", opts.name, key.account(), - opts.config.id + opts.config.id(), )) .exit(), Err(e) => Output::error(format!( @@ -175,7 +174,7 @@ impl Runnable for KeysAddCmd { "Restored key '{}' ({}) on chain {}", opts.name, key.account(), - opts.config.id + opts.config.id() )) .exit(), Err(e) => Output::error(format!( @@ -203,8 +202,8 @@ pub fn add_key( hd_path: &StandardHDPath, overwrite: bool, ) -> eyre::Result { - let key_pair = match config.r#type { - ChainType::CosmosSdk => { + let key_pair = match config { + ChainConfig::CosmosSdk(config) => { let mut keyring = KeyRing::new_secp256k1( Store::Test, &config.account_prefix, @@ -236,8 +235,8 @@ pub fn restore_key( let mnemonic_content = fs::read_to_string(mnemonic).map_err(|_| eyre!("error reading the mnemonic file"))?; - let key_pair = match config.r#type { - ChainType::CosmosSdk => { + let key_pair = match config { + ChainConfig::CosmosSdk(config) => { let mut keyring = KeyRing::new_secp256k1( Store::Test, &config.account_prefix, diff --git a/crates/relayer-cli/src/commands/keys/balance.rs b/crates/relayer-cli/src/commands/keys/balance.rs index 5a64bea74d..b3c1edd90d 100644 --- a/crates/relayer-cli/src/commands/keys/balance.rs +++ b/crates/relayer-cli/src/commands/keys/balance.rs @@ -4,6 +4,7 @@ use abscissa_core::clap::Parser; use abscissa_core::{Command, Runnable}; use ibc_relayer::chain::handle::ChainHandle; +use ibc_relayer::config::ChainConfig; use ibc_relayer_types::core::ics24_host::identifier::ChainId; use crate::application::app_config; @@ -75,7 +76,9 @@ fn get_balance(chain: impl ChainHandle, key_name: Option, denom: Option< // Retrieve the key name string to output. let key_name = key_name.unwrap_or_else(|| { let chain_config = chain.config().unwrap_or_else(exit_with_unrecoverable_error); - chain_config.key_name + match chain_config { + ChainConfig::CosmosSdk(chain_config) => chain_config.key_name, + } }); Output::success_msg(format!( @@ -95,7 +98,9 @@ fn get_balances(chain: impl ChainHandle, key_name: Option) { // Retrieve the key name string to output. let key_name = key_name.unwrap_or_else(|| { let chain_config = chain.config().unwrap_or_else(exit_with_unrecoverable_error); - chain_config.key_name + match chain_config { + ChainConfig::CosmosSdk(chain_config) => chain_config.key_name, + } }); let mut pretty_output = format!("Balances for key `{key_name}`:"); diff --git a/crates/relayer-cli/src/commands/keys/delete.rs b/crates/relayer-cli/src/commands/keys/delete.rs index fdc892afa9..fe25e8a056 100644 --- a/crates/relayer-cli/src/commands/keys/delete.rs +++ b/crates/relayer-cli/src/commands/keys/delete.rs @@ -3,7 +3,6 @@ use abscissa_core::{Command, Runnable}; use eyre::eyre; use ibc_relayer::{ - chain::ChainType, config::{ChainConfig, Config}, keyring::{KeyRing, Store}, }; @@ -95,7 +94,7 @@ impl Runnable for KeysDeleteCmd { match opts.id { KeysDeleteId::All => match delete_all_keys(&opts.config) { Ok(_) => { - Output::success_msg(format!("Removed all keys on chain {}", opts.config.id)) + Output::success_msg(format!("Removed all keys on chain {}", opts.config.id())) .exit() } Err(e) => Output::error(e).exit(), @@ -103,7 +102,8 @@ impl Runnable for KeysDeleteCmd { KeysDeleteId::Named(key_name) => match delete_key(&opts.config, key_name) { Ok(_) => Output::success_msg(format!( "Removed key ({}) on chain {}", - key_name, opts.config.id + key_name, + opts.config.id(), )) .exit(), Err(e) => Output::error(e).exit(), @@ -113,8 +113,8 @@ impl Runnable for KeysDeleteCmd { } pub fn delete_key(config: &ChainConfig, key_name: &str) -> eyre::Result<()> { - match config.r#type { - ChainType::CosmosSdk => { + match config { + ChainConfig::CosmosSdk(config) => { let mut keyring = KeyRing::new_secp256k1( Store::Test, &config.account_prefix, @@ -128,8 +128,8 @@ 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 => { + match config { + ChainConfig::CosmosSdk(config) => { let mut keyring = KeyRing::new_secp256k1( Store::Test, &config.account_prefix, diff --git a/crates/relayer-cli/src/commands/keys/list.rs b/crates/relayer-cli/src/commands/keys/list.rs index 1713546a4e..cf3ec72651 100644 --- a/crates/relayer-cli/src/commands/keys/list.rs +++ b/crates/relayer-cli/src/commands/keys/list.rs @@ -6,10 +6,7 @@ use abscissa_core::{Command, Runnable}; use crate::conclude::Output; use crate::{application::app_config, conclude::json}; -use ibc_relayer::{ - config::{ChainConfig, Config}, - keyring::list_keys, -}; +use ibc_relayer::config::{ChainConfig, Config}; use ibc_relayer_types::core::ics24_host::identifier::ChainId; #[derive(Clone, Command, Debug, Parser, PartialEq, Eq)] @@ -45,7 +42,7 @@ impl Runnable for KeysListCmd { Ok(result) => result, }; - match list_keys(&opts.chain_config) { + match opts.chain_config.list_keys() { Ok(keys) if json() => { let keys = keys.into_iter().collect::>(); Output::success(keys).exit() diff --git a/crates/relayer-cli/src/commands/listen.rs b/crates/relayer-cli/src/commands/listen.rs index 1806fc310d..3858dc3a8e 100644 --- a/crates/relayer-cli/src/commands/listen.rs +++ b/crates/relayer-cli/src/commands/listen.rs @@ -101,7 +101,7 @@ impl Runnable for ListenCmd { } /// Listen to events -#[instrument(skip_all, level = "error", fields(chain = %config.id))] +#[instrument(skip_all, level = "error", fields(chain = %config.id()))] pub fn listen(config: &ChainConfig, filters: &[EventFilter]) -> eyre::Result<()> { let rt = Arc::new(TokioRuntime::new()?); let compat_mode = detect_compatibility_mode(config, rt.clone())?; @@ -143,37 +143,47 @@ fn subscribe( compat_mode: CompatMode, rt: Arc, ) -> eyre::Result { - let (event_source, monitor_tx) = match &chain_config.event_source { - EventSourceMode::Push { url, batch_delay } => EventSource::websocket( - chain_config.id.clone(), - url.clone(), - compat_mode, - *batch_delay, - rt, - ), - EventSourceMode::Pull { interval } => EventSource::rpc( - chain_config.id.clone(), - HttpClient::new(chain_config.rpc_addr.clone())?, - *interval, - rt, - ), - }?; - - thread::spawn(move || event_source.run()); - - let subscription = monitor_tx.subscribe()?; - Ok(subscription) + // Q: Should this be restricted only to backends that support it, + // or are all backends expected to support subscriptions? + match chain_config { + ChainConfig::CosmosSdk(config) => { + let (event_source, monitor_tx) = match &config.event_source { + EventSourceMode::Push { url, batch_delay } => EventSource::websocket( + chain_config.id().clone(), + url.clone(), + compat_mode, + *batch_delay, + rt, + ), + EventSourceMode::Pull { interval } => EventSource::rpc( + chain_config.id().clone(), + HttpClient::new(config.rpc_addr.clone())?, + *interval, + rt, + ), + }?; + + thread::spawn(move || event_source.run()); + + let subscription = monitor_tx.subscribe()?; + Ok(subscription) + } + } } fn detect_compatibility_mode( config: &ChainConfig, rt: Arc, ) -> eyre::Result { - let client = HttpClient::new(config.rpc_addr.clone())?; + // TODO(erwan): move this to the cosmos sdk endpoint implementation + let rpc_addr = match config { + ChainConfig::CosmosSdk(config) => config.rpc_addr.clone(), + }; + let client = HttpClient::new(rpc_addr)?; let status = rt.block_on(client.status())?; let compat_mode = CompatMode::from_version(status.node_info.version).unwrap_or_else(|e| { - warn!("Unsupported tendermint version, will use v0.37 compatibility mode but relaying might not work as desired: {e}"); - CompatMode::V0_37 + warn!("Unsupported tendermint version, will use v0.34 compatibility mode but relaying might not work as desired: {e}"); + CompatMode::V0_34 }); Ok(compat_mode) } diff --git a/crates/relayer-cli/src/commands/query/channel_ends.rs b/crates/relayer-cli/src/commands/query/channel_ends.rs index 83a94fdf76..aaa668beb1 100644 --- a/crates/relayer-cli/src/commands/query/channel_ends.rs +++ b/crates/relayer-cli/src/commands/query/channel_ends.rs @@ -9,7 +9,6 @@ use ibc_relayer::chain::requests::{ }; use ibc_relayer::client_state::AnyClientState; use ibc_relayer::registry::Registry; -use ibc_relayer_types::core::ics02_client::client_state::ClientState; use ibc_relayer_types::core::ics03_connection::connection::ConnectionEnd; use ibc_relayer_types::core::ics04_channel::channel::{ChannelEnd, State}; use ibc_relayer_types::core::ics24_host::identifier::ChainId; diff --git a/crates/relayer-cli/src/commands/query/channels.rs b/crates/relayer-cli/src/commands/query/channels.rs index fce0441b1d..a516854416 100644 --- a/crates/relayer-cli/src/commands/query/channels.rs +++ b/crates/relayer-cli/src/commands/query/channels.rs @@ -11,7 +11,6 @@ use ibc_relayer::chain::requests::{ QueryConnectionRequest, QueryHeight, }; use ibc_relayer::registry::Registry; -use ibc_relayer_types::core::ics02_client::client_state::ClientState; use ibc_relayer_types::core::ics04_channel::channel::{ChannelEnd, State}; use ibc_relayer_types::core::ics24_host::identifier::{ ChainId, ChannelId, ConnectionId, PortChannelId, PortId, diff --git a/crates/relayer-cli/src/commands/query/clients.rs b/crates/relayer-cli/src/commands/query/clients.rs index 2290b5661c..0ced719b2b 100644 --- a/crates/relayer-cli/src/commands/query/clients.rs +++ b/crates/relayer-cli/src/commands/query/clients.rs @@ -4,7 +4,6 @@ use ibc_relayer::chain::handle::ChainHandle; use serde::Serialize; use ibc_relayer::chain::requests::{PageRequest, QueryClientStatesRequest}; -use ibc_relayer_types::core::ics02_client::client_state::ClientState; use ibc_relayer_types::core::ics24_host::identifier::{ChainId, ClientId}; use crate::cli_utils::spawn_chain_runtime; diff --git a/crates/relayer-cli/src/commands/query/connections.rs b/crates/relayer-cli/src/commands/query/connections.rs index f3a19e3585..dadef9d6a2 100644 --- a/crates/relayer-cli/src/commands/query/connections.rs +++ b/crates/relayer-cli/src/commands/query/connections.rs @@ -5,7 +5,6 @@ use ibc_relayer::chain::handle::ChainHandle; use ibc_relayer::chain::requests::{ IncludeProof, PageRequest, QueryClientStateRequest, QueryConnectionsRequest, QueryHeight, }; -use ibc_relayer_types::core::ics02_client::client_state::ClientState; use ibc_relayer_types::core::ics24_host::identifier::{ChainId, ConnectionId}; use crate::cli_utils::spawn_chain_runtime; @@ -61,19 +60,27 @@ impl Runnable for QueryConnectionsCmd { connections.retain(|connection| { let client_id = connection.end().client_id().to_owned(); let chain_height = chain.query_latest_height(); - let (client_state, _) = chain - .query_client_state( - QueryClientStateRequest { - client_id, - height: QueryHeight::Specific(chain_height.unwrap()), - }, - IncludeProof::No, - ) - .unwrap(); - - let counterparty_chain_id = client_state.chain_id(); - - counterparty_chain_id == counterparty_filter_id + + let client_state = chain.query_client_state( + QueryClientStateRequest { + client_id: client_id.clone(), + height: QueryHeight::Specific(chain_height.unwrap()), + }, + IncludeProof::No, + ); + + match client_state { + Ok((client_state, _)) => { + let counterparty_chain_id = client_state.chain_id(); + counterparty_chain_id == counterparty_filter_id + } + Err(e) => { + warn!("failed to query client state for client {client_id}, skipping..."); + warn!("reason: {e}"); + + false + } + } }); } diff --git a/crates/relayer-cli/src/commands/tx/channel.rs b/crates/relayer-cli/src/commands/tx/channel.rs index 83b6c702de..0531c85dfe 100644 --- a/crates/relayer-cli/src/commands/tx/channel.rs +++ b/crates/relayer-cli/src/commands/tx/channel.rs @@ -1,3 +1,5 @@ +#![allow(clippy::redundant_closure_call)] + use abscissa_core::clap::Parser; use abscissa_core::{Command, Runnable}; diff --git a/crates/relayer-cli/src/commands/tx/client.rs b/crates/relayer-cli/src/commands/tx/client.rs index e528e0a4bc..827d1c5cc1 100644 --- a/crates/relayer-cli/src/commands/tx/client.rs +++ b/crates/relayer-cli/src/commands/tx/client.rs @@ -7,14 +7,16 @@ use std::thread; use abscissa_core::clap::Parser; use abscissa_core::{Command, Runnable}; -use ibc_relayer::chain::requests::{ - IncludeProof, PageRequest, QueryClientStateRequest, QueryClientStatesRequest, QueryHeight, -}; use ibc_relayer::config::Config; use ibc_relayer::event::IbcEventWithHeight; use ibc_relayer::foreign_client::{CreateOptions, ForeignClient}; use ibc_relayer::{chain::handle::ChainHandle, config::GenesisRestart}; -use ibc_relayer_types::core::ics02_client::client_state::ClientState; +use ibc_relayer::{ + chain::requests::{ + IncludeProof, PageRequest, QueryClientStateRequest, QueryClientStatesRequest, QueryHeight, + }, + config::ChainConfig, +}; use ibc_relayer_types::core::ics24_host::identifier::{ChainId, ClientId}; use ibc_relayer_types::events::IbcEvent; use ibc_relayer_types::Height; @@ -202,8 +204,19 @@ impl Runnable for TxUpdateClientCmd { }; if let Some(restart_params) = self.genesis_restart_params() { - if let Some(c) = config.find_chain_mut(&reference_chain_id) { - c.genesis_restart = Some(restart_params); + match config.find_chain_mut(&reference_chain_id) { + Some(chain_config) => match chain_config { + ChainConfig::CosmosSdk(chain_config) => { + chain_config.genesis_restart = Some(restart_params) + } + }, + None => { + Output::error(format!( + "Chain '{}' is unsupported, or not found in the configuration", + reference_chain_id + )) + .exit(); + } } } @@ -435,15 +448,15 @@ impl Runnable for TxUpgradeClientsCmd { .chains .iter() .filter(|&chain| { - self.reference_chain_id != chain.id + self.reference_chain_id != *chain.id() && (self.host_chain_id.is_none() - || self.host_chain_id == Some(chain.id.clone())) + || self.host_chain_id == Some(chain.id().clone())) }) .map(|chain| { self.upgrade_clients_for_chain( &config, reference_chain.clone(), - &chain.id, + chain.id(), reference_upgrade_height, ) }) diff --git a/crates/relayer-cli/src/commands/tx/connection.rs b/crates/relayer-cli/src/commands/tx/connection.rs index a16484bdc3..fb88a61d2e 100644 --- a/crates/relayer-cli/src/commands/tx/connection.rs +++ b/crates/relayer-cli/src/commands/tx/connection.rs @@ -1,3 +1,5 @@ +#![allow(clippy::redundant_closure_call)] + use abscissa_core::clap::Parser; use abscissa_core::{Command, Runnable}; diff --git a/crates/relayer-cli/src/commands/tx/transfer.rs b/crates/relayer-cli/src/commands/tx/transfer.rs index 50d43a0afa..66b14026ae 100644 --- a/crates/relayer-cli/src/commands/tx/transfer.rs +++ b/crates/relayer-cli/src/commands/tx/transfer.rs @@ -131,7 +131,7 @@ impl Override for TxIcs20MsgTransferCmd { })?; if let Some(ref key_name) = self.key_name { - src_chain_config.key_name = key_name.to_string(); + src_chain_config.set_key_name(key_name.to_string()); } Ok(config) diff --git a/crates/relayer-cli/src/components.rs b/crates/relayer-cli/src/components.rs index ba46f7ffd2..a4751e343f 100644 --- a/crates/relayer-cli/src/components.rs +++ b/crates/relayer-cli/src/components.rs @@ -8,8 +8,8 @@ use ibc_relayer::{ util::debug_section::DebugSection, }; -use crate::config::Error; use crate::tracing_handle::ReloadHandle; +use ibc_relayer::config::Error; /// The name of the environment variable through which one can override /// the tracing filter built in [`build_tracing_filter`]. diff --git a/crates/relayer-cli/src/config.rs b/crates/relayer-cli/src/config.rs index 6e5d6218a1..39e5f9106d 100644 --- a/crates/relayer-cli/src/config.rs +++ b/crates/relayer-cli/src/config.rs @@ -1,172 +1,8 @@ -//! Validation code for the Hermes configuration file. -//! -//! See instructions in `commands.rs` to specify the path to your -//! application's configuration file and/or command-line options -//! for specifying it. - -use alloc::collections::BTreeSet; +use crate::prelude::app_reader; use std::path::PathBuf; -use flex_error::{define_error, TraceError}; -use ibc_relayer::config::{ChainConfig, Config, ModeConfig}; -use ibc_relayer_types::core::ics24_host::identifier::ChainId; -use tendermint_light_client_verifier::types::TrustThreshold; -use tracing_subscriber::filter::ParseError; - -use crate::application::app_reader; - /// Get the path to configuration file pub fn config_path() -> Option { let app = app_reader(); app.config_path().cloned() } - -// Specifies all the possible syntactic errors -// that a Hermes configuration file could contain. -define_error! { - Error { - ZeroChain - |_| { "config file does not specify any chain" }, - - InvalidLogDirective - { directive: String, } - [ TraceError ] - |e| { - format!("invalid log directive: {0:?}", e.directive) - }, - - InvalidMode - { reason: String, } - |e| { - format!("config file specifies invalid mode config, caused by: {0}", - e.reason) - }, - - DuplicateChains - { chain_id: ChainId } - |e| { - format!("config file has duplicate entry for the chain '{0}'", - e.chain_id) - }, - - InvalidTrustThreshold - { - threshold: TrustThreshold, - chain_id: ChainId, - reason: String - } - |e| { - format!("config file specifies an invalid `trust_threshold` ({0}) for the chain '{1}', caused by: {2}", - e.threshold, e.chain_id, e.reason) - }, - - DeprecatedGasAdjustment - { - gas_adjustment: f64, - gas_multiplier: f64, - chain_id: ChainId, - } - |e| { - format!( - "config file specifies deprecated setting `gas_adjustment = {1}` for the chain '{0}'; \ - to get the same behavior, use `gas_multiplier = {2}", - e.chain_id, e.gas_adjustment, e.gas_multiplier - ) - }, - } -} - -#[derive(Clone, Debug)] -pub enum Diagnostic { - Warning(E), - Error(E), -} - -/// Method for syntactic validation of the input configuration file. -pub fn validate_config(config: &Config) -> Result<(), Diagnostic> { - // Check for duplicate chain configuration and invalid trust thresholds - let mut unique_chain_ids = BTreeSet::new(); - for c in config.chains.iter() { - let already_present = !unique_chain_ids.insert(c.id.clone()); - if already_present { - return Err(Diagnostic::Error(Error::duplicate_chains(c.id.clone()))); - } - - validate_trust_threshold(&c.id, c.trust_threshold)?; - - // Validate gas-related settings - validate_gas_settings(&c.id, c)?; - } - - // Check for invalid mode config - validate_mode(&config.mode)?; - - Ok(()) -} - -fn validate_mode(mode: &ModeConfig) -> Result<(), Diagnostic> { - if mode.all_disabled() { - return Err(Diagnostic::Warning(Error::invalid_mode( - "all operation modes of Hermes are disabled, relayer won't perform any action aside from subscribing to events".to_string(), - ))); - } - - if mode.clients.enabled && !mode.clients.refresh && !mode.clients.misbehaviour { - return Err(Diagnostic::Error(Error::invalid_mode( - "either `refresh` or `misbehaviour` must be set to true if `clients.enabled` is set to true".to_string(), - ))); - } - - Ok(()) -} - -/// Check that the trust threshold is: -/// -/// a) non-zero -/// b) greater or equal to 1/3 -/// c) strictly less than 1 -fn validate_trust_threshold( - id: &ChainId, - trust_threshold: TrustThreshold, -) -> Result<(), Diagnostic> { - if trust_threshold.denominator() == 0 { - return Err(Diagnostic::Error(Error::invalid_trust_threshold( - trust_threshold, - id.clone(), - "trust threshold denominator cannot be zero".to_string(), - ))); - } - - if trust_threshold.numerator() * 3 < trust_threshold.denominator() { - return Err(Diagnostic::Error(Error::invalid_trust_threshold( - trust_threshold, - id.clone(), - "trust threshold cannot be < 1/3".to_string(), - ))); - } - - if trust_threshold.numerator() >= trust_threshold.denominator() { - return Err(Diagnostic::Error(Error::invalid_trust_threshold( - trust_threshold, - id.clone(), - "trust threshold cannot be >= 1".to_string(), - ))); - } - - Ok(()) -} - -fn validate_gas_settings(id: &ChainId, config: &ChainConfig) -> Result<(), Diagnostic> { - // Check that the gas_adjustment option is not set - if let Some(gas_adjustment) = config.gas_adjustment { - let gas_multiplier = gas_adjustment + 1.0; - - return Err(Diagnostic::Error(Error::deprecated_gas_adjustment( - gas_adjustment, - gas_multiplier, - id.clone(), - ))); - } - - Ok(()) -} diff --git a/crates/relayer-rest/Cargo.toml b/crates/relayer-rest/Cargo.toml index 17214cfa22..ceee740ed1 100644 --- a/crates/relayer-rest/Cargo.toml +++ b/crates/relayer-rest/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ibc-relayer-rest" -version = "0.25.0" +version = "0.26.0" authors = ["Informal Systems "] edition = "2021" license = "Apache-2.0" @@ -14,8 +14,8 @@ description = """ """ [dependencies] -ibc-relayer-types = { version = "0.25.0", path = "../relayer-types" } -ibc-relayer = { version = "0.25.0", path = "../relayer" } +ibc-relayer-types = { version = "0.26.0", path = "../relayer-types" } +ibc-relayer = { version = "0.26.0", path = "../relayer" } crossbeam-channel = "0.5" serde = "1.0" diff --git a/crates/relayer-rest/tests/mock.rs b/crates/relayer-rest/tests/mock.rs index 49db676549..b18a1b4531 100644 --- a/crates/relayer-rest/tests/mock.rs +++ b/crates/relayer-rest/tests/mock.rs @@ -64,7 +64,7 @@ async fn version() { let rest_api_version = VersionInfo { name: "ibc-relayer-rest".to_string(), - version: "0.25.0".to_string(), + version: "0.26.0".to_string(), }; let result: JsonResult<_, ()> = JsonResult::Success(vec![version.clone(), rest_api_version]); @@ -96,6 +96,7 @@ async fn get_chains() { const MOCK_CHAIN_CONFIG: &str = r#" id = 'mock-0' +type = 'CosmosSdk' rpc_addr = 'http://127.0.0.1:26557' grpc_addr = 'http://127.0.0.1:9091' event_source = { mode = 'push', url = 'ws://127.0.0.1:26557/websocket', batch_delay = '500ms' } diff --git a/crates/relayer-types/Cargo.toml b/crates/relayer-types/Cargo.toml index 0b20dc7dc4..c67b61661b 100644 --- a/crates/relayer-types/Cargo.toml +++ b/crates/relayer-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ibc-relayer-types" -version = "0.25.0" +version = "0.26.0" edition = "2021" license = "Apache-2.0" readme = "README.md" @@ -24,13 +24,12 @@ mocks = ["tendermint-testgen", "clock"] [dependencies] # Proto definitions for all IBC-related interfaces, e.g., connections or channels. -ibc-proto = { version = "0.37.0" } +ibc-proto = { version = "0.38.0", features = ["serde"] } ics23 = { version = "0.11.0", features = ["std", "host-functions"] } time = { version = "0.3" } serde_derive = { version = "1.0.104" } serde = { version = "1.0" } serde_json = { version = "1" } -erased-serde = { version = "0.3" } prost = { version = "0.12" } bytes = { version = "1.4.0" } subtle-encoding = { version = "0.5" } @@ -39,7 +38,6 @@ derive_more = { version = "0.99.17", default-features = false, features = ["from uint = { version = "0.9" } itertools = { version = "0.10.3" } primitive-types = { version = "0.12.1", default-features = false, features = ["serde_no_std"] } -dyn-clone = "1.0.12" num-rational = "0.4.1" regex = "1" diff --git a/crates/relayer-types/src/applications/ics27_ica/cosmos_tx.rs b/crates/relayer-types/src/applications/ics27_ica/cosmos_tx.rs index 8503d027dd..f6b6043de8 100644 --- a/crates/relayer-types/src/applications/ics27_ica/cosmos_tx.rs +++ b/crates/relayer-types/src/applications/ics27_ica/cosmos_tx.rs @@ -1,6 +1,6 @@ use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::applications::interchain_accounts::v1::CosmosTx as RawCosmosTx; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use serde_derive::Deserialize; use serde_derive::Serialize; diff --git a/crates/relayer-types/src/applications/ics27_ica/msgs/register.rs b/crates/relayer-types/src/applications/ics27_ica/msgs/register.rs index 67954b27d5..9c73c9de93 100644 --- a/crates/relayer-types/src/applications/ics27_ica/msgs/register.rs +++ b/crates/relayer-types/src/applications/ics27_ica/msgs/register.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use ibc_proto::ibc::applications::interchain_accounts::controller::v1::MsgRegisterInterchainAccount as RawMsgRegisterInterchainAccount; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use crate::applications::ics27_ica::error::Error; use crate::core::ics04_channel::version::Version; diff --git a/crates/relayer-types/src/applications/ics27_ica/msgs/send_tx.rs b/crates/relayer-types/src/applications/ics27_ica/msgs/send_tx.rs index 40c11a9646..72bc922a2d 100644 --- a/crates/relayer-types/src/applications/ics27_ica/msgs/send_tx.rs +++ b/crates/relayer-types/src/applications/ics27_ica/msgs/send_tx.rs @@ -1,7 +1,7 @@ use serde_derive::{Deserialize, Serialize}; use ibc_proto::ibc::applications::interchain_accounts::controller::v1::MsgSendTx as RawMsgSendTx; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use crate::applications::ics27_ica::error::Error; use crate::applications::ics27_ica::packet_data::InterchainAccountPacketData; diff --git a/crates/relayer-types/src/applications/ics28_ccv/mod.rs b/crates/relayer-types/src/applications/ics28_ccv/mod.rs new file mode 100644 index 0000000000..7ba0198166 --- /dev/null +++ b/crates/relayer-types/src/applications/ics28_ccv/mod.rs @@ -0,0 +1,4 @@ +//! The implementation of the ICS 28 Cross-Chain Validation (CCV). +//! Please see the [specification](https://github.com/cosmos/ibc/tree/main/spec/app/ics-028-cross-chain-validation#readme). + +pub mod msgs; diff --git a/crates/relayer-types/src/applications/ics28_ccv/msgs/ccv_double_voting.rs b/crates/relayer-types/src/applications/ics28_ccv/msgs/ccv_double_voting.rs new file mode 100644 index 0000000000..a1ce4291d9 --- /dev/null +++ b/crates/relayer-types/src/applications/ics28_ccv/msgs/ccv_double_voting.rs @@ -0,0 +1,85 @@ +use core::fmt; + +use ibc_proto::interchain_security::ccv::provider::v1::MsgSubmitConsumerDoubleVoting as RawIcsDoubleVoting; +use ibc_proto::Protobuf; +use tendermint::evidence::DuplicateVoteEvidence; + +use crate::clients::ics07_tendermint::header::Header; +use crate::signer::Signer; +use crate::tx_msg::Msg; + +use super::error::Error; + +pub const ICS_DOUBLE_VOTING_TYPE_URL: &str = + "/interchain_security.ccv.provider.v1.MsgSubmitConsumerDoubleVoting"; + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct MsgSubmitIcsConsumerDoubleVoting { + pub submitter: Signer, + pub duplicate_vote_evidence: DuplicateVoteEvidence, + pub infraction_block_header: Header, +} + +impl Msg for MsgSubmitIcsConsumerDoubleVoting { + type ValidationError = crate::core::ics24_host::error::ValidationError; + type Raw = RawIcsDoubleVoting; + + fn route(&self) -> String { + crate::keys::ROUTER_KEY.to_string() + } + + fn type_url(&self) -> String { + ICS_DOUBLE_VOTING_TYPE_URL.to_string() + } +} + +impl Protobuf for MsgSubmitIcsConsumerDoubleVoting {} + +impl TryFrom for MsgSubmitIcsConsumerDoubleVoting { + type Error = Error; + + fn try_from(raw: RawIcsDoubleVoting) -> Result { + Ok(Self { + submitter: raw.submitter.parse().map_err(Error::signer)?, + duplicate_vote_evidence: raw + .duplicate_vote_evidence + .ok_or_else(|| Error::invalid_raw_double_voting("missing evidence".into()))? + .try_into() + .map_err(|e| { + Error::invalid_raw_double_voting(format!("cannot convert evidence: {e}")) + })?, + infraction_block_header: raw + .infraction_block_header + .ok_or_else(|| { + Error::invalid_raw_double_voting("missing infraction block header".into()) + })? + .try_into() + .map_err(|e| { + Error::invalid_raw_double_voting(format!("cannot convert header: {e}")) + })?, + }) + } +} + +impl From for RawIcsDoubleVoting { + fn from(value: MsgSubmitIcsConsumerDoubleVoting) -> Self { + RawIcsDoubleVoting { + submitter: value.submitter.to_string(), + duplicate_vote_evidence: Some(value.duplicate_vote_evidence.into()), + infraction_block_header: Some(value.infraction_block_header.into()), + } + } +} + +impl fmt::Display for MsgSubmitIcsConsumerDoubleVoting { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + f.debug_struct("MsgSubmitIcsConsumerDoubleVoting") + .field("submitter", &self.submitter) + .field("duplicate_vote_evidence", &"[...]") + .field( + "infraction_block_header", + &self.infraction_block_header.signed_header.header.height, + ) + .finish() + } +} diff --git a/crates/relayer-types/src/applications/ics28_ccv/msgs/ccv_misbehaviour.rs b/crates/relayer-types/src/applications/ics28_ccv/msgs/ccv_misbehaviour.rs new file mode 100644 index 0000000000..8b5c6c2750 --- /dev/null +++ b/crates/relayer-types/src/applications/ics28_ccv/msgs/ccv_misbehaviour.rs @@ -0,0 +1,71 @@ +use core::fmt; + +use serde::{Deserialize, Serialize}; + +use ibc_proto::interchain_security::ccv::provider::v1::MsgSubmitConsumerMisbehaviour as RawIcsMisbehaviour; +use ibc_proto::Protobuf; + +use crate::clients::ics07_tendermint::misbehaviour::Misbehaviour; +use crate::signer::Signer; +use crate::tx_msg::Msg; + +use super::error::Error; + +pub const ICS_MISBEHAVIOR_TYPE_URL: &str = + "/interchain_security.ccv.provider.v1.MsgSubmitConsumerMisbehaviour"; + +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct MsgSubmitIcsConsumerMisbehaviour { + pub submitter: Signer, + pub misbehaviour: Misbehaviour, +} + +impl Msg for MsgSubmitIcsConsumerMisbehaviour { + type ValidationError = crate::core::ics24_host::error::ValidationError; + type Raw = RawIcsMisbehaviour; + + fn route(&self) -> String { + crate::keys::ROUTER_KEY.to_string() + } + + fn type_url(&self) -> String { + ICS_MISBEHAVIOR_TYPE_URL.to_string() + } +} + +impl Protobuf for MsgSubmitIcsConsumerMisbehaviour {} + +impl TryFrom for MsgSubmitIcsConsumerMisbehaviour { + type Error = Error; + + fn try_from(raw: RawIcsMisbehaviour) -> Result { + Ok(Self { + submitter: raw.submitter.parse().map_err(Error::signer)?, + misbehaviour: raw + .misbehaviour + .ok_or_else(|| Error::invalid_raw_misbehaviour("missing misbehaviour".into()))? + .try_into() + .map_err(|_e| { + Error::invalid_raw_misbehaviour("cannot convert misbehaviour".into()) + })?, + }) + } +} + +impl From for RawIcsMisbehaviour { + fn from(value: MsgSubmitIcsConsumerMisbehaviour) -> Self { + RawIcsMisbehaviour { + submitter: value.submitter.to_string(), + misbehaviour: Some(value.misbehaviour.into()), + } + } +} + +impl fmt::Display for MsgSubmitIcsConsumerMisbehaviour { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + f.debug_struct("MsgSubmitIcsConsumerMisbehaviour") + .field("submitter", &self.submitter) + .field("misbehaviour", &self.misbehaviour) + .finish() + } +} diff --git a/crates/relayer-types/src/applications/ics28_ccv/msgs/error.rs b/crates/relayer-types/src/applications/ics28_ccv/msgs/error.rs new file mode 100644 index 0000000000..ee5d3a2a36 --- /dev/null +++ b/crates/relayer-types/src/applications/ics28_ccv/msgs/error.rs @@ -0,0 +1,20 @@ +use flex_error::define_error; + +use crate::signer::SignerError; + +define_error! { + #[derive(Debug, PartialEq, Eq)] + Error { + InvalidRawMisbehaviour + { reason: String } + | e | { format_args!("invalid raw misbehaviour: {}", e.reason) }, + + InvalidRawDoubleVoting + { reason: String } + | e | { format_args!("invalid raw double voting: {}", e.reason) }, + + Signer + [ SignerError ] + | _ | { "failed to parse signer" }, + } +} diff --git a/crates/relayer-types/src/applications/ics28_ccv/msgs/mod.rs b/crates/relayer-types/src/applications/ics28_ccv/msgs/mod.rs new file mode 100644 index 0000000000..df28e4a73a --- /dev/null +++ b/crates/relayer-types/src/applications/ics28_ccv/msgs/mod.rs @@ -0,0 +1,3 @@ +pub mod ccv_double_voting; +pub mod ccv_misbehaviour; +pub mod error; diff --git a/crates/relayer-types/src/applications/mod.rs b/crates/relayer-types/src/applications/mod.rs index 539225bf08..7080c37fc4 100644 --- a/crates/relayer-types/src/applications/mod.rs +++ b/crates/relayer-types/src/applications/mod.rs @@ -1,6 +1,7 @@ //! Various packet encoding semantics which underpin the various types of transactions. pub mod ics27_ica; +pub mod ics28_ccv; pub mod ics29_fee; pub mod ics31_icq; pub mod transfer; diff --git a/crates/relayer-types/src/applications/transfer/error.rs b/crates/relayer-types/src/applications/transfer/error.rs index 5fdf2660aa..f0e52d946d 100644 --- a/crates/relayer-types/src/applications/transfer/error.rs +++ b/crates/relayer-types/src/applications/transfer/error.rs @@ -1,9 +1,10 @@ -use flex_error::{define_error, DisplayOnly, TraceError}; -use ibc_proto::protobuf::Error as TendermintProtoError; use std::convert::Infallible; use std::str::Utf8Error; use std::string::FromUtf8Error; + +use flex_error::{define_error, DisplayOnly, TraceError}; use subtle_encoding::Error as EncodingError; +use tendermint_proto::Error as TendermintProtoError; use uint::FromDecStrErr; use crate::core::ics04_channel::channel::Ordering; diff --git a/crates/relayer-types/src/applications/transfer/msgs/send.rs b/crates/relayer-types/src/applications/transfer/msgs/send.rs index 8529453880..36e71dc66b 100644 --- a/crates/relayer-types/src/applications/transfer/msgs/send.rs +++ b/crates/relayer-types/src/applications/transfer/msgs/send.rs @@ -1,7 +1,7 @@ use std::fmt::Display; use std::str::FromStr; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use serde_derive::Deserialize; use serde_derive::Serialize; diff --git a/crates/relayer-types/src/applications/transfer/msgs/transfer.rs b/crates/relayer-types/src/applications/transfer/msgs/transfer.rs index ffdbdc22e9..8bfc198b44 100644 --- a/crates/relayer-types/src/applications/transfer/msgs/transfer.rs +++ b/crates/relayer-types/src/applications/transfer/msgs/transfer.rs @@ -3,7 +3,7 @@ use ibc_proto::cosmos::base::v1beta1::Coin; use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::applications::transfer::v1::MsgTransfer as RawMsgTransfer; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use crate::applications::transfer::error::Error; use crate::core::ics04_channel::timeout::TimeoutHeight; diff --git a/crates/relayer-types/src/clients/ics07_tendermint/client_state.rs b/crates/relayer-types/src/clients/ics07_tendermint/client_state.rs index 0e0f800653..7c1852e27d 100644 --- a/crates/relayer-types/src/clients/ics07_tendermint/client_state.rs +++ b/crates/relayer-types/src/clients/ics07_tendermint/client_state.rs @@ -7,15 +7,13 @@ use serde::{Deserialize, Serialize}; use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::core::client::v1::Height as RawHeight; use ibc_proto::ibc::lightclients::tendermint::v1::ClientState as RawTmClientState; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use tendermint_light_client_verifier::options::Options; use crate::clients::ics07_tendermint::error::Error; use crate::clients::ics07_tendermint::header::Header as TmHeader; -use crate::core::ics02_client::client_state::{ - ClientState as Ics2ClientState, UpgradeOptions as CoreUpgradeOptions, -}; +use crate::core::ics02_client::client_state::ClientState as Ics2ClientState; use crate::core::ics02_client::client_type::ClientType; use crate::core::ics02_client::error::Error as Ics02Error; use crate::core::ics02_client::trust_threshold::TrustThreshold; @@ -199,9 +197,9 @@ pub struct UpgradeOptions { pub unbonding_period: Duration, } -impl CoreUpgradeOptions for UpgradeOptions {} - impl Ics2ClientState for ClientState { + type UpgradeOptions = UpgradeOptions; + fn chain_id(&self) -> ChainId { self.chain_id.clone() } @@ -221,14 +219,9 @@ impl Ics2ClientState for ClientState { fn upgrade( &mut self, upgrade_height: Height, - upgrade_options: &dyn CoreUpgradeOptions, + upgrade_options: UpgradeOptions, chain_id: ChainId, ) { - let upgrade_options = upgrade_options - .as_any() - .downcast_ref::() - .expect("UpgradeOptions not of type Tendermint"); - // Reset custom fields to zero values self.trusting_period = ZERO_DURATION; self.trust_threshold = TrustThreshold::CLIENT_STATE_RESET; @@ -351,7 +344,10 @@ impl TryFrom for ClientState { TENDERMINT_CLIENT_STATE_TYPE_URL => { decode_client_state(raw.value.deref()).map_err(Into::into) } - _ => Err(Ics02Error::unknown_client_state_type(raw.type_url)), + _ => Err(Ics02Error::unexpected_client_state_type( + TENDERMINT_CLIENT_STATE_TYPE_URL.to_string(), + raw.type_url, + )), } } } @@ -360,7 +356,7 @@ impl From for Any { fn from(client_state: ClientState) -> Self { Any { type_url: TENDERMINT_CLIENT_STATE_TYPE_URL.to_string(), - value: Protobuf::::encode_vec(&client_state), + value: Protobuf::::encode_vec(client_state), } } } diff --git a/crates/relayer-types/src/clients/ics07_tendermint/consensus_state.rs b/crates/relayer-types/src/clients/ics07_tendermint/consensus_state.rs index 6ba3fceba6..5cbd77732b 100644 --- a/crates/relayer-types/src/clients/ics07_tendermint/consensus_state.rs +++ b/crates/relayer-types/src/clients/ics07_tendermint/consensus_state.rs @@ -1,6 +1,6 @@ use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::lightclients::tendermint::v1::ConsensusState as RawConsensusState; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use serde::{Deserialize, Serialize}; use tendermint::{hash::Algorithm, time::Time, Hash}; use tendermint_proto::google::protobuf as tpb; @@ -123,7 +123,7 @@ impl From for Any { fn from(consensus_state: ConsensusState) -> Self { Any { type_url: TENDERMINT_CONSENSUS_STATE_TYPE_URL.to_string(), - value: Protobuf::::encode_vec(&consensus_state), + value: Protobuf::::encode_vec(consensus_state), } } } diff --git a/crates/relayer-types/src/clients/ics07_tendermint/header.rs b/crates/relayer-types/src/clients/ics07_tendermint/header.rs index a361d66737..57b99db1e9 100644 --- a/crates/relayer-types/src/clients/ics07_tendermint/header.rs +++ b/crates/relayer-types/src/clients/ics07_tendermint/header.rs @@ -3,7 +3,7 @@ use std::fmt::{Display, Error as FmtError, Formatter}; use bytes::Buf; use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::lightclients::tendermint::v1::Header as RawHeader; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use prost::Message; use serde_derive::{Deserialize, Serialize}; use tendermint::block::signed_header::SignedHeader; @@ -127,7 +127,7 @@ impl From
for Any { fn from(header: Header) -> Self { Any { type_url: TENDERMINT_HEADER_TYPE_URL.to_string(), - value: Protobuf::::encode_vec(&header), + value: Protobuf::::encode_vec(header), } } } diff --git a/crates/relayer-types/src/clients/ics07_tendermint/misbehaviour.rs b/crates/relayer-types/src/clients/ics07_tendermint/misbehaviour.rs index f8d1034a3e..1336e160bf 100644 --- a/crates/relayer-types/src/clients/ics07_tendermint/misbehaviour.rs +++ b/crates/relayer-types/src/clients/ics07_tendermint/misbehaviour.rs @@ -1,10 +1,11 @@ use ibc_proto::ibc::lightclients::tendermint::v1::Misbehaviour as RawMisbehaviour; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use serde::{Deserialize, Serialize}; use crate::clients::ics07_tendermint::error::Error; use crate::clients::ics07_tendermint::header::Header; use crate::core::ics24_host::identifier::ClientId; +use crate::tx_msg::Msg; use crate::Height; pub const TENDERMINT_MISBEHAVIOR_TYPE_URL: &str = "/ibc.lightclients.tendermint.v1.Misbehaviour"; @@ -26,6 +27,19 @@ impl crate::core::ics02_client::misbehaviour::Misbehaviour for Misbehaviour { } } +impl Msg for Misbehaviour { + type ValidationError = Error; + type Raw = RawMisbehaviour; + + fn route(&self) -> String { + crate::keys::ROUTER_KEY.to_string() + } + + fn type_url(&self) -> String { + TENDERMINT_MISBEHAVIOR_TYPE_URL.to_string() + } +} + impl Protobuf for Misbehaviour {} impl TryFrom for Misbehaviour { diff --git a/crates/relayer-types/src/core/ics02_client/client_state.rs b/crates/relayer-types/src/core/ics02_client/client_state.rs index 08c6e5677c..007bc19e17 100644 --- a/crates/relayer-types/src/core/ics02_client/client_state.rs +++ b/crates/relayer-types/src/core/ics02_client/client_state.rs @@ -1,30 +1,16 @@ +use core::fmt::Debug; use std::marker::{Send, Sync}; use std::time::Duration; -use dyn_clone::DynClone; -use erased_serde::Serialize as ErasedSerialize; -use ibc_proto::google::protobuf::Any; -use ibc_proto::protobuf::Protobuf as ErasedProtobuf; - use crate::core::ics02_client::client_type::ClientType; -use crate::core::ics02_client::error::Error; use crate::core::ics24_host::identifier::ChainId; -use crate::dynamic_typing::AsAny; use crate::Height; -use super::consensus_state::ConsensusState; - -pub trait ClientState: - AsAny - + sealed::ErasedPartialEqClientState - + DynClone - + ErasedSerialize - + ErasedProtobuf - + core::fmt::Debug - + Send - + Sync +pub trait ClientState: Clone + Debug + Send + Sync // Any: From, { + type UpgradeOptions; + /// Return the chain identifier which this client is serving (i.e., the client is verifying /// consensus states from this chain). fn chain_id(&self) -> ChainId; @@ -53,65 +39,7 @@ pub trait ClientState: fn upgrade( &mut self, upgrade_height: Height, - upgrade_options: &dyn UpgradeOptions, + upgrade_options: Self::UpgradeOptions, chain_id: ChainId, ); - - /// Convert into a boxed trait object - fn into_box(self) -> Box - where - Self: Sized, - { - Box::new(self) - } -} - -// Implements `Clone` for `Box` -dyn_clone::clone_trait_object!(ClientState); - -// Implements `serde::Serialize` for all types that have ClientState as supertrait -erased_serde::serialize_trait_object!(ClientState); - -impl PartialEq for dyn ClientState { - fn eq(&self, other: &Self) -> bool { - self.eq_client_state(other) - } -} - -// see https://github.com/rust-lang/rust/issues/31740 -impl PartialEq<&Self> for Box { - fn eq(&self, other: &&Self) -> bool { - self.eq_client_state(other.as_ref()) - } -} - -pub fn downcast_client_state(h: &dyn ClientState) -> Option<&CS> { - h.as_any().downcast_ref::() -} - -pub trait UpgradeOptions: AsAny {} - -pub struct UpdatedState { - pub client_state: Box, - pub consensus_state: Box, -} - -mod sealed { - use super::*; - - pub trait ErasedPartialEqClientState { - fn eq_client_state(&self, other: &dyn ClientState) -> bool; - } - - impl ErasedPartialEqClientState for CS - where - CS: ClientState + PartialEq, - { - fn eq_client_state(&self, other: &dyn ClientState) -> bool { - other - .as_any() - .downcast_ref::() - .map_or(false, |h| self == h) - } - } } diff --git a/crates/relayer-types/src/core/ics02_client/consensus_state.rs b/crates/relayer-types/src/core/ics02_client/consensus_state.rs index 2e17d56594..b3c6cf7d69 100644 --- a/crates/relayer-types/src/core/ics02_client/consensus_state.rs +++ b/crates/relayer-types/src/core/ics02_client/consensus_state.rs @@ -1,14 +1,8 @@ -use std::marker::{Send, Sync}; - -use dyn_clone::DynClone; -use erased_serde::Serialize as ErasedSerialize; -use ibc_proto::google::protobuf::Any; -use ibc_proto::protobuf::Protobuf as ErasedProtobuf; +use core::fmt::Debug; +use core::marker::{Send, Sync}; use crate::core::ics02_client::client_type::ClientType; -use crate::core::ics02_client::error::Error; use crate::core::ics23_commitment::commitment::CommitmentRoot; -use crate::dynamic_typing::AsAny; use crate::timestamp::Timestamp; /// Abstract of consensus state information used by the validity predicate @@ -18,15 +12,7 @@ use crate::timestamp::Timestamp; /// Effectively, that trait bound mandates implementors to derive PartialEq, /// after which our blanket implementation will implement /// `ErasedPartialEqConsensusState` for their type. -pub trait ConsensusState: - AsAny - + sealed::ErasedPartialEqConsensusState - + DynClone - + ErasedSerialize - + ErasedProtobuf - + core::fmt::Debug - + Send - + Sync +pub trait ConsensusState: Clone + Debug + Send + Sync // Any: From, { /// Type of client associated with this consensus state (eg. Tendermint) fn client_type(&self) -> ClientType; @@ -36,55 +22,4 @@ pub trait ConsensusState: /// The timestamp of the consensus state fn timestamp(&self) -> Timestamp; - - /// Convert into a boxed trait object - fn into_box(self) -> Box - where - Self: Sized, - { - Box::new(self) - } -} - -// Implements `Clone` for `Box` -dyn_clone::clone_trait_object!(ConsensusState); - -// Implements `serde::Serialize` for all types that have ConsensusState as supertrait -erased_serde::serialize_trait_object!(ConsensusState); - -pub fn downcast_consensus_state(h: &dyn ConsensusState) -> Option<&CS> { - h.as_any().downcast_ref::() -} - -impl PartialEq for dyn ConsensusState { - fn eq(&self, other: &Self) -> bool { - self.eq_consensus_state(other) - } -} - -// see https://github.com/rust-lang/rust/issues/31740 -impl PartialEq<&Self> for Box { - fn eq(&self, other: &&Self) -> bool { - self.eq_consensus_state(other.as_ref()) - } -} - -mod sealed { - use super::*; - - pub trait ErasedPartialEqConsensusState { - fn eq_consensus_state(&self, other: &dyn ConsensusState) -> bool; - } - - impl ErasedPartialEqConsensusState for CS - where - CS: ConsensusState + PartialEq, - { - fn eq_consensus_state(&self, other: &dyn ConsensusState) -> bool { - other - .as_any() - .downcast_ref::() - .map_or(false, |h| self == h) - } - } } diff --git a/crates/relayer-types/src/core/ics02_client/error.rs b/crates/relayer-types/src/core/ics02_client/error.rs index c01dd19714..6dee458d02 100644 --- a/crates/relayer-types/src/core/ics02_client/error.rs +++ b/crates/relayer-types/src/core/ics02_client/error.rs @@ -1,5 +1,5 @@ use flex_error::{define_error, TraceError}; -use ibc_proto::protobuf::Error as TendermintProtoError; +use tendermint_proto::Error as TendermintProtoError; use crate::core::ics02_client::client_type::ClientType; use crate::core::ics02_client::height::HeightError; @@ -63,6 +63,13 @@ define_error! { { client_state_type: String } | e | { format_args!("unknown client state type: {0}", e.client_state_type) }, + UnexpectedClientStateType + { + expected: String, + got: String, + } + | e | { format_args!("unexpected client state type, expected: {0}, got: {1}", e.expected, e.got) }, + EmptyClientStateResponse | _ | { "the client state was not found" }, diff --git a/crates/relayer-types/src/core/ics02_client/events.rs b/crates/relayer-types/src/core/ics02_client/events.rs index 455457fffc..3abe9b7b8d 100644 --- a/crates/relayer-types/src/core/ics02_client/events.rs +++ b/crates/relayer-types/src/core/ics02_client/events.rs @@ -3,8 +3,9 @@ use serde_derive::{Deserialize, Serialize}; use std::fmt::{Display, Error as FmtError, Formatter}; use tendermint::abci; +use tendermint_proto::Protobuf; -use super::header::Header; +use super::header::AnyHeader; use crate::core::ics02_client::client_type::ClientType; use crate::core::ics02_client::height::Height; use crate::core::ics24_host::identifier::ClientId; @@ -135,7 +136,7 @@ impl From for abci::Event { #[derive(Clone, Debug, PartialEq, Serialize)] pub struct UpdateClient { pub common: Attributes, - pub header: Option>, + pub header: Option, } impl UpdateClient { @@ -154,12 +155,7 @@ impl UpdateClient { impl Display for UpdateClient { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { - // TODO Display: Check for a solution for Box - write!( - f, - "UpdateClient {{ common: {}, header: None }}", - self.common - ) + write!(f, "UpdateClient {{ {} }}", self.common) } } @@ -178,13 +174,21 @@ impl From for IbcEvent { } } +fn encode_to_hex_string(header: AnyHeader) -> String { + let buf = header.encode_vec(); + let encoded = subtle_encoding::hex::encode(buf); + String::from_utf8(encoded).expect("hex-encoded string should always be valid UTF-8") +} + impl From for abci::Event { fn from(v: UpdateClient) -> Self { let mut attributes: Vec<_> = v.common.into(); + if let Some(h) = v.header { - let header = (HEADER_ATTRIBUTE_KEY, h.encode_to_hex_string()).into(); + let header = (HEADER_ATTRIBUTE_KEY, encode_to_hex_string(h)).into(); attributes.push(header); } + Self { kind: IbcEventType::UpdateClient.as_str().to_string(), attributes, diff --git a/crates/relayer-types/src/core/ics02_client/header.rs b/crates/relayer-types/src/core/ics02_client/header.rs index da2184d2b9..e238fe1d96 100644 --- a/crates/relayer-types/src/core/ics02_client/header.rs +++ b/crates/relayer-types/src/core/ics02_client/header.rs @@ -1,29 +1,20 @@ -use dyn_clone::DynClone; -use erased_serde::Serialize as ErasedSerialize; +use core::fmt::Debug; + +use serde::{Deserialize, Serialize}; + use ibc_proto::google::protobuf::Any; -use ibc_proto::protobuf::Protobuf as ErasedProtobuf; +use ibc_proto::Protobuf; +use crate::clients::ics07_tendermint::header::{ + decode_header as tm_decode_header, Header as TendermintHeader, TENDERMINT_HEADER_TYPE_URL, +}; use crate::core::ics02_client::client_type::ClientType; use crate::core::ics02_client::error::Error; -use crate::dynamic_typing::AsAny; use crate::timestamp::Timestamp; use crate::Height; /// Abstract of consensus state update information -/// -/// Users are not expected to implement sealed::ErasedPartialEqHeader. -/// Effectively, that trait bound mandates implementors to derive PartialEq, -/// after which our blanket implementation will implement -/// `ErasedPartialEqHeader` for their type. -pub trait Header: - AsAny - + sealed::ErasedPartialEqHeader - + DynClone - + ErasedSerialize - + ErasedProtobuf - + core::fmt::Debug - + Send - + Sync +pub trait Header: Debug + Send + Sync // Any: From, { /// The type of client (eg. Tendermint) fn client_type(&self) -> ClientType; @@ -33,48 +24,77 @@ pub trait Header: /// The timestamp of the consensus state fn timestamp(&self) -> Timestamp; - - /// Convert into a boxed trait object - fn into_box(self) -> Box - where - Self: Sized, - { - Box::new(self) - } } -// Implements `Clone` for `Box` -dyn_clone::clone_trait_object!(Header); +/// Decodes an encoded header into a known `Header` type, +pub fn decode_header(header_bytes: &[u8]) -> Result { + // For now, we only have tendermint; however when there is more than one, we + // can try decoding into all the known types, and return an error only if + // none work + let header: TendermintHeader = + Protobuf::::decode(header_bytes).map_err(Error::invalid_raw_header)?; -// Implements `serde::Serialize` for all types that have Header as supertrait -erased_serde::serialize_trait_object!(Header); + Ok(AnyHeader::Tendermint(header)) +} -pub fn downcast_header(h: &dyn Header) -> Option<&H> { - h.as_any().downcast_ref::() +#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] +#[allow(clippy::large_enum_variant)] +pub enum AnyHeader { + Tendermint(TendermintHeader), } -impl PartialEq for dyn Header { - fn eq(&self, other: &Self) -> bool { - self.eq_header(other) +impl Header for AnyHeader { + fn client_type(&self) -> ClientType { + match self { + Self::Tendermint(header) => header.client_type(), + } + } + + fn height(&self) -> Height { + match self { + Self::Tendermint(header) => header.height(), + } + } + + fn timestamp(&self) -> Timestamp { + match self { + Self::Tendermint(header) => header.timestamp(), + } } } -mod sealed { - use super::*; +impl Protobuf for AnyHeader {} + +impl TryFrom for AnyHeader { + type Error = Error; - pub trait ErasedPartialEqHeader { - fn eq_header(&self, other: &dyn Header) -> bool; + fn try_from(raw: Any) -> Result { + match raw.type_url.as_str() { + TENDERMINT_HEADER_TYPE_URL => { + let val = tm_decode_header(raw.value.as_slice())?; + Ok(AnyHeader::Tendermint(val)) + } + + _ => Err(Error::unknown_header_type(raw.type_url)), + } } +} + +impl From for Any { + fn from(value: AnyHeader) -> Self { + use ibc_proto::ibc::lightclients::tendermint::v1::Header as RawHeader; - impl ErasedPartialEqHeader for H - where - H: Header + PartialEq, - { - fn eq_header(&self, other: &dyn Header) -> bool { - other - .as_any() - .downcast_ref::() - .map_or(false, |h| self == h) + match value { + AnyHeader::Tendermint(header) => Any { + type_url: TENDERMINT_HEADER_TYPE_URL.to_string(), + value: Protobuf::::encode_vec(header), + }, } } } + +impl From for AnyHeader { + fn from(header: TendermintHeader) -> Self { + Self::Tendermint(header) + } +} diff --git a/crates/relayer-types/src/core/ics02_client/height.rs b/crates/relayer-types/src/core/ics02_client/height.rs index fb4c9c0f85..4563333244 100644 --- a/crates/relayer-types/src/core/ics02_client/height.rs +++ b/crates/relayer-types/src/core/ics02_client/height.rs @@ -3,7 +3,7 @@ use std::num::ParseIntError; use std::str::FromStr; use flex_error::{define_error, TraceError}; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use serde_derive::{Deserialize, Serialize}; use ibc_proto::ibc::core::client::v1::Height as RawHeight; diff --git a/crates/relayer-types/src/core/ics02_client/misbehaviour.rs b/crates/relayer-types/src/core/ics02_client/misbehaviour.rs index 2905ab8a68..21b296ec29 100644 --- a/crates/relayer-types/src/core/ics02_client/misbehaviour.rs +++ b/crates/relayer-types/src/core/ics02_client/misbehaviour.rs @@ -1,44 +1,12 @@ -use dyn_clone::DynClone; - -use crate::dynamic_typing::AsAny; +use core::fmt::Debug; use crate::core::ics24_host::identifier::ClientId; use crate::Height; -pub trait Misbehaviour: - AsAny + sealed::ErasedPartialEqMisbehaviour + DynClone + core::fmt::Debug + Send + Sync -{ +pub trait Misbehaviour: Clone + Debug + Send + Sync { /// The type of client (eg. Tendermint) fn client_id(&self) -> &ClientId; /// The height of the consensus state fn height(&self) -> Height; } - -// Implements `Clone` for `Box` -dyn_clone::clone_trait_object!(Misbehaviour); - -impl PartialEq for dyn Misbehaviour { - fn eq(&self, other: &Self) -> bool { - self.eq_misbehaviour(other) - } -} -mod sealed { - use super::*; - - pub trait ErasedPartialEqMisbehaviour { - fn eq_misbehaviour(&self, other: &dyn Misbehaviour) -> bool; - } - - impl ErasedPartialEqMisbehaviour for H - where - H: Misbehaviour + PartialEq, - { - fn eq_misbehaviour(&self, other: &dyn Misbehaviour) -> bool { - other - .as_any() - .downcast_ref::() - .map_or(false, |h| self == h) - } - } -} diff --git a/crates/relayer-types/src/core/ics02_client/msgs/create_client.rs b/crates/relayer-types/src/core/ics02_client/msgs/create_client.rs index 8e94a1af1c..de26fde320 100644 --- a/crates/relayer-types/src/core/ics02_client/msgs/create_client.rs +++ b/crates/relayer-types/src/core/ics02_client/msgs/create_client.rs @@ -2,7 +2,7 @@ use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::core::client::v1::MsgCreateClient as RawMsgCreateClient; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use crate::core::ics02_client::error::Error; use crate::signer::Signer; diff --git a/crates/relayer-types/src/core/ics02_client/msgs/misbehaviour.rs b/crates/relayer-types/src/core/ics02_client/msgs/misbehaviour.rs index 707ffe01cb..ae7156a834 100644 --- a/crates/relayer-types/src/core/ics02_client/msgs/misbehaviour.rs +++ b/crates/relayer-types/src/core/ics02_client/msgs/misbehaviour.rs @@ -1,6 +1,6 @@ use ibc_proto::google::protobuf::Any as ProtoAny; use ibc_proto::ibc::core::client::v1::MsgSubmitMisbehaviour as RawMsgSubmitMisbehaviour; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use crate::core::ics02_client::error::Error; use crate::core::ics24_host::identifier::ClientId; @@ -38,27 +38,25 @@ impl Protobuf for MsgSubmitMisbehaviour {} impl TryFrom for MsgSubmitMisbehaviour { type Error = Error; - // NOTE: The `MsgSubmitMisbehaviour` message is has been deprecated in IBC-Go v7 in favor of a + // NOTE: The `MsgSubmitMisbehaviour` message has been deprecated in IBC-Go v7 in favor of a // regular `MsgUpdateClient`, but will keep working for the foreseeable future. #[allow(deprecated)] fn try_from(raw: RawMsgSubmitMisbehaviour) -> Result { - let raw_misbehaviour = raw - .misbehaviour - .ok_or_else(Error::missing_raw_misbehaviour)?; - Ok(MsgSubmitMisbehaviour { client_id: raw .client_id .parse() .map_err(Error::invalid_raw_misbehaviour)?, - misbehaviour: raw_misbehaviour, + misbehaviour: raw + .misbehaviour + .ok_or_else(Error::missing_raw_misbehaviour)?, signer: raw.signer.parse().map_err(Error::signer)?, }) } } impl From for RawMsgSubmitMisbehaviour { - // NOTE: The `MsgSubmitMisbehaviour` message is has been deprecated in IBC-Go v7 in favor of a + // NOTE: The `MsgSubmitMisbehaviour` message has been deprecated in IBC-Go v7 in favor of a // regular `MsgUpdateClient`, but will keep working for the foreseeable future. #[allow(deprecated)] fn from(ics_msg: MsgSubmitMisbehaviour) -> Self { diff --git a/crates/relayer-types/src/core/ics02_client/msgs/update_client.rs b/crates/relayer-types/src/core/ics02_client/msgs/update_client.rs index 5ab3fef364..e5966b7b7c 100644 --- a/crates/relayer-types/src/core/ics02_client/msgs/update_client.rs +++ b/crates/relayer-types/src/core/ics02_client/msgs/update_client.rs @@ -2,7 +2,7 @@ use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::core::client::v1::MsgUpdateClient as RawMsgUpdateClient; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use crate::core::ics02_client::error::Error; use crate::core::ics24_host::error::ValidationError; diff --git a/crates/relayer-types/src/core/ics02_client/msgs/upgrade_client.rs b/crates/relayer-types/src/core/ics02_client/msgs/upgrade_client.rs index 63cd606a41..20fcf6ccc3 100644 --- a/crates/relayer-types/src/core/ics02_client/msgs/upgrade_client.rs +++ b/crates/relayer-types/src/core/ics02_client/msgs/upgrade_client.rs @@ -5,7 +5,7 @@ use std::str::FromStr; use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::core::client::v1::MsgUpgradeClient as RawMsgUpgradeClient; use ibc_proto::ibc::core::commitment::v1::MerkleProof as RawMerkleProof; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use crate::core::ics02_client::error::Error; use crate::core::ics23_commitment::commitment::CommitmentProofBytes; diff --git a/crates/relayer-types/src/core/ics02_client/trust_threshold.rs b/crates/relayer-types/src/core/ics02_client/trust_threshold.rs index 73444f4651..b2183c6f98 100644 --- a/crates/relayer-types/src/core/ics02_client/trust_threshold.rs +++ b/crates/relayer-types/src/core/ics02_client/trust_threshold.rs @@ -5,7 +5,7 @@ use std::convert::TryFrom; use std::fmt::{Display, Error as FmtError, Formatter}; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use num_rational::Ratio; use serde::{Deserialize, Serialize}; diff --git a/crates/relayer-types/src/core/ics03_connection/connection.rs b/crates/relayer-types/src/core/ics03_connection/connection.rs index a73a692949..d240eaf905 100644 --- a/crates/relayer-types/src/core/ics03_connection/connection.rs +++ b/crates/relayer-types/src/core/ics03_connection/connection.rs @@ -5,7 +5,7 @@ use std::{ u64, }; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use serde::{Deserialize, Serialize}; use ibc_proto::ibc::core::connection::v1::{ @@ -241,9 +241,9 @@ impl ConnectionEnd { #[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct Counterparty { - client_id: ClientId, + pub client_id: ClientId, pub connection_id: Option, - prefix: CommitmentPrefix, + pub prefix: CommitmentPrefix, } impl Protobuf for Counterparty {} diff --git a/crates/relayer-types/src/core/ics03_connection/msgs/conn_open_ack.rs b/crates/relayer-types/src/core/ics03_connection/msgs/conn_open_ack.rs index 72798ecc2a..ff8f03028b 100644 --- a/crates/relayer-types/src/core/ics03_connection/msgs/conn_open_ack.rs +++ b/crates/relayer-types/src/core/ics03_connection/msgs/conn_open_ack.rs @@ -1,6 +1,6 @@ use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::core::connection::v1::MsgConnectionOpenAck as RawMsgConnectionOpenAck; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use crate::core::ics03_connection::error::Error; use crate::core::ics03_connection::version::Version; diff --git a/crates/relayer-types/src/core/ics03_connection/msgs/conn_open_confirm.rs b/crates/relayer-types/src/core/ics03_connection/msgs/conn_open_confirm.rs index ae20b9bd5f..c7b86b4b43 100644 --- a/crates/relayer-types/src/core/ics03_connection/msgs/conn_open_confirm.rs +++ b/crates/relayer-types/src/core/ics03_connection/msgs/conn_open_confirm.rs @@ -1,4 +1,4 @@ -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use ibc_proto::ibc::core::connection::v1::MsgConnectionOpenConfirm as RawMsgConnectionOpenConfirm; diff --git a/crates/relayer-types/src/core/ics03_connection/msgs/conn_open_init.rs b/crates/relayer-types/src/core/ics03_connection/msgs/conn_open_init.rs index 0e1cb7fe3c..4bdc6db6c2 100644 --- a/crates/relayer-types/src/core/ics03_connection/msgs/conn_open_init.rs +++ b/crates/relayer-types/src/core/ics03_connection/msgs/conn_open_init.rs @@ -1,7 +1,7 @@ use std::time::Duration; use ibc_proto::ibc::core::connection::v1::MsgConnectionOpenInit as RawMsgConnectionOpenInit; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use crate::core::ics03_connection::connection::Counterparty; use crate::core::ics03_connection::error::Error; diff --git a/crates/relayer-types/src/core/ics03_connection/msgs/conn_open_try.rs b/crates/relayer-types/src/core/ics03_connection/msgs/conn_open_try.rs index 2915ff87bd..8cebee431b 100644 --- a/crates/relayer-types/src/core/ics03_connection/msgs/conn_open_try.rs +++ b/crates/relayer-types/src/core/ics03_connection/msgs/conn_open_try.rs @@ -6,7 +6,7 @@ use std::{ use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::core::connection::v1::MsgConnectionOpenTry as RawMsgConnectionOpenTry; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use crate::core::ics03_connection::connection::Counterparty; use crate::core::ics03_connection::error::Error; diff --git a/crates/relayer-types/src/core/ics03_connection/version.rs b/crates/relayer-types/src/core/ics03_connection/version.rs index 5e747575d2..a796ff3c05 100644 --- a/crates/relayer-types/src/core/ics03_connection/version.rs +++ b/crates/relayer-types/src/core/ics03_connection/version.rs @@ -3,7 +3,7 @@ use std::fmt::Display; use crate::utils::pretty::PrettySlice; use ibc_proto::ibc::core::connection::v1::Version as RawVersion; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use serde::{Deserialize, Serialize}; use crate::core::ics03_connection::error::Error; diff --git a/crates/relayer-types/src/core/ics04_channel/channel.rs b/crates/relayer-types/src/core/ics04_channel/channel.rs index dc57f69893..0205e2998a 100644 --- a/crates/relayer-types/src/core/ics04_channel/channel.rs +++ b/crates/relayer-types/src/core/ics04_channel/channel.rs @@ -3,7 +3,7 @@ use crate::utils::pretty::PrettySlice; use std::fmt::{Display, Error as FmtError, Formatter}; use std::str::FromStr; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use serde::{Deserialize, Serialize}; use ibc_proto::ibc::core::channel::v1::{ diff --git a/crates/relayer-types/src/core/ics04_channel/error.rs b/crates/relayer-types/src/core/ics04_channel/error.rs index ce07b27fca..1f0f04de6c 100644 --- a/crates/relayer-types/src/core/ics04_channel/error.rs +++ b/crates/relayer-types/src/core/ics04_channel/error.rs @@ -12,7 +12,7 @@ use crate::timestamp::Timestamp; use crate::Height; use flex_error::{define_error, TraceError}; -use ibc_proto::protobuf::Error as TendermintError; +use tendermint_proto::Error as TendermintError; define_error! { #[derive(Debug, PartialEq, Eq)] diff --git a/crates/relayer-types/src/core/ics04_channel/msgs/acknowledgement.rs b/crates/relayer-types/src/core/ics04_channel/msgs/acknowledgement.rs index 3bb054f8cb..421342837d 100644 --- a/crates/relayer-types/src/core/ics04_channel/msgs/acknowledgement.rs +++ b/crates/relayer-types/src/core/ics04_channel/msgs/acknowledgement.rs @@ -1,6 +1,6 @@ use derive_more::{From, Into}; use ibc_proto::ibc::core::channel::v1::MsgAcknowledgement as RawMsgAcknowledgement; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use crate::core::ics04_channel::error::Error; use crate::core::ics04_channel::packet::Packet; diff --git a/crates/relayer-types/src/core/ics04_channel/msgs/chan_close_confirm.rs b/crates/relayer-types/src/core/ics04_channel/msgs/chan_close_confirm.rs index 9102a104a5..e29872320d 100644 --- a/crates/relayer-types/src/core/ics04_channel/msgs/chan_close_confirm.rs +++ b/crates/relayer-types/src/core/ics04_channel/msgs/chan_close_confirm.rs @@ -1,4 +1,4 @@ -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use ibc_proto::ibc::core::channel::v1::MsgChannelCloseConfirm as RawMsgChannelCloseConfirm; diff --git a/crates/relayer-types/src/core/ics04_channel/msgs/chan_close_init.rs b/crates/relayer-types/src/core/ics04_channel/msgs/chan_close_init.rs index 49f5208795..9e249d6137 100644 --- a/crates/relayer-types/src/core/ics04_channel/msgs/chan_close_init.rs +++ b/crates/relayer-types/src/core/ics04_channel/msgs/chan_close_init.rs @@ -1,4 +1,4 @@ -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use ibc_proto::ibc::core::channel::v1::MsgChannelCloseInit as RawMsgChannelCloseInit; diff --git a/crates/relayer-types/src/core/ics04_channel/msgs/chan_open_ack.rs b/crates/relayer-types/src/core/ics04_channel/msgs/chan_open_ack.rs index 7409775097..895ff7d204 100644 --- a/crates/relayer-types/src/core/ics04_channel/msgs/chan_open_ack.rs +++ b/crates/relayer-types/src/core/ics04_channel/msgs/chan_open_ack.rs @@ -7,7 +7,7 @@ use crate::signer::Signer; use crate::tx_msg::Msg; use ibc_proto::ibc::core::channel::v1::MsgChannelOpenAck as RawMsgChannelOpenAck; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; pub const TYPE_URL: &str = "/ibc.core.channel.v1.MsgChannelOpenAck"; diff --git a/crates/relayer-types/src/core/ics04_channel/msgs/chan_open_confirm.rs b/crates/relayer-types/src/core/ics04_channel/msgs/chan_open_confirm.rs index 6a29096945..627f320698 100644 --- a/crates/relayer-types/src/core/ics04_channel/msgs/chan_open_confirm.rs +++ b/crates/relayer-types/src/core/ics04_channel/msgs/chan_open_confirm.rs @@ -6,7 +6,7 @@ use crate::signer::Signer; use crate::tx_msg::Msg; use ibc_proto::ibc::core::channel::v1::MsgChannelOpenConfirm as RawMsgChannelOpenConfirm; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; pub const TYPE_URL: &str = "/ibc.core.channel.v1.MsgChannelOpenConfirm"; diff --git a/crates/relayer-types/src/core/ics04_channel/msgs/chan_open_init.rs b/crates/relayer-types/src/core/ics04_channel/msgs/chan_open_init.rs index 4b1920e72e..8128674f24 100644 --- a/crates/relayer-types/src/core/ics04_channel/msgs/chan_open_init.rs +++ b/crates/relayer-types/src/core/ics04_channel/msgs/chan_open_init.rs @@ -6,7 +6,7 @@ use crate::signer::Signer; use crate::tx_msg::Msg; use ibc_proto::ibc::core::channel::v1::MsgChannelOpenInit as RawMsgChannelOpenInit; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; pub const TYPE_URL: &str = "/ibc.core.channel.v1.MsgChannelOpenInit"; diff --git a/crates/relayer-types/src/core/ics04_channel/msgs/chan_open_try.rs b/crates/relayer-types/src/core/ics04_channel/msgs/chan_open_try.rs index c9b65c6772..597204e5ec 100644 --- a/crates/relayer-types/src/core/ics04_channel/msgs/chan_open_try.rs +++ b/crates/relayer-types/src/core/ics04_channel/msgs/chan_open_try.rs @@ -9,7 +9,7 @@ use crate::signer::Signer; use crate::tx_msg::Msg; use ibc_proto::ibc::core::channel::v1::MsgChannelOpenTry as RawMsgChannelOpenTry; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use core::str::FromStr; diff --git a/crates/relayer-types/src/core/ics04_channel/msgs/recv_packet.rs b/crates/relayer-types/src/core/ics04_channel/msgs/recv_packet.rs index 24d0b587ee..6d3472c4ef 100644 --- a/crates/relayer-types/src/core/ics04_channel/msgs/recv_packet.rs +++ b/crates/relayer-types/src/core/ics04_channel/msgs/recv_packet.rs @@ -1,4 +1,4 @@ -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use ibc_proto::ibc::core::channel::v1::MsgRecvPacket as RawMsgRecvPacket; diff --git a/crates/relayer-types/src/core/ics04_channel/msgs/timeout.rs b/crates/relayer-types/src/core/ics04_channel/msgs/timeout.rs index 0c8f2cc620..7407bb9908 100644 --- a/crates/relayer-types/src/core/ics04_channel/msgs/timeout.rs +++ b/crates/relayer-types/src/core/ics04_channel/msgs/timeout.rs @@ -1,4 +1,4 @@ -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use ibc_proto::ibc::core::channel::v1::MsgTimeout as RawMsgTimeout; diff --git a/crates/relayer-types/src/core/ics04_channel/msgs/timeout_on_close.rs b/crates/relayer-types/src/core/ics04_channel/msgs/timeout_on_close.rs index e4d39f956a..8d6fc5e970 100644 --- a/crates/relayer-types/src/core/ics04_channel/msgs/timeout_on_close.rs +++ b/crates/relayer-types/src/core/ics04_channel/msgs/timeout_on_close.rs @@ -1,5 +1,5 @@ use ibc_proto::ibc::core::channel::v1::MsgTimeoutOnClose as RawMsgTimeoutOnClose; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use crate::core::ics04_channel::error::Error; use crate::core::ics04_channel::packet::{Packet, Sequence}; diff --git a/crates/relayer-types/src/core/ics26_routing/error.rs b/crates/relayer-types/src/core/ics26_routing/error.rs index 5687860cf4..f51581b6e0 100644 --- a/crates/relayer-types/src/core/ics26_routing/error.rs +++ b/crates/relayer-types/src/core/ics26_routing/error.rs @@ -29,7 +29,7 @@ define_error! { | e | { format_args!("unknown type URL {0}", e.url) }, MalformedMessageBytes - [ TraceError ] + [ TraceError ] | _ | { "the message is malformed and cannot be decoded" }, } } diff --git a/crates/relayer-types/src/core/ics26_routing/msgs.rs b/crates/relayer-types/src/core/ics26_routing/msgs.rs index c6c7d72bda..68864ce23e 100644 --- a/crates/relayer-types/src/core/ics26_routing/msgs.rs +++ b/crates/relayer-types/src/core/ics26_routing/msgs.rs @@ -9,7 +9,7 @@ use crate::core::ics04_channel::msgs::{ chan_open_init, chan_open_try, recv_packet, timeout, timeout_on_close, ChannelMsg, PacketMsg, }; use crate::core::ics26_routing::error::Error; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; /// Enumeration of all messages that the local ICS26 module is capable of routing. #[derive(Clone, Debug)] diff --git a/crates/relayer-types/src/dynamic_typing.rs b/crates/relayer-types/src/dynamic_typing.rs deleted file mode 100644 index 7385b04ff5..0000000000 --- a/crates/relayer-types/src/dynamic_typing.rs +++ /dev/null @@ -1,11 +0,0 @@ -use std::any::Any; - -pub trait AsAny: Any { - fn as_any(&self) -> &dyn Any; -} - -impl AsAny for M { - fn as_any(&self) -> &dyn Any { - self - } -} diff --git a/crates/relayer-types/src/lib.rs b/crates/relayer-types/src/lib.rs index 33ef64cdf3..7684e0b41a 100644 --- a/crates/relayer-types/src/lib.rs +++ b/crates/relayer-types/src/lib.rs @@ -47,13 +47,11 @@ pub mod applications; pub mod bigint; pub mod clients; pub mod core; -pub mod dynamic_typing; pub mod events; pub mod handler; pub mod keys; pub mod macros; pub mod proofs; -pub mod relayer; pub mod signer; pub mod timestamp; pub mod tx_msg; diff --git a/crates/relayer-types/src/mock/client_state.rs b/crates/relayer-types/src/mock/client_state.rs index 320d15aafb..a9cc487dc4 100644 --- a/crates/relayer-types/src/mock/client_state.rs +++ b/crates/relayer-types/src/mock/client_state.rs @@ -1,15 +1,13 @@ -use std::collections::HashMap; use std::time::Duration; use serde::{Deserialize, Serialize}; use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::mock::ClientState as RawMockClientState; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; -use crate::core::ics02_client::client_state::{ClientState, UpgradeOptions}; +use crate::core::ics02_client::client_state::ClientState; use crate::core::ics02_client::client_type::ClientType; -use crate::core::ics02_client::consensus_state::ConsensusState; use crate::core::ics02_client::error::Error; use crate::core::ics24_host::identifier::ChainId; @@ -21,20 +19,6 @@ use crate::Height; pub const MOCK_CLIENT_STATE_TYPE_URL: &str = "/ibc.mock.ClientState"; -/// A mock of an IBC client record as it is stored in a mock context. -/// For testing ICS02 handlers mostly, cf. `MockClientContext`. -#[derive(Clone, Debug)] -pub struct MockClientRecord { - /// The type of this client. - pub client_type: ClientType, - - /// The client state (representing only the latest height at the moment). - pub client_state: Option>, - - /// Mapping of heights to consensus states for this client. - pub consensus_states: HashMap>, -} - /// A mock of a client state. For an example of a real structure that this mocks, you can see /// `ClientState` of ics07_tendermint/client_state.rs. #[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] @@ -101,7 +85,10 @@ impl TryFrom for MockClientState { MOCK_CLIENT_STATE_TYPE_URL => { decode_client_state(raw.value.deref()).map_err(Into::into) } - _ => Err(Error::unknown_client_state_type(raw.type_url)), + _ => Err(Error::unexpected_client_state_type( + MOCK_CLIENT_STATE_TYPE_URL.to_string(), + raw.type_url, + )), } } } @@ -110,12 +97,14 @@ impl From for Any { fn from(client_state: MockClientState) -> Self { Any { type_url: MOCK_CLIENT_STATE_TYPE_URL.to_string(), - value: Protobuf::::encode_vec(&client_state), + value: Protobuf::::encode_vec(client_state), } } } impl ClientState for MockClientState { + type UpgradeOptions = (); + fn chain_id(&self) -> ChainId { unimplemented!() } @@ -132,12 +121,7 @@ impl ClientState for MockClientState { self.frozen_height } - fn upgrade( - &mut self, - _upgrade_height: Height, - _upgrade_options: &dyn UpgradeOptions, - _chain_id: ChainId, - ) { + fn upgrade(&mut self, _upgrade_height: Height, _upgrade_options: (), _chain_id: ChainId) { unimplemented!() } diff --git a/crates/relayer-types/src/mock/consensus_state.rs b/crates/relayer-types/src/mock/consensus_state.rs index 5ee4ab94f6..0237d50074 100644 --- a/crates/relayer-types/src/mock/consensus_state.rs +++ b/crates/relayer-types/src/mock/consensus_state.rs @@ -1,6 +1,6 @@ use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::mock::ConsensusState as RawMockConsensusState; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use serde::{Deserialize, Serialize}; use crate::core::ics02_client::client_type::ClientType; @@ -86,7 +86,7 @@ impl From for Any { fn from(consensus_state: MockConsensusState) -> Self { Any { type_url: MOCK_CONSENSUS_STATE_TYPE_URL.to_string(), - value: Protobuf::::encode_vec(&consensus_state), + value: Protobuf::::encode_vec(consensus_state), } } } diff --git a/crates/relayer-types/src/mock/header.rs b/crates/relayer-types/src/mock/header.rs index a3e4189621..2f5c931201 100644 --- a/crates/relayer-types/src/mock/header.rs +++ b/crates/relayer-types/src/mock/header.rs @@ -2,7 +2,7 @@ use std::fmt::{Display, Error as FmtError, Formatter}; use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::mock::Header as RawMockHeader; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use serde_derive::{Deserialize, Serialize}; use crate::core::ics02_client::client_type::ClientType; @@ -114,7 +114,7 @@ impl From for Any { fn from(header: MockHeader) -> Self { Any { type_url: MOCK_HEADER_TYPE_URL.to_string(), - value: Protobuf::::encode_vec(&header), + value: Protobuf::::encode_vec(header), } } } @@ -122,12 +122,12 @@ impl From for Any { #[cfg(test)] mod tests { use super::*; - use ibc_proto::protobuf::Protobuf; + use ibc_proto::Protobuf; #[test] fn encode_any() { let header = MockHeader::new(Height::new(1, 10).unwrap()).with_timestamp(Timestamp::none()); - let bytes = >::encode_vec(&header); + let bytes = >::encode_vec(header); assert_eq!( &bytes, diff --git a/crates/relayer-types/src/mock/host.rs b/crates/relayer-types/src/mock/host.rs deleted file mode 100644 index 631af7499e..0000000000 --- a/crates/relayer-types/src/mock/host.rs +++ /dev/null @@ -1,192 +0,0 @@ -//! Host chain types and methods, used by context mock. - -use ibc_proto::google::protobuf::Any; -use ibc_proto::ibc::lightclients::tendermint::v1::Header as RawHeader; -use ibc_proto::protobuf::Protobuf as ErasedProtobuf; -use serde::Serialize; -use tendermint::block::Header as TmHeader; -use tendermint_testgen::light_block::TmLightBlock; -use tendermint_testgen::{Generator, LightBlock as TestgenLightBlock}; - -use crate::clients::ics07_tendermint::consensus_state::ConsensusState as TMConsensusState; -use crate::clients::ics07_tendermint::header::TENDERMINT_HEADER_TYPE_URL; -use crate::core::ics02_client::client_type::ClientType; -use crate::core::ics02_client::consensus_state::ConsensusState; -use crate::core::ics02_client::error::Error; -use crate::core::ics02_client::header::Header; -use crate::core::ics24_host::identifier::ChainId; -use crate::mock::consensus_state::MockConsensusState; -use crate::mock::header::MockHeader; - -use crate::timestamp::Timestamp; -use crate::Height; - -/// Defines the different types of host chains that a mock context can emulate. -/// The variants are as follows: -/// - `Mock` defines that the context history consists of `MockHeader` blocks. -/// - `SyntheticTendermint`: the context has synthetically-generated Tendermint (light) blocks. -/// See also the `HostBlock` enum to get more insights into the underlying block type. -#[derive(Clone, Debug, Copy)] -pub enum HostType { - Mock, - SyntheticTendermint, -} - -#[derive(Clone, Debug, PartialEq, Eq, Serialize)] -pub struct SyntheticTmBlock { - pub trusted_height: Height, - pub light_block: TmLightBlock, -} - -impl SyntheticTmBlock { - pub fn header(&self) -> &TmHeader { - &self.light_block.signed_header.header - } -} - -/// Depending on `HostType` (the type of host chain underlying a context mock), this enum defines -/// the type of blocks composing the history of the host chain. -#[derive(Clone, Debug, PartialEq, Eq, Serialize)] -pub enum HostBlock { - Mock(MockHeader), - SyntheticTendermint(SyntheticTmBlock), -} - -impl HostBlock { - /// Returns the height of a block. - pub fn height(&self) -> Height { - match self { - HostBlock::Mock(header) => header.height(), - HostBlock::SyntheticTendermint(light_block) => Height::new( - ChainId::chain_version(light_block.header().chain_id.as_str()), - light_block.header().height.value(), - ) - .unwrap(), - } - } - - pub fn set_trusted_height(&mut self, height: Height) { - match self { - HostBlock::Mock(_) => {} - HostBlock::SyntheticTendermint(light_block) => light_block.trusted_height = height, - } - } - - /// Returns the timestamp of a block. - pub fn timestamp(&self) -> Timestamp { - match self { - HostBlock::Mock(header) => header.timestamp, - HostBlock::SyntheticTendermint(light_block) => light_block.header().time.into(), - } - } - - /// Generates a new block at `height` for the given chain identifier and chain type. - pub fn generate_block( - chain_id: ChainId, - chain_type: HostType, - height: u64, - timestamp: Timestamp, - ) -> HostBlock { - match chain_type { - HostType::Mock => HostBlock::Mock(MockHeader { - height: Height::new(chain_id.version(), height).unwrap(), - timestamp, - }), - HostType::SyntheticTendermint => { - HostBlock::SyntheticTendermint(Self::generate_tm_block(chain_id, height, timestamp)) - } - } - } - - pub fn generate_tm_block( - chain_id: ChainId, - height: u64, - timestamp: Timestamp, - ) -> SyntheticTmBlock { - let light_block = TestgenLightBlock::new_default_with_time_and_chain_id( - chain_id.to_string(), - timestamp.into_tm_time().unwrap(), - height, - ) - .generate() - .unwrap(); - SyntheticTmBlock { - trusted_height: Height::new(chain_id.version(), 1).unwrap(), - light_block, - } - } -} - -impl From for Box { - fn from(light_block: SyntheticTmBlock) -> Self { - let cs = TMConsensusState::from(light_block.header().clone()); - cs.into_box() - } -} - -impl From for Box { - fn from(any_block: HostBlock) -> Self { - match any_block { - HostBlock::Mock(mock_header) => MockConsensusState::new(mock_header).into_box(), - HostBlock::SyntheticTendermint(light_block) => { - TMConsensusState::from(light_block.header().clone()).into_box() - } - } - } -} - -impl ErasedProtobuf for HostBlock {} - -impl TryFrom for HostBlock { - type Error = Error; - - fn try_from(_raw: Any) -> Result { - todo!() - } -} - -impl From for Any { - fn from(value: HostBlock) -> Self { - fn encode_light_block(light_block: SyntheticTmBlock) -> Vec { - use prost::Message; - - let SyntheticTmBlock { - trusted_height, - light_block, - } = light_block; - - RawHeader { - signed_header: Some(light_block.signed_header.into()), - validator_set: Some(light_block.validators.into()), - trusted_height: Some(trusted_height.into()), - trusted_validators: Some(light_block.next_validators.into()), - } - .encode_to_vec() - } - - match value { - HostBlock::Mock(mock_header) => mock_header.into(), - HostBlock::SyntheticTendermint(light_block_box) => Self { - type_url: TENDERMINT_HEADER_TYPE_URL.to_string(), - value: encode_light_block(light_block_box), - }, - } - } -} - -impl Header for HostBlock { - fn client_type(&self) -> ClientType { - match self { - HostBlock::Mock(_) => ClientType::Mock, - HostBlock::SyntheticTendermint(_) => ClientType::Tendermint, - } - } - - fn height(&self) -> Height { - HostBlock::height(self) - } - - fn timestamp(&self) -> Timestamp { - HostBlock::timestamp(self) - } -} diff --git a/crates/relayer-types/src/mock/misbehaviour.rs b/crates/relayer-types/src/mock/misbehaviour.rs index 418c187251..17e303940c 100644 --- a/crates/relayer-types/src/mock/misbehaviour.rs +++ b/crates/relayer-types/src/mock/misbehaviour.rs @@ -1,5 +1,5 @@ use ibc_proto::ibc::mock::Misbehaviour as RawMisbehaviour; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use serde::{Deserialize, Serialize}; use crate::core::ics02_client::error::Error; diff --git a/crates/relayer-types/src/mock/mod.rs b/crates/relayer-types/src/mock/mod.rs index 5c1cc333e0..340dacdaef 100644 --- a/crates/relayer-types/src/mock/mod.rs +++ b/crates/relayer-types/src/mock/mod.rs @@ -3,5 +3,4 @@ pub mod client_state; pub mod consensus_state; pub mod header; -pub mod host; pub mod misbehaviour; diff --git a/crates/relayer-types/src/relayer/ics18_relayer/context.rs b/crates/relayer-types/src/relayer/ics18_relayer/context.rs deleted file mode 100644 index c7a505914d..0000000000 --- a/crates/relayer-types/src/relayer/ics18_relayer/context.rs +++ /dev/null @@ -1,34 +0,0 @@ -use ibc_proto::google::protobuf::Any; - -use crate::core::ics02_client::client_state::ClientState; -use crate::core::ics02_client::header::Header; -use crate::events::IbcEvent; - -use crate::core::ics24_host::identifier::ClientId; -use crate::relayer::ics18_relayer::error::Error; -use crate::signer::Signer; -use crate::Height; - -/// Trait capturing all dependencies (i.e., the context) which algorithms in ICS18 require to -/// relay packets between chains. This trait comprises the dependencies towards a single chain. -/// Most of the functions in this represent wrappers over the ABCI interface. -/// This trait mimics the `Chain` trait, but at a lower level of abstraction (no networking, header -/// types, light client, RPC client, etc.) -pub trait Ics18Context { - /// Returns the latest height of the chain. - fn query_latest_height(&self) -> Height; - - /// Returns this client state for the given `client_id` on this chain. - /// Wrapper over the `/abci_query?path=..` endpoint. - fn query_client_full_state(&self, client_id: &ClientId) -> Option>; - - /// Returns the most advanced header of this chain. - fn query_latest_header(&self) -> Option>; - - /// Interface that the relayer uses to submit a datagram to this chain. - /// One can think of this as wrapping around the `/broadcast_tx_commit` ABCI endpoint. - fn send(&mut self, msgs: Vec) -> Result, Error>; - - /// Temporary solution. Similar to `CosmosSDKChain::key_and_signer()` but simpler. - fn signer(&self) -> Signer; -} diff --git a/crates/relayer-types/src/relayer/ics18_relayer/error.rs b/crates/relayer-types/src/relayer/ics18_relayer/error.rs deleted file mode 100644 index e975de5a3a..0000000000 --- a/crates/relayer-types/src/relayer/ics18_relayer/error.rs +++ /dev/null @@ -1,38 +0,0 @@ -use crate::core::ics24_host::identifier::ClientId; -use crate::core::ics26_routing::error::Error as RoutingError; -use crate::Height; -use flex_error::define_error; - -define_error! { - Error { - ClientStateNotFound - { client_id: ClientId } - | e | { format_args!("client state on destination chain not found, (client id: {0})", e.client_id) }, - - ClientAlreadyUpToDate - { - client_id: ClientId, - source_height: Height, - destination_height: Height, - } - | e | { - format_args!("the client on destination chain is already up-to-date (client id: {0}, source height: {1}, dest height: {2})", - e.client_id, e.source_height, e.destination_height) - }, - - ClientAtHigherHeight - { - client_id: ClientId, - source_height: Height, - destination_height: Height, - } - | e | { - format_args!("the client on destination chain is at a higher height (client id: {0}, source height: {1}, dest height: {2})", - e.client_id, e.source_height, e.destination_height) - }, - - TransactionFailed - [ RoutingError ] - | _ | { "transaction processing by modules failed" }, - } -} diff --git a/crates/relayer-types/src/relayer/ics18_relayer/mod.rs b/crates/relayer-types/src/relayer/ics18_relayer/mod.rs deleted file mode 100644 index 8a7f14e5b6..0000000000 --- a/crates/relayer-types/src/relayer/ics18_relayer/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -//! ICS 18: Relayer contains utilities for testing `ibc` against the Hermes relayer. - -pub mod context; -pub mod error; diff --git a/crates/relayer-types/src/relayer/mod.rs b/crates/relayer-types/src/relayer/mod.rs deleted file mode 100644 index 3749606559..0000000000 --- a/crates/relayer-types/src/relayer/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Utilities for testing the `ibc` crate against the [Hermes IBC relayer][relayer-repo]. -//! -//! [relayer-repo]: https://github.com/informalsystems/hermes/tree/master/crates/relayer - -pub mod ics18_relayer; diff --git a/crates/relayer/Cargo.toml b/crates/relayer/Cargo.toml index bed5adf649..a6132b4291 100644 --- a/crates/relayer/Cargo.toml +++ b/crates/relayer/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ibc-relayer" -version = "0.25.0" +version = "0.26.0" edition = "2021" license = "Apache-2.0" readme = "README.md" @@ -20,9 +20,9 @@ default = ["flex-error/std", "flex-error/eyre_tracer"] telemetry = ["ibc-telemetry"] [dependencies] -ibc-proto = { version = "0.37.0", features = ["serde"] } -ibc-telemetry = { version = "0.25.0", path = "../telemetry", optional = true } -ibc-relayer-types = { version = "0.25.0", path = "../relayer-types", features = ["mocks"] } +ibc-proto = { version = "0.38.0", features = ["serde"] } +ibc-telemetry = { version = "0.26.0", path = "../telemetry", optional = true } +ibc-relayer-types = { version = "0.26.0", path = "../relayer-types", features = ["mocks"] } subtle-encoding = "0.5" humantime-serde = "1.1.1" @@ -57,7 +57,7 @@ anyhow = "1.0" semver = "1.0" humantime = "2.1.0" regex = "1" -moka = "0.11.3" +moka = { version = "0.12.0", features = ["sync"] } uuid = { version = "1.4.0", features = ["v4"] } bs58 = "0.5.0" digest = "0.10.6" @@ -69,6 +69,7 @@ secp256k1 = { version = "0.27.0", features = ["rand-std"] } strum = { version = "0.25", features = ["derive"] } tokio-stream = "0.1.14" once_cell = "1.17.1" +tracing-subscriber = { version = "0.3.14", features = ["fmt", "env-filter", "json"] } [dependencies.byte-unit] version = "4.0.19" @@ -87,6 +88,9 @@ features = ["num-bigint", "serde"] version = "0.34.0" features = ["secp256k1"] +[dependencies.tendermint-proto] +version = "0.34.0" + [dependencies.tendermint-rpc] version = "0.34.0" features = ["http-client", "websocket-client"] @@ -100,11 +104,14 @@ features = ["rpc-client", "secp256k1", "unstable"] version = "0.34.0" default-features = false +[dependencies.tendermint-light-client-verifier] +version = "0.34.0" +default-features = false + [dev-dependencies] -ibc-relayer-types = { version = "0.25.0", path = "../relayer-types", features = ["mocks"] } +ibc-relayer-types = { version = "0.26.0", path = "../relayer-types", features = ["mocks"] } serial_test = "2.0.0" env_logger = "0.10.0" -tracing-subscriber = { version = "0.3.14", features = ["fmt", "env-filter", "json"] } test-log = { version = "0.2.10", features = ["trace"] } # Needed for generating (synthetic) light blocks. diff --git a/crates/relayer/src/chain.rs b/crates/relayer/src/chain.rs index 2adee44155..bcca34e85f 100644 --- a/crates/relayer/src/chain.rs +++ b/crates/relayer/src/chain.rs @@ -6,60 +6,3 @@ pub mod handle; pub mod requests; pub mod runtime; pub mod tracking; - -use serde::{de::Error, Deserialize, Serialize}; - -// NOTE(new): When adding a variant to `ChainType`, make sure to update -// the `Deserialize` implementation below and the tests. -// See the NOTE(new) comments below. - -#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize)] -/// Types of chains the relayer can relay to and from -pub enum ChainType { - /// Chains based on the Cosmos SDK - CosmosSdk, -} - -impl<'de> Deserialize<'de> for ChainType { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - let original = String::deserialize(deserializer)?; - let s = original.to_ascii_lowercase().replace('-', ""); - - match s.as_str() { - "cosmossdk" => Ok(Self::CosmosSdk), - - // NOTE(new): Add a case here - _ => Err(D::Error::unknown_variant(&original, &["cosmos-sdk"])), // NOTE(new): mention the new variant here - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[derive(Copy, Clone, Debug, Serialize, Deserialize)] - pub struct Config { - tpe: ChainType, - } - - fn parse(variant: &str) -> Result { - toml::from_str::(&format!("tpe = '{variant}'")).map(|e| e.tpe) - } - - #[test] - fn deserialize() { - use ChainType::*; - - assert!(matches!(parse("CosmosSdk"), Ok(CosmosSdk))); - assert!(matches!(parse("cosmossdk"), Ok(CosmosSdk))); - assert!(matches!(parse("cosmos-sdk"), Ok(CosmosSdk))); - - // NOTE(new): Add tests here - - assert!(parse("hello-world").is_err()); - } -} diff --git a/crates/relayer/src/chain/client.rs b/crates/relayer/src/chain/client.rs index b791c9d199..6f00ec8df9 100644 --- a/crates/relayer/src/chain/client.rs +++ b/crates/relayer/src/chain/client.rs @@ -24,10 +24,18 @@ impl ClientSettings { // Currently, only Tendermint chain pairs are supported by // ForeignClient::build_create_client_and_send. Support for // heterogeneous chains is left for future revisions. - ClientSettings::Tendermint(cosmos::client::Settings::for_create_command( - options, - src_chain_config, - dst_chain_config, - )) + // + // TODO: extract Tendermint-related configs into a separate substructure + // that can be used both by CosmosSdkConfig and configs for nonSDK chains. + use ChainConfig::CosmosSdk as Csdk; + match (src_chain_config, dst_chain_config) { + (Csdk(src_chain_config), Csdk(dst_chain_config)) => { + ClientSettings::Tendermint(cosmos::client::Settings::for_create_command( + options, + src_chain_config, + dst_chain_config, + )) + } + } } } diff --git a/crates/relayer/src/chain/cosmos.rs b/crates/relayer/src/chain/cosmos.rs index b2f71a1c37..660814bb4f 100644 --- a/crates/relayer/src/chain/cosmos.rs +++ b/crates/relayer/src/chain/cosmos.rs @@ -15,16 +15,13 @@ use tonic::codegen::http::Uri; use tonic::metadata::AsciiMetadataValue; use tracing::{debug, error, info, instrument, trace, warn}; -use ibc_proto::cosmos::{ - base::node::v1beta1::ConfigResponse, staking::v1beta1::Params as StakingParams, -}; - -use ibc_proto::interchain_security::ccv::consumer::v1::Params as CcvConsumerParams; - +use ibc_proto::cosmos::base::node::v1beta1::ConfigResponse; +use ibc_proto::cosmos::staking::v1beta1::Params as StakingParams; use ibc_proto::ibc::apps::fee::v1::{ QueryIncentivizedPacketRequest, QueryIncentivizedPacketResponse, }; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::interchain_security::ccv::v1::ConsumerParams as CcvConsumerParams; +use ibc_proto::Protobuf; use ibc_relayer_types::applications::ics31_icq::response::CrossChainQueryResponse; use ibc_relayer_types::clients::ics07_tendermint::client_state::{ AllowUpdate, ClientState as TmClientState, @@ -64,7 +61,6 @@ use tendermint_rpc::endpoint::status; use tendermint_rpc::{Client, HttpClient, Order}; use crate::account::Balance; -use crate::chain::client::ClientSettings; use crate::chain::cosmos::batch::{ send_batched_messages_and_wait_check_tx, send_batched_messages_and_wait_commit, sequential_send_batched_messages_and_wait_commit, @@ -106,12 +102,14 @@ use crate::misbehaviour::MisbehaviourEvidence; use crate::util::pretty::{ PrettyIdentifiedChannel, PrettyIdentifiedClientState, PrettyIdentifiedConnection, }; +use crate::{chain::client::ClientSettings, config::Error as ConfigError}; use self::types::app_state::GenesisAppState; pub mod batch; pub mod client; pub mod compatibility; +pub mod config; pub mod encode; pub mod estimate; pub mod fee; @@ -140,9 +138,9 @@ pub mod wait; /// [tm-37-max]: https://github.com/tendermint/tendermint/blob/v0.37.0-rc1/types/params.go#L79 pub const BLOCK_MAX_BYTES_MAX_FRACTION: f64 = 0.9; pub struct CosmosSdkChain { - config: ChainConfig, + config: config::CosmosSdkConfig, tx_config: TxConfig, - rpc_client: HttpClient, + pub rpc_client: HttpClient, compat_mode: CompatMode, grpc_addr: Uri, light_client: TmLightClient, @@ -157,7 +155,7 @@ pub struct CosmosSdkChain { impl CosmosSdkChain { /// Get a reference to the configuration for this chain. - pub fn config(&self) -> &ChainConfig { + pub fn config(&self) -> &config::CosmosSdkConfig { &self.config } @@ -568,7 +566,7 @@ impl CosmosSdkChain { prove, ))?; - // TODO - Verify response proof, if requested. + // TODO: Verify response proof, if requested. Ok(response) } @@ -872,19 +870,29 @@ impl ChainEndpoint for CosmosSdkChain { type Time = TmTime; type SigningKeyPair = Secp256k1KeyPair; + fn id(&self) -> &ChainId { + &self.config.id + } + fn bootstrap(config: ChainConfig, rt: Arc) -> Result { + #[allow(irrefutable_let_patterns)] + let ChainConfig::CosmosSdk(config) = config + else { + return Err(Error::config(ConfigError::wrong_type())); + }; + let mut rpc_client = HttpClient::new(config.rpc_addr.clone()) .map_err(|e| Error::rpc(config.rpc_addr.clone(), e))?; let node_info = rt.block_on(fetch_node_info(&rpc_client, &config))?; let compat_mode = CompatMode::from_version(node_info.version).unwrap_or_else(|e| { - warn!("Unsupported tendermint version, will use v0.37 compatibility mode but relaying might not work as desired: {e}"); - CompatMode::V0_37 + warn!("Unsupported tendermint version, will use v0.34 compatibility mode but relaying might not work as desired: {e}"); + CompatMode::V0_34 }); rpc_client.set_compat_mode(compat_mode); - let light_client = TmLightClient::from_config(&config, node_info.id)?; + let light_client = TmLightClient::from_cosmos_sdk_config(&config, node_info.id)?; // Initialize key store and load key let keybase = KeyRing::new_secp256k1( @@ -934,6 +942,16 @@ impl ChainEndpoint for CosmosSdkChain { &mut self.keybase } + fn get_key(&mut self) -> Result { + // Get the key from key seed file + let key_pair = self + .keybase() + .get_key(&self.config.key_name) + .map_err(|e| Error::key_not_found(self.config().key_name.clone(), e))?; + + Ok(key_pair) + } + fn subscribe(&mut self) -> Result { let tx_monitor_cmd = match &self.tx_monitor_cmd { Some(tx_monitor_cmd) => tx_monitor_cmd, @@ -1058,8 +1076,8 @@ impl ChainEndpoint for CosmosSdkChain { } /// Get the chain configuration - fn config(&self) -> &ChainConfig { - &self.config + fn config(&self) -> ChainConfig { + ChainConfig::CosmosSdk(self.config.clone()) } fn ibc_version(&self) -> Result, Error> { @@ -1961,48 +1979,32 @@ impl ChainEndpoint for CosmosSdkChain { ); crate::telemetry!(query, self.id(), "query_next_sequence_receive"); - match include_proof { - IncludeProof::Yes => { - let res = self.query( - SeqRecvsPath(request.port_id, request.channel_id), - request.height, - true, - )?; - - // Note: We expect the return to be a u64 encoded in big-endian. Refer to ibc-go: - // https://github.com/cosmos/ibc-go/blob/25767f6bdb5bab2c2a116b41d92d753c93e18121/modules/core/04-channel/client/utils/utils.go#L191 - if res.value.len() != 8 { - return Err(Error::query("next_sequence_receive".into())); - } - let seq: Sequence = Bytes::from(res.value).get_u64().into(); - - let proof = res.proof.ok_or_else(Error::empty_response_proof)?; + let prove = include_proof.to_bool(); - Ok((seq, Some(proof))) - } - IncludeProof::No => { - let mut client = self - .block_on( - ibc_proto::ibc::core::channel::v1::query_client::QueryClient::connect( - self.grpc_addr.clone(), - ), - ) - .map_err(Error::grpc_transport)?; + let res = self.query( + SeqRecvsPath(request.port_id, request.channel_id), + request.height, + true, + )?; - client = client.max_decoding_message_size( - self.config().max_grpc_decoding_size.get_bytes() as usize, - ); + // Note: We expect the return to be a u64 encoded in big-endian. Refer to ibc-go: + // https://github.com/cosmos/ibc-go/blob/25767f6bdb5bab2c2a116b41d92d753c93e18121/modules/core/04-channel/client/utils/utils.go#L191 + if res.value.len() != 8 { + return Err(Error::query(format!( + "next_sequence_receive: expected a u64 but got {} bytes of data", + res.value.len() + ))); + } - let request = tonic::Request::new(request.into()); + let seq: Sequence = Bytes::from(res.value).get_u64().into(); - let response = self - .block_on(client.next_sequence_receive(request)) - .map_err(|e| Error::grpc_status(e, "query_next_sequence_receive".to_owned()))? - .into_inner(); + let proof = if prove { + Some(res.proof.ok_or_else(Error::empty_response_proof)?) + } else { + None + }; - Ok((Sequence::from(response.next_sequence_receive), None)) - } - } + Ok((seq, proof)) } /// This function queries transactions for events matching certain criteria. @@ -2253,6 +2255,40 @@ impl ChainEndpoint for CosmosSdkChain { self.block_on(query_incentivized_packet(&self.grpc_addr, request))?; Ok(incentivized_response) } + + fn query_consumer_chains(&self) -> Result, Error> { + crate::time!( + "query_consumer_chains", + { + "src_chain": self.config().id.to_string(), + } + ); + crate::telemetry!(query, self.id(), "query_consumer_chains"); + + let mut client = self.block_on( + ibc_proto::interchain_security::ccv::provider::v1::query_client::QueryClient::connect( + self.grpc_addr.clone(), + ), + ) + .map_err(Error::grpc_transport)?; + + let request = tonic::Request::new( + ibc_proto::interchain_security::ccv::provider::v1::QueryConsumerChainsRequest {}, + ); + + let response = self + .block_on(client.query_consumer_chains(request)) + .map_err(|e| Error::grpc_status(e, "query_consumer_chains".to_owned()))? + .into_inner(); + + let result = response + .chains + .into_iter() + .map(|c| (c.chain_id.parse().unwrap(), c.client_id.parse().unwrap())) + .collect(); + + Ok(result) + } } fn sort_events_by_sequence(events: &mut [IbcEventWithHeight]) { @@ -2267,7 +2303,7 @@ fn sort_events_by_sequence(events: &mut [IbcEventWithHeight]) { async fn fetch_node_info( rpc_client: &HttpClient, - config: &ChainConfig, + config: &config::CosmosSdkConfig, ) -> Result { crate::time!("fetch_node_info", { diff --git a/crates/relayer/src/chain/cosmos/batch.rs b/crates/relayer/src/chain/cosmos/batch.rs index 747ccca360..ca82b2d5c7 100644 --- a/crates/relayer/src/chain/cosmos/batch.rs +++ b/crates/relayer/src/chain/cosmos/batch.rs @@ -332,7 +332,11 @@ mod tests { ); let config = config::load(path).expect("could not parse config"); let chain_id = ChainId::from_string("chain_A"); - let chain_config = config.find_chain(&chain_id).unwrap(); + + #[allow(irrefutable_let_patterns)] + let config::ChainConfig::CosmosSdk(chain_config) = config.find_chain(&chain_id).unwrap() else { + panic!("should be a cosmos sdk chain config"); + }; let tx_config = TxConfig::try_from(chain_config).expect("could not obtain tx config"); diff --git a/crates/relayer/src/chain/cosmos/client.rs b/crates/relayer/src/chain/cosmos/client.rs index 9196a93f87..0d3b69cdbc 100644 --- a/crates/relayer/src/chain/cosmos/client.rs +++ b/crates/relayer/src/chain/cosmos/client.rs @@ -6,8 +6,9 @@ use tracing::warn; use ibc_relayer_types::core::ics02_client::trust_threshold::TrustThreshold; -use crate::config::ChainConfig; +use crate::chain::cosmos::config::CosmosSdkConfig; use crate::foreign_client::CreateOptions; + use crate::util::pretty::PrettyDuration; /// Cosmos-specific client parameters for the `build_client_state` operation. @@ -21,8 +22,8 @@ pub struct Settings { impl Settings { pub fn for_create_command( options: CreateOptions, - src_chain_config: &ChainConfig, - dst_chain_config: &ChainConfig, + src_chain_config: &CosmosSdkConfig, + dst_chain_config: &CosmosSdkConfig, ) -> Self { let max_clock_drift = match options.max_clock_drift { None => calculate_client_state_drift(src_chain_config, dst_chain_config), @@ -55,8 +56,8 @@ impl Settings { /// chain block frequency and clock drift on source and dest. /// https://github.com/informalsystems/hermes/issues/1445 fn calculate_client_state_drift( - src_chain_config: &ChainConfig, - dst_chain_config: &ChainConfig, + src_chain_config: &CosmosSdkConfig, + dst_chain_config: &CosmosSdkConfig, ) -> Duration { src_chain_config.clock_drift + dst_chain_config.clock_drift + dst_chain_config.max_block_time } diff --git a/crates/relayer/src/chain/cosmos/config.rs b/crates/relayer/src/chain/cosmos/config.rs new file mode 100644 index 0000000000..81d9b25de0 --- /dev/null +++ b/crates/relayer/src/chain/cosmos/config.rs @@ -0,0 +1,193 @@ +use crate::chain::cosmos::config::error::Error as ConfigError; +use crate::config::default; +use crate::config::gas_multiplier::GasMultiplier; +use crate::config::types::{MaxMsgNum, MaxTxSize, Memo}; +use crate::config::{ + self, AddressType, EventSourceMode, ExtensionOption, GasPrice, GenesisRestart, PacketFilter, +}; +use byte_unit::Byte; +use core::time::Duration; +use ibc_relayer_types::core::ics23_commitment::specs::ProofSpecs; +use ibc_relayer_types::core::ics24_host::identifier::ChainId; +use serde_derive::{Deserialize, Serialize}; +use std::path::PathBuf; +use tendermint_light_client::verifier::types::TrustThreshold; +use tendermint_rpc::Url; + +use crate::keyring::Store; + +pub mod error; + +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +#[serde(deny_unknown_fields)] +pub struct CosmosSdkConfig { + /// The chain's network identifier + pub id: ChainId, + + /// The RPC URL to connect to + pub rpc_addr: Url, + + /// The gRPC URL to connect to + pub grpc_addr: Url, + + /// The type of event source and associated settings + pub event_source: EventSourceMode, + + /// Timeout used when issuing RPC queries + #[serde(default = "default::rpc_timeout", with = "humantime_serde")] + pub rpc_timeout: Duration, + + /// Whether or not the full node Hermes connects to is trusted + #[serde(default = "default::trusted_node")] + pub trusted_node: bool, + + pub account_prefix: String, + 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, + + // This field is only meant to be set via the `update client` command, + // for when we need to ugprade a client across a genesis restart and + // therefore need and archive node to fetch blocks from. + pub genesis_restart: Option, + + // This field is deprecated, use `gas_multiplier` instead + pub gas_adjustment: Option, + pub gas_multiplier: Option, + + pub fee_granter: Option, + #[serde(default)] + pub max_msg_num: MaxMsgNum, + #[serde(default)] + pub max_tx_size: MaxTxSize, + #[serde(default = "default::max_grpc_decoding_size")] + pub max_grpc_decoding_size: Byte, + + /// A correction parameter that helps deal with clocks that are only approximately synchronized + /// between the source and destination chains for a client. + /// This parameter is used when deciding to accept or reject a new header + /// (originating from the source chain) for any client with the destination chain + /// that uses this configuration, unless it is overridden by the client-specific + /// clock drift option. + #[serde(default = "default::clock_drift", with = "humantime_serde")] + pub clock_drift: Duration, + + #[serde(default = "default::max_block_time", with = "humantime_serde")] + pub max_block_time: Duration, + + /// The trusting period specifies how long a validator set is trusted for + /// (must be shorter than the chain's unbonding period). + #[serde(default, with = "humantime_serde")] + pub trusting_period: Option, + + /// CCV consumer chain + #[serde(default = "default::ccv_consumer_chain")] + pub ccv_consumer_chain: bool, + + #[serde(default)] + pub memo_prefix: Memo, + + // This is an undocumented and hidden config to make the relayer wait for + // DeliverTX before sending the next transaction when sending messages in + // multiple batches. We will instruct relayer operators to turn this on + // in case relaying failed in a chain with priority mempool enabled. + // Warning: turning this on may cause degradation in performance. + #[serde(default)] + pub sequential_batch_tx: bool, + + // Note: These last few need to be last otherwise we run into `ValueAfterTable` error when serializing to TOML. + // That's because these are all tables and have to come last when serializing. + #[serde( + default, + skip_serializing_if = "Option::is_none", + with = "config::proof_specs" + )] + pub proof_specs: Option, + + // These last few need to be last otherwise we run into `ValueAfterTable` error when serializing to TOML + /// The trust threshold defines what fraction of the total voting power of a known + /// and trusted validator set is sufficient for a commit to be accepted going forward. + #[serde(default)] + pub trust_threshold: TrustThreshold, + + pub gas_price: GasPrice, + + #[serde(default)] + pub packet_filter: PacketFilter, + + #[serde(default)] + pub address_type: AddressType, + #[serde(default = "Vec::new", skip_serializing_if = "Vec::is_empty")] + pub extension_options: Vec, +} + +impl CosmosSdkConfig { + pub fn validate(&self) -> Result<(), Diagnostic> { + validate_trust_threshold(&self.id, self.trust_threshold)?; + validate_gas_settings(&self.id, self.gas_adjustment)?; + Ok(()) + } +} + +/// Check that the trust threshold is: +/// +/// a) non-zero +/// b) greater or equal to 1/3 +/// c) strictly less than 1 +fn validate_trust_threshold( + id: &ChainId, + trust_threshold: TrustThreshold, +) -> Result<(), Diagnostic> { + if trust_threshold.denominator() == 0 { + return Err(Diagnostic::Error(ConfigError::invalid_trust_threshold( + trust_threshold, + id.clone(), + "trust threshold denominator cannot be zero".to_string(), + ))); + } + + if trust_threshold.numerator() * 3 < trust_threshold.denominator() { + return Err(Diagnostic::Error(ConfigError::invalid_trust_threshold( + trust_threshold, + id.clone(), + "trust threshold cannot be < 1/3".to_string(), + ))); + } + + if trust_threshold.numerator() >= trust_threshold.denominator() { + return Err(Diagnostic::Error(ConfigError::invalid_trust_threshold( + trust_threshold, + id.clone(), + "trust threshold cannot be >= 1".to_string(), + ))); + } + + Ok(()) +} + +fn validate_gas_settings( + id: &ChainId, + gas_adjustment: Option, +) -> Result<(), Diagnostic> { + // Check that the gas_adjustment option is not set + if let Some(gas_adjustment) = gas_adjustment { + let gas_multiplier = gas_adjustment + 1.0; + + return Err(Diagnostic::Error(ConfigError::deprecated_gas_adjustment( + gas_adjustment, + gas_multiplier, + id.clone(), + ))); + } + + Ok(()) +} +#[derive(Clone, Debug)] +pub enum Diagnostic { + Warning(E), + Error(E), +} diff --git a/crates/relayer/src/chain/cosmos/config/error.rs b/crates/relayer/src/chain/cosmos/config/error.rs new file mode 100644 index 0000000000..41ee500266 --- /dev/null +++ b/crates/relayer/src/chain/cosmos/config/error.rs @@ -0,0 +1,34 @@ +use flex_error::define_error; +use ibc_relayer_types::core::ics24_host::identifier::ChainId; +use tendermint_light_client_verifier::types::TrustThreshold; + +define_error! { + + Error { + InvalidTrustThreshold + { + threshold: TrustThreshold, + chain_id: ChainId, + reason: String + } + |e| { + format!("config file specifies an invalid `trust_threshold` ({0}) for the chain '{1}', caused by: {2}", + e.threshold, e.chain_id, e.reason) + }, + +DeprecatedGasAdjustment + { + gas_adjustment: f64, + gas_multiplier: f64, + chain_id: ChainId, + } + |e| { + format!( + "config file specifies deprecated setting `gas_adjustment = {1}` for the chain '{0}'; \ + to get the same behavior, use `gas_multiplier = {2}", + e.chain_id, e.gas_adjustment, e.gas_multiplier + ) + }, + + } +} diff --git a/crates/relayer/src/chain/cosmos/query/account.rs b/crates/relayer/src/chain/cosmos/query/account.rs index 0a424d1693..e24c414ff7 100644 --- a/crates/relayer/src/chain/cosmos/query/account.rs +++ b/crates/relayer/src/chain/cosmos/query/account.rs @@ -39,9 +39,9 @@ pub async fn refresh_account<'a>( let account = query_account(grpc_address, account_address).await?; info!( - sequence = %account.sequence, - number = %account.account_number, - "refresh: retrieved account", + old = %m_account.sequence, + new = %account.sequence, + "refreshed account sequence number", ); *m_account = account.into(); diff --git a/crates/relayer/src/chain/cosmos/types/config.rs b/crates/relayer/src/chain/cosmos/types/config.rs index f5a19cc3c6..a89a0ebb38 100644 --- a/crates/relayer/src/chain/cosmos/types/config.rs +++ b/crates/relayer/src/chain/cosmos/types/config.rs @@ -5,9 +5,10 @@ use ibc_proto::google::protobuf::Any; use ibc_relayer_types::core::ics24_host::identifier::ChainId; use tendermint_rpc::Url; +use crate::chain::cosmos::config::CosmosSdkConfig; use crate::chain::cosmos::types::gas::GasConfig; use crate::config::types::{MaxMsgNum, MaxTxSize}; -use crate::config::{AddressType, ChainConfig}; +use crate::config::AddressType; use crate::error::Error; #[derive(Debug, Clone)] @@ -23,10 +24,10 @@ pub struct TxConfig { pub extension_options: Vec, } -impl<'a> TryFrom<&'a ChainConfig> for TxConfig { +impl<'a> TryFrom<&'a CosmosSdkConfig> for TxConfig { type Error = Error; - fn try_from(config: &'a ChainConfig) -> Result { + fn try_from(config: &'a CosmosSdkConfig) -> Result { let grpc_address = 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/types/gas.rs b/crates/relayer/src/chain/cosmos/types/gas.rs index e0d952796f..80291faaab 100644 --- a/crates/relayer/src/chain/cosmos/types/gas.rs +++ b/crates/relayer/src/chain/cosmos/types/gas.rs @@ -1,7 +1,8 @@ use ibc_proto::cosmos::tx::v1beta1::Fee; use crate::chain::cosmos::calculate_fee; -use crate::config::{ChainConfig, GasPrice}; +use crate::chain::cosmos::config::CosmosSdkConfig; +use crate::config::GasPrice; /// Default gas limit when submitting a transaction. const DEFAULT_MAX_GAS: u64 = 400_000; @@ -18,8 +19,8 @@ pub struct GasConfig { pub fee_granter: String, } -impl<'a> From<&'a ChainConfig> for GasConfig { - fn from(config: &'a ChainConfig) -> Self { +impl<'a> From<&'a CosmosSdkConfig> for GasConfig { + fn from(config: &'a CosmosSdkConfig) -> Self { Self { default_gas: default_gas_from_config(config), max_gas: max_gas_from_config(config), @@ -33,24 +34,24 @@ impl<'a> From<&'a ChainConfig> for GasConfig { /// The default amount of gas the relayer is willing to pay for a transaction, /// when it cannot simulate the tx and therefore estimate the gas amount needed. -pub fn default_gas_from_config(config: &ChainConfig) -> u64 { +pub fn default_gas_from_config(config: &CosmosSdkConfig) -> u64 { config .default_gas .unwrap_or_else(|| max_gas_from_config(config)) } /// The maximum amount of gas the relayer is willing to pay for a transaction -pub fn max_gas_from_config(config: &ChainConfig) -> u64 { +pub fn max_gas_from_config(config: &CosmosSdkConfig) -> u64 { config.max_gas.unwrap_or(DEFAULT_MAX_GAS) } /// The gas multiplier -pub fn gas_multiplier_from_config(config: &ChainConfig) -> f64 { +pub fn gas_multiplier_from_config(config: &CosmosSdkConfig) -> f64 { config.gas_multiplier.unwrap_or_default().to_f64() } /// Get the fee granter address -fn fee_granter_from_config(config: &ChainConfig) -> String { +fn fee_granter_from_config(config: &CosmosSdkConfig) -> String { config .fee_granter .as_deref() @@ -58,7 +59,7 @@ fn fee_granter_from_config(config: &ChainConfig) -> String { .to_string() } -fn max_fee_from_config(config: &ChainConfig) -> Fee { +fn max_fee_from_config(config: &CosmosSdkConfig) -> Fee { let max_gas = max_gas_from_config(config); // The maximum fee the relayer pays for a transaction diff --git a/crates/relayer/src/chain/counterparty.rs b/crates/relayer/src/chain/counterparty.rs index ac34d84f40..be9425aae2 100644 --- a/crates/relayer/src/chain/counterparty.rs +++ b/crates/relayer/src/chain/counterparty.rs @@ -2,7 +2,6 @@ use std::collections::HashSet; use ibc_relayer_types::{ core::{ - ics02_client::client_state::ClientState, ics03_connection::connection::{ ConnectionEnd, IdentifiedConnectionEnd, State as ConnectionState, }, diff --git a/crates/relayer/src/chain/endpoint.rs b/crates/relayer/src/chain/endpoint.rs index 4c0134dfb3..d47367a6b2 100644 --- a/crates/relayer/src/chain/endpoint.rs +++ b/crates/relayer/src/chain/endpoint.rs @@ -10,7 +10,7 @@ use ibc_relayer_types::applications::ics31_icq::response::CrossChainQueryRespons use ibc_relayer_types::core::ics02_client::client_state::ClientState; use ibc_relayer_types::core::ics02_client::consensus_state::ConsensusState; use ibc_relayer_types::core::ics02_client::events::UpdateClient; -use ibc_relayer_types::core::ics02_client::header::Header; +use ibc_relayer_types::core::ics02_client::header::{AnyHeader, Header}; use ibc_relayer_types::core::ics03_connection::connection::{ ConnectionEnd, IdentifiedConnectionEnd, State, }; @@ -44,7 +44,6 @@ use crate::denom::DenomTrace; use crate::error::Error; use crate::event::IbcEventWithHeight; use crate::keyring::{AnySigningKeyPair, KeyRing, SigningKeyPairSized}; -use crate::light_client::AnyHeader; use crate::misbehaviour::MisbehaviourEvidence; /// The result of a health check. @@ -82,12 +81,10 @@ pub trait ChainEndpoint: Sized { type SigningKeyPair: SigningKeyPairSized + Into; /// Returns the chain's identifier - fn id(&self) -> &ChainId { - &self.config().id - } + fn id(&self) -> &ChainId; /// Returns the chain configuration - fn config(&self) -> &ChainConfig; + fn config(&self) -> ChainConfig; // Life cycle @@ -114,15 +111,7 @@ pub trait ChainEndpoint: Sized { fn get_signer(&self) -> Result; /// Get the signing key pair - fn get_key(&mut self) -> Result { - // Get the key from key seed file - let key_pair = self - .keybase() - .get_key(&self.config().key_name) - .map_err(|e| Error::key_not_found(self.config().key_name.clone(), e))?; - - Ok(key_pair) - } + fn get_key(&mut self) -> Result; fn add_key(&mut self, key_name: &str, key_pair: Self::SigningKeyPair) -> Result<(), Error> { self.keybase_mut() @@ -695,4 +684,6 @@ pub trait ChainEndpoint: Sized { &self, request: QueryIncentivizedPacketRequest, ) -> Result; + + fn query_consumer_chains(&self) -> Result, Error>; } diff --git a/crates/relayer/src/chain/handle.rs b/crates/relayer/src/chain/handle.rs index be905173cb..af6cb7e1ef 100644 --- a/crates/relayer/src/chain/handle.rs +++ b/crates/relayer/src/chain/handle.rs @@ -10,7 +10,7 @@ use ibc_proto::ibc::apps::fee::v1::{ use ibc_relayer_types::{ applications::ics31_icq::response::CrossChainQueryResponse, core::{ - ics02_client::events::UpdateClient, + ics02_client::{events::UpdateClient, header::AnyHeader}, ics03_connection::{ connection::{ConnectionEnd, IdentifiedConnectionEnd}, version::Version, @@ -40,7 +40,6 @@ use crate::{ IbcEventWithHeight, }, keyring::AnySigningKeyPair, - light_client::AnyHeader, misbehaviour::MisbehaviourEvidence, }; @@ -367,6 +366,10 @@ pub enum ChainRequest { request: QueryIncentivizedPacketRequest, reply_to: ReplyTo, }, + + QueryConsumerChains { + reply_to: ReplyTo>, + }, } pub trait ChainHandle: Clone + Display + Send + Sync + Debug + 'static { @@ -678,4 +681,6 @@ pub trait ChainHandle: Clone + Display + Send + Sync + Debug + 'static { &self, request: QueryIncentivizedPacketRequest, ) -> Result; + + fn query_consumer_chains(&self) -> Result, Error>; } diff --git a/crates/relayer/src/chain/handle/base.rs b/crates/relayer/src/chain/handle/base.rs index 2c2264f55c..fccfd383f8 100644 --- a/crates/relayer/src/chain/handle/base.rs +++ b/crates/relayer/src/chain/handle/base.rs @@ -9,7 +9,7 @@ use ibc_proto::ibc::apps::fee::v1::{ use ibc_relayer_types::{ applications::ics31_icq::response::CrossChainQueryResponse, core::{ - ics02_client::events::UpdateClient, + ics02_client::{events::UpdateClient, header::AnyHeader}, ics03_connection::connection::{ConnectionEnd, IdentifiedConnectionEnd}, ics03_connection::version::Version, ics04_channel::channel::{ChannelEnd, IdentifiedChannelEnd}, @@ -35,7 +35,6 @@ use crate::{ error::Error, event::IbcEventWithHeight, keyring::AnySigningKeyPair, - light_client::AnyHeader, misbehaviour::MisbehaviourEvidence, }; @@ -515,4 +514,8 @@ impl ChainHandle for BaseChainHandle { ) -> Result { self.send(|reply_to| ChainRequest::QueryIncentivizedPacket { request, reply_to }) } + + fn query_consumer_chains(&self) -> Result, Error> { + self.send(|reply_to| ChainRequest::QueryConsumerChains { reply_to }) + } } diff --git a/crates/relayer/src/chain/handle/cache.rs b/crates/relayer/src/chain/handle/cache.rs index d09bc6927f..edec29b7fb 100644 --- a/crates/relayer/src/chain/handle/cache.rs +++ b/crates/relayer/src/chain/handle/cache.rs @@ -1,5 +1,6 @@ use core::fmt::{Display, Error as FmtError, Formatter}; use crossbeam_channel as channel; +use ibc_relayer_types::core::ics02_client::header::AnyHeader; use tracing::Span; use ibc_proto::ibc::apps::fee::v1::QueryIncentivizedPacketRequest; @@ -36,7 +37,6 @@ use crate::denom::DenomTrace; use crate::error::Error; use crate::event::IbcEventWithHeight; use crate::keyring::AnySigningKeyPair; -use crate::light_client::AnyHeader; use crate::misbehaviour::MisbehaviourEvidence; use crate::telemetry; @@ -510,4 +510,8 @@ impl ChainHandle for CachingChainHandle { ) -> Result { self.inner.query_incentivized_packet(request) } + + fn query_consumer_chains(&self) -> Result, Error> { + self.inner.query_consumer_chains() + } } diff --git a/crates/relayer/src/chain/handle/counting.rs b/crates/relayer/src/chain/handle/counting.rs index 66b83e5686..d08662bdc0 100644 --- a/crates/relayer/src/chain/handle/counting.rs +++ b/crates/relayer/src/chain/handle/counting.rs @@ -10,6 +10,7 @@ use ibc_proto::ibc::apps::fee::v1::{ }; use ibc_relayer_types::applications::ics31_icq::response::CrossChainQueryResponse; use ibc_relayer_types::core::ics02_client::events::UpdateClient; +use ibc_relayer_types::core::ics02_client::header::AnyHeader; use ibc_relayer_types::core::ics03_connection::connection::ConnectionEnd; use ibc_relayer_types::core::ics03_connection::connection::IdentifiedConnectionEnd; use ibc_relayer_types::core::ics03_connection::version::Version; @@ -39,7 +40,6 @@ use crate::denom::DenomTrace; use crate::error::Error; use crate::event::IbcEventWithHeight; use crate::keyring::AnySigningKeyPair; -use crate::light_client::AnyHeader; use crate::misbehaviour::MisbehaviourEvidence; use crate::util::lock::LockExt; @@ -503,4 +503,9 @@ impl ChainHandle for CountingChainHandle { self.inc_metric("query_incentivized_packet"); self.inner.query_incentivized_packet(request) } + + fn query_consumer_chains(&self) -> Result, Error> { + self.inc_metric("query_consumer_chains"); + self.inner.query_consumer_chains() + } } diff --git a/crates/relayer/src/chain/requests.rs b/crates/relayer/src/chain/requests.rs index be6e071251..cc45908172 100644 --- a/crates/relayer/src/chain/requests.rs +++ b/crates/relayer/src/chain/requests.rs @@ -76,12 +76,18 @@ impl Display for QueryHeight { /// Defines a type to be used in select requests to specify whether or not a proof should be /// returned along with the response. -#[derive(Clone, Copy, Debug, Serialize, Deserialize)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] pub enum IncludeProof { Yes, No, } +impl IncludeProof { + pub fn to_bool(&self) -> bool { + *self == IncludeProof::Yes + } +} + #[derive(Clone, Debug, Default, Serialize, Deserialize)] pub struct PageRequest { /// key is a value returned in PageResponse.next_key to begin diff --git a/crates/relayer/src/chain/runtime.rs b/crates/relayer/src/chain/runtime.rs index 0426f6377d..1c700a6978 100644 --- a/crates/relayer/src/chain/runtime.rs +++ b/crates/relayer/src/chain/runtime.rs @@ -12,6 +12,7 @@ use ibc_relayer_types::{ applications::ics31_icq::response::CrossChainQueryResponse, core::{ ics02_client::events::UpdateClient, + ics02_client::header::AnyHeader, ics03_connection::{ connection::{ConnectionEnd, IdentifiedConnectionEnd}, version::Version, @@ -21,7 +22,7 @@ use ibc_relayer_types::{ packet::{PacketMsgType, Sequence}, }, ics23_commitment::{commitment::CommitmentPrefix, merkle::MerkleProof}, - ics24_host::identifier::{ChannelId, ClientId, ConnectionId, PortId}, + ics24_host::identifier::{ChainId, ChannelId, ClientId, ConnectionId, PortId}, }, proofs::Proofs, signer::Signer, @@ -39,7 +40,6 @@ use crate::{ error::Error, event::IbcEventWithHeight, keyring::AnySigningKeyPair, - light_client::AnyHeader, misbehaviour::MisbehaviourEvidence, }; @@ -349,6 +349,10 @@ where ChainRequest::QueryIncentivizedPacket { request, reply_to } => { self.query_incentivized_packet(request, reply_to)? }, + + ChainRequest::QueryConsumerChains { reply_to } => { + self.query_consumer_chains(reply_to)? + }, } }, } @@ -850,4 +854,14 @@ where Ok(()) } + + fn query_consumer_chains( + &self, + reply_to: ReplyTo>, + ) -> Result<(), Error> { + let result = self.chain.query_consumer_chains(); + reply_to.send(result).map_err(Error::send)?; + + Ok(()) + } } diff --git a/crates/relayer/src/channel.rs b/crates/relayer/src/channel.rs index 84bce4470e..372ee4a42e 100644 --- a/crates/relayer/src/channel.rs +++ b/crates/relayer/src/channel.rs @@ -481,12 +481,12 @@ impl Channel { .a_chain() .config() .map_err(ChannelError::relayer)? - .max_block_time; + .max_block_time(); let b_block_time = self .b_chain() .config() .map_err(ChannelError::relayer)? - .max_block_time; + .max_block_time(); Ok(a_block_time.max(b_block_time)) } diff --git a/crates/relayer/src/channel/error.rs b/crates/relayer/src/channel/error.rs index 7fc820ce89..c6d3b40391 100644 --- a/crates/relayer/src/channel/error.rs +++ b/crates/relayer/src/channel/error.rs @@ -196,16 +196,27 @@ define_error! { } impl HasExpiredOrFrozenError for ChannelErrorDetail { - fn is_expired_or_frozen_error(&self) -> bool { + fn is_frozen_error(&self) -> bool { match self { - Self::ClientOperation(e) => e.source.is_expired_or_frozen_error(), + Self::ClientOperation(e) => e.source.is_frozen_error(), + _ => false, + } + } + + fn is_expired_error(&self) -> bool { + match self { + Self::ClientOperation(e) => e.source.is_expired_error(), _ => false, } } } impl HasExpiredOrFrozenError for ChannelError { - fn is_expired_or_frozen_error(&self) -> bool { - self.detail().is_expired_or_frozen_error() + fn is_frozen_error(&self) -> bool { + self.detail().is_frozen_error() + } + + fn is_expired_error(&self) -> bool { + self.detail().is_expired_error() } } diff --git a/crates/relayer/src/client_state.rs b/crates/relayer/src/client_state.rs index 8c5eff288b..91b729e7e6 100644 --- a/crates/relayer/src/client_state.rs +++ b/crates/relayer/src/client_state.rs @@ -1,31 +1,30 @@ use core::time::Duration; -use ibc_proto::ibc::core::client::v1::IdentifiedClientState; -use ibc_proto::ibc::lightclients::tendermint::v1::ClientState as RawClientState; -#[cfg(test)] -use ibc_proto::ibc::mock::ClientState as RawMockClientState; -use ibc_proto::protobuf::Protobuf; use serde::{Deserialize, Serialize}; use ibc_proto::google::protobuf::Any; +use ibc_proto::ibc::core::client::v1::IdentifiedClientState; +use ibc_proto::ibc::lightclients::tendermint::v1::ClientState as RawTmClientState; +use ibc_proto::Protobuf; use ibc_relayer_types::clients::ics07_tendermint::client_state::{ ClientState as TmClientState, UpgradeOptions as TmUpgradeOptions, TENDERMINT_CLIENT_STATE_TYPE_URL, }; -use ibc_relayer_types::core::ics02_client::client_state::{ - downcast_client_state, ClientState, UpgradeOptions, -}; +use ibc_relayer_types::core::ics02_client::client_state::ClientState; use ibc_relayer_types::core::ics02_client::client_type::ClientType; use ibc_relayer_types::core::ics02_client::error::Error; use ibc_relayer_types::core::ics02_client::trust_threshold::TrustThreshold; use ibc_relayer_types::core::ics24_host::error::ValidationError; use ibc_relayer_types::core::ics24_host::identifier::{ChainId, ClientId}; +use ibc_relayer_types::Height; + +#[cfg(test)] +use ibc_proto::ibc::mock::ClientState as RawMockClientState; #[cfg(test)] use ibc_relayer_types::mock::client_state::MockClientState; #[cfg(test)] use ibc_relayer_types::mock::client_state::MOCK_CLIENT_STATE_TYPE_URL; -use ibc_relayer_types::Height; #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(tag = "type")] @@ -37,7 +36,7 @@ pub enum AnyUpgradeOptions { } impl AnyUpgradeOptions { - fn as_tm_upgrade_options(&self) -> Option<&TmUpgradeOptions> { + fn into_tm_upgrade_options(self) -> Option { match self { AnyUpgradeOptions::Tendermint(tm) => Some(tm), #[cfg(test)] @@ -46,8 +45,6 @@ impl AnyUpgradeOptions { } } -impl UpgradeOptions for AnyUpgradeOptions {} - #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[serde(tag = "type")] pub enum AnyClientState { @@ -58,6 +55,15 @@ pub enum AnyClientState { } impl AnyClientState { + pub fn chain_id(&self) -> ChainId { + match self { + AnyClientState::Tendermint(tm_state) => tm_state.chain_id(), + + #[cfg(test)] + AnyClientState::Mock(mock_state) => mock_state.chain_id(), + } + } + pub fn latest_height(&self) -> Height { match self { Self::Tendermint(tm_state) => tm_state.latest_height(), @@ -123,7 +129,7 @@ impl TryFrom for AnyClientState { "" => Err(Error::empty_client_state_response()), TENDERMINT_CLIENT_STATE_TYPE_URL => Ok(AnyClientState::Tendermint( - Protobuf::::decode_vec(&raw.value) + Protobuf::::decode_vec(&raw.value) .map_err(Error::decode_raw_client_state)?, )), @@ -143,18 +149,20 @@ impl From for Any { match value { AnyClientState::Tendermint(value) => Any { type_url: TENDERMINT_CLIENT_STATE_TYPE_URL.to_string(), - value: Protobuf::::encode_vec(&value), + value: Protobuf::::encode_vec(value), }, #[cfg(test)] AnyClientState::Mock(value) => Any { type_url: MOCK_CLIENT_STATE_TYPE_URL.to_string(), - value: Protobuf::::encode_vec(&value), + value: Protobuf::::encode_vec(value), }, } } } impl ClientState for AnyClientState { + type UpgradeOptions = AnyUpgradeOptions; + fn chain_id(&self) -> ChainId { match self { AnyClientState::Tendermint(tm_state) => tm_state.chain_id(), @@ -179,24 +187,21 @@ impl ClientState for AnyClientState { fn upgrade( &mut self, upgrade_height: Height, - upgrade_options: &dyn UpgradeOptions, + upgrade_options: AnyUpgradeOptions, chain_id: ChainId, ) { - let upgrade_options = upgrade_options - .as_any() - .downcast_ref::() - .expect("UpgradeOptions not of type AnyUpgradeOptions"); - match self { - AnyClientState::Tendermint(tm_state) => tm_state.upgrade( - upgrade_height, - upgrade_options.as_tm_upgrade_options().unwrap(), - chain_id, - ), + AnyClientState::Tendermint(tm_state) => { + if let Some(upgrade_options) = upgrade_options.into_tm_upgrade_options() { + tm_state.upgrade(upgrade_height, upgrade_options, chain_id); + } + // TODO: Handle case where upgrade options are not of the right type, + // not a problem in practice for now but good to have. + } #[cfg(test)] AnyClientState::Mock(mock_state) => { - mock_state.upgrade(upgrade_height, upgrade_options, chain_id) + mock_state.upgrade(upgrade_height, (), chain_id); } } } @@ -224,21 +229,6 @@ impl From for AnyClientState { } } -impl From<&dyn ClientState> for AnyClientState { - fn from(client_state: &dyn ClientState) -> Self { - #[cfg(test)] - if let Some(cs) = downcast_client_state::(client_state) { - return AnyClientState::from(*cs); - } - - if let Some(cs) = downcast_client_state::(client_state) { - AnyClientState::from(cs.clone()) - } else { - unreachable!() - } - } -} - #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[serde(tag = "type")] pub struct IdentifiedAnyClientState { diff --git a/crates/relayer/src/config.rs b/crates/relayer/src/config.rs index 8fe656dcb3..55ff61f68f 100644 --- a/crates/relayer/src/config.rs +++ b/crates/relayer/src/config.rs @@ -15,28 +15,20 @@ use core::{ time::Duration, }; use serde_derive::{Deserialize, Serialize}; -use std::{ - fs, - fs::File, - io::Write, - ops::Range, - path::{Path, PathBuf}, -}; +use std::{fs, fs::File, io::Write, ops::Range, path::Path}; use tendermint::block::Height as BlockHeight; -use tendermint_light_client::verifier::types::TrustThreshold; use tendermint_rpc::{Url, WebSocketClientUrl}; use ibc_proto::google::protobuf::Any; -use ibc_relayer_types::core::ics23_commitment::specs::ProofSpecs; use ibc_relayer_types::core::ics24_host::identifier::{ChainId, ChannelId, PortId}; use ibc_relayer_types::timestamp::ZERO_DURATION; -use crate::chain::ChainType; -use crate::config::gas_multiplier::GasMultiplier; -use crate::config::types::{MaxMsgNum, MaxTxSize, Memo}; -use crate::error::Error as RelayerError; use crate::extension_options::ExtensionOptionDynamicFeeTx; use crate::keyring::Store; +use crate::keyring::{AnySigningKeyPair, KeyRing}; +use crate::{chain::cosmos::config::CosmosSdkConfig, error::Error as RelayerError}; + +use crate::keyring; pub use crate::config::Error as ConfigError; pub use error::Error; @@ -150,10 +142,6 @@ impl Display for ExtensionOption { pub mod default { use super::*; - pub fn chain_type() -> ChainType { - ChainType::CosmosSdk - } - pub fn ccv_consumer_chain() -> bool { false } @@ -246,15 +234,15 @@ pub struct Config { impl Config { pub fn has_chain(&self, id: &ChainId) -> bool { - self.chains.iter().any(|c| c.id == *id) + self.chains.iter().any(|c| c.id() == id) } pub fn find_chain(&self, id: &ChainId) -> Option<&ChainConfig> { - self.chains.iter().find(|c| c.id == *id) + self.chains.iter().find(|c| c.id() == id) } pub fn find_chain_mut(&mut self, id: &ChainId) -> Option<&mut ChainConfig> { - self.chains.iter_mut().find(|c| c.id == *id) + self.chains.iter_mut().find(|c| c.id() == id) } /// Returns true if filtering is disabled or if packets are allowed on @@ -268,7 +256,7 @@ impl Config { ) -> bool { match self.find_chain(chain_id) { Some(chain_config) => chain_config - .packet_filter + .packet_filter() .channel_policy .is_allowed(port_id, channel_id), None => false, @@ -276,7 +264,35 @@ impl Config { } pub fn chains_map(&self) -> BTreeMap<&ChainId, &ChainConfig> { - self.chains.iter().map(|c| (&c.id, c)).collect() + self.chains.iter().map(|c| (c.id(), c)).collect() + } + + /// Method for syntactic validation of the input configuration file. + pub fn validate_config(&self) -> Result<(), Diagnostic> { + use alloc::collections::BTreeSet; + // Check for duplicate chain configuration and invalid trust thresholds + let mut unique_chain_ids = BTreeSet::new(); + for chain_config in self.chains.iter() { + let already_present = !unique_chain_ids.insert(chain_config.id().clone()); + if already_present { + return Err(Diagnostic::Error(Error::duplicate_chains( + chain_config.id().clone(), + ))); + } + + match chain_config { + ChainConfig::CosmosSdk(cosmos_config) => { + cosmos_config + .validate() + .map_err(Into::>::into)?; + } + } + } + + // Check for invalid mode config + self.mode.validate()?; + + Ok(()) } } @@ -296,6 +312,22 @@ impl ModeConfig { && !self.channels.enabled && !self.packets.enabled } + + fn validate(&self) -> Result<(), Diagnostic> { + if self.all_disabled() { + return Err(Diagnostic::Warning(Error::invalid_mode( + "all operation modes of Hermes are disabled, relayer won't perform any action aside from subscribing to events".to_string(), + ))); + } + + if self.clients.enabled && !self.clients.refresh && !self.clients.misbehaviour { + return Err(Diagnostic::Error(Error::invalid_mode( + "either `refresh` or `misbehaviour` must be set to true if `clients.enabled` is set to true".to_string(), + ))); + } + + Ok(()) + } } /// # IMPORTANT: Keep the values here in sync with the values in the default config.toml. @@ -556,113 +588,60 @@ pub enum EventSourceMode { #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] #[serde(deny_unknown_fields)] -pub struct ChainConfig { - /// The chain's network identifier - pub id: ChainId, - - /// The chain type - #[serde(default = "default::chain_type")] - pub r#type: ChainType, - - /// The RPC URL to connect to - pub rpc_addr: Url, - - /// The gRPC URL to connect to - pub grpc_addr: Url, - - /// The type of event source and associated settings - pub event_source: EventSourceMode, - - /// Timeout used when issuing RPC queries - #[serde(default = "default::rpc_timeout", with = "humantime_serde")] - pub rpc_timeout: Duration, - - /// Whether or not the full node Hermes connects to is trusted - #[serde(default = "default::trusted_node")] - pub trusted_node: bool, +#[serde(tag = "type")] +pub enum ChainConfig { + CosmosSdk(CosmosSdkConfig), +} - pub account_prefix: String, - 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, - - // This field is only meant to be set via the `update client` command, - // for when we need to ugprade a client across a genesis restart and - // therefore need and archive node to fetch blocks from. - pub genesis_restart: Option, - - // This field is deprecated, use `gas_multiplier` instead - pub gas_adjustment: Option, - pub gas_multiplier: Option, - - pub fee_granter: Option, - #[serde(default)] - pub max_msg_num: MaxMsgNum, - #[serde(default)] - pub max_tx_size: MaxTxSize, - #[serde(default = "default::max_grpc_decoding_size")] - pub max_grpc_decoding_size: Byte, - - /// A correction parameter that helps deal with clocks that are only approximately synchronized - /// between the source and destination chains for a client. - /// This parameter is used when deciding to accept or reject a new header - /// (originating from the source chain) for any client with the destination chain - /// that uses this configuration, unless it is overridden by the client-specific - /// clock drift option. - #[serde(default = "default::clock_drift", with = "humantime_serde")] - pub clock_drift: Duration, - - #[serde(default = "default::max_block_time", with = "humantime_serde")] - pub max_block_time: Duration, - - /// The trusting period specifies how long a validator set is trusted for - /// (must be shorter than the chain's unbonding period). - #[serde(default, with = "humantime_serde")] - pub trusting_period: Option, - - /// CCV consumer chain - #[serde(default = "default::ccv_consumer_chain")] - pub ccv_consumer_chain: bool, +impl ChainConfig { + pub fn id(&self) -> &ChainId { + match self { + Self::CosmosSdk(config) => &config.id, + } + } - #[serde(default)] - pub memo_prefix: Memo, + pub fn packet_filter(&self) -> &PacketFilter { + match self { + Self::CosmosSdk(config) => &config.packet_filter, + } + } - // This is an undocumented and hidden config to make the relayer wait for - // DeliverTX before sending the next transaction when sending messages in - // multiple batches. We will instruct relayer operators to turn this on - // in case relaying failed in a chain with priority mempool enabled. - // Warning: turning this on may cause degradation in performance. - #[serde(default)] - pub sequential_batch_tx: bool, - - // Note: These last few need to be last otherwise we run into `ValueAfterTable` error when serializing to TOML. - // That's because these are all tables and have to come last when serializing. - #[serde( - default, - skip_serializing_if = "Option::is_none", - with = "self::proof_specs" - )] - pub proof_specs: Option, - - // These last few need to be last otherwise we run into `ValueAfterTable` error when serializing to TOML - /// The trust threshold defines what fraction of the total voting power of a known - /// and trusted validator set is sufficient for a commit to be accepted going forward. - #[serde(default)] - pub trust_threshold: TrustThreshold, + pub fn max_block_time(&self) -> Duration { + match self { + Self::CosmosSdk(config) => config.max_block_time, + } + } - pub gas_price: GasPrice, + pub fn key_name(&self) -> &String { + match self { + Self::CosmosSdk(config) => &config.key_name, + } + } - #[serde(default)] - pub packet_filter: PacketFilter, + pub fn set_key_name(&mut self, key_name: String) { + match self { + Self::CosmosSdk(config) => config.key_name = key_name, + } + } - #[serde(default)] - pub address_type: AddressType, - #[serde(default = "Vec::new", skip_serializing_if = "Vec::is_empty")] - pub extension_options: Vec, + pub fn list_keys(&self) -> Result, keyring::errors::Error> { + let keys = match self { + ChainConfig::CosmosSdk(config) => { + let keyring = KeyRing::new_secp256k1( + Store::Test, + &config.account_prefix, + &config.id, + &config.key_store_folder, + )?; + keyring + .keys()? + .into_iter() + .map(|(key_name, keys)| (key_name, keys.into())) + .collect() + } + }; + Ok(keys) + } } /// Attempt to load and parse the TOML config file as a `Config`. @@ -710,6 +689,29 @@ impl Default for TracingServerConfig { } } +#[derive(Clone, Debug)] +pub enum Diagnostic { + Warning(E), + Error(E), +} + +use crate::chain::cosmos::config::Diagnostic as CosmosConfigDiagnostic; +impl> From> for Diagnostic { + fn from(value: CosmosConfigDiagnostic) -> Self { + match value { + CosmosConfigDiagnostic::Warning(e) => Diagnostic::Warning(e.into()), + CosmosConfigDiagnostic::Error(e) => Diagnostic::Error(e.into()), + } + } +} + +use crate::chain::cosmos::config::error::Error as CosmosConfigError; +impl From for Error { + fn from(error: CosmosConfigError) -> Error { + Error::cosmos_config_error(error.to_string()) + } +} + #[cfg(test)] mod tests { use core::str::FromStr; diff --git a/crates/relayer/src/config/error.rs b/crates/relayer/src/config/error.rs index 9889e553ad..b827465583 100644 --- a/crates/relayer/src/config/error.rs +++ b/crates/relayer/src/config/error.rs @@ -1,8 +1,36 @@ +use ibc_relayer_types::core::ics24_host::identifier::ChainId; + use flex_error::{define_error, TraceError}; +use tracing_subscriber::filter::ParseError; +// Specifies all the possible errors that a Hermes config file can contain. define_error! { Error { - Io + ZeroChain + |_| { "config file does not specify any chain" }, + + InvalidLogDirective + { directive: String, } + [ TraceError ] + |e| { + format!("invalid log directive: {0:?}", e.directive) + }, + + InvalidMode + { reason: String, } + |e| { + format!("config file specifies invalid mode config, caused by: {0}", + e.reason) + }, + + DuplicateChains + { chain_id: ChainId } + |e| { + format!("config file has duplicate entry for the chain '{0}'", + e.chain_id) + }, + + Io [ TraceError ] |_| { "config I/O error" }, @@ -14,8 +42,18 @@ define_error! { [ TraceError ] |_| { "invalid configuration" }, + WrongType + |_| { "wrong configuration type" }, + InvalidGasPrice { price: String } - |e| { format!("invalid gas price: {}", e.price) }, + |e| { + format!("invalid gas price: {}", e.price) + }, + + CosmosConfigError { reason: String } + |e| { + format!("invalid cosmos config: {}", e.reason) + }, } } diff --git a/crates/relayer/src/connection.rs b/crates/relayer/src/connection.rs index 341049446b..5e1ee140be 100644 --- a/crates/relayer/src/connection.rs +++ b/crates/relayer/src/connection.rs @@ -445,12 +445,12 @@ impl Connection { .a_chain() .config() .map_err(ConnectionError::relayer)? - .max_block_time; + .max_block_time(); let b_block_time = self .b_chain() .config() .map_err(ConnectionError::relayer)? - .max_block_time; + .max_block_time(); Ok(a_block_time.max(b_block_time)) } diff --git a/crates/relayer/src/connection/error.rs b/crates/relayer/src/connection/error.rs index f8f026bcfa..ee017b5cc9 100644 --- a/crates/relayer/src/connection/error.rs +++ b/crates/relayer/src/connection/error.rs @@ -187,16 +187,27 @@ define_error! { } impl HasExpiredOrFrozenError for ConnectionErrorDetail { - fn is_expired_or_frozen_error(&self) -> bool { + fn is_frozen_error(&self) -> bool { match self { - Self::ClientOperation(e) => e.source.is_expired_or_frozen_error(), + Self::ClientOperation(e) => e.source.is_frozen_error(), + _ => false, + } + } + + fn is_expired_error(&self) -> bool { + match self { + Self::ClientOperation(e) => e.source.is_expired_error(), _ => false, } } } impl HasExpiredOrFrozenError for ConnectionError { - fn is_expired_or_frozen_error(&self) -> bool { - self.detail().is_expired_or_frozen_error() + fn is_frozen_error(&self) -> bool { + self.detail().is_frozen_error() + } + + fn is_expired_error(&self) -> bool { + self.detail().is_expired_error() } } diff --git a/crates/relayer/src/consensus_state.rs b/crates/relayer/src/consensus_state.rs index 71abf1828d..c6b6f8114e 100644 --- a/crates/relayer/src/consensus_state.rs +++ b/crates/relayer/src/consensus_state.rs @@ -1,25 +1,25 @@ +use serde::{Deserialize, Serialize}; + use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::core::client::v1::ConsensusStateWithHeight; use ibc_proto::ibc::lightclients::tendermint::v1::ConsensusState as RawConsensusState; -#[cfg(test)] -use ibc_proto::ibc::mock::ConsensusState as RawMockConsensusState; -use ibc_proto::protobuf::Protobuf; +use ibc_proto::Protobuf; use ibc_relayer_types::clients::ics07_tendermint::consensus_state::{ ConsensusState as TmConsensusState, TENDERMINT_CONSENSUS_STATE_TYPE_URL, }; use ibc_relayer_types::core::ics02_client::client_type::ClientType; -use ibc_relayer_types::core::ics02_client::consensus_state::{ - downcast_consensus_state, ConsensusState, -}; +use ibc_relayer_types::core::ics02_client::consensus_state::ConsensusState; use ibc_relayer_types::core::ics02_client::error::Error; use ibc_relayer_types::core::ics23_commitment::commitment::CommitmentRoot; +use ibc_relayer_types::timestamp::Timestamp; +use ibc_relayer_types::Height; + +#[cfg(test)] +use ibc_proto::ibc::mock::ConsensusState as RawMockConsensusState; #[cfg(test)] use ibc_relayer_types::mock::consensus_state::MockConsensusState; #[cfg(test)] use ibc_relayer_types::mock::consensus_state::MOCK_CONSENSUS_STATE_TYPE_URL; -use ibc_relayer_types::timestamp::Timestamp; -use ibc_relayer_types::Height; -use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(tag = "type")] @@ -81,12 +81,12 @@ impl From for Any { match value { AnyConsensusState::Tendermint(value) => Any { type_url: TENDERMINT_CONSENSUS_STATE_TYPE_URL.to_string(), - value: Protobuf::::encode_vec(&value), + value: Protobuf::::encode_vec(value), }, #[cfg(test)] AnyConsensusState::Mock(value) => Any { type_url: MOCK_CONSENSUS_STATE_TYPE_URL.to_string(), - value: Protobuf::::encode_vec(&value), + value: Protobuf::::encode_vec(value), }, } } @@ -105,21 +105,6 @@ impl From for AnyConsensusState { } } -impl From<&dyn ConsensusState> for AnyConsensusState { - fn from(cs: &dyn ConsensusState) -> Self { - #[cfg(test)] - if let Some(cs) = downcast_consensus_state::(cs) { - return AnyConsensusState::from(cs.clone()); - } - - if let Some(cs) = downcast_consensus_state::(cs) { - AnyConsensusState::from(cs.clone()) - } else { - unreachable!() - } - } -} - #[derive(Clone, Debug, PartialEq, Eq, Serialize)] pub struct AnyConsensusStateWithHeight { pub height: Height, diff --git a/crates/relayer/src/error.rs b/crates/relayer/src/error.rs index 10e97c08b7..012c7af2e2 100644 --- a/crates/relayer/src/error.rs +++ b/crates/relayer/src/error.rs @@ -5,9 +5,13 @@ use core::time::Duration; use flex_error::{define_error, DisplayOnly, TraceError}; use http::uri::InvalidUri; use humantime::format_duration; -use ibc_proto::protobuf::Error as TendermintProtoError; use prost::{DecodeError, EncodeError}; use regex::Regex; +use tonic::{ + metadata::errors::InvalidMetadataValue, transport::Error as TransportError, + Status as GrpcStatus, +}; + use tendermint::abci; use tendermint::Error as TendermintError; use tendermint_light_client::builder::error::Error as LightClientBuilderError; @@ -15,28 +19,19 @@ use tendermint_light_client::components::io::IoError as LightClientIoError; use tendermint_light_client::errors::{ Error as LightClientError, ErrorDetail as LightClientErrorDetail, }; +use tendermint_proto::Error as TendermintProtoError; use tendermint_rpc::endpoint::abci_query::AbciQuery; use tendermint_rpc::endpoint::broadcast::tx_sync::Response as TxSyncResponse; use tendermint_rpc::Error as TendermintRpcError; -use tonic::{ - metadata::errors::InvalidMetadataValue, transport::Error as TransportError, - Status as GrpcStatus, -}; -use ibc_relayer_types::{ - applications::{ - ics29_fee::error::Error as FeeError, ics31_icq::error::Error as CrossChainQueryError, - }, - clients::ics07_tendermint::error as tendermint_error, - core::{ - ics02_client::{client_type::ClientType, error as client_error}, - ics03_connection::error as connection_error, - ics23_commitment::error as commitment_error, - ics24_host::identifier::{ChainId, ChannelId, ConnectionId}, - }, - proofs::ProofError, - relayer::ics18_relayer::error as relayer_error, -}; +use ibc_relayer_types::applications::ics29_fee::error::Error as FeeError; +use ibc_relayer_types::applications::ics31_icq::error::Error as CrossChainQueryError; +use ibc_relayer_types::clients::ics07_tendermint::error as tendermint_error; +use ibc_relayer_types::core::ics02_client::{client_type::ClientType, error as client_error}; +use ibc_relayer_types::core::ics03_connection::error as connection_error; +use ibc_relayer_types::core::ics23_commitment::error as commitment_error; +use ibc_relayer_types::core::ics24_host::identifier::{ChainId, ChannelId, ConnectionId}; +use ibc_relayer_types::proofs::ProofError; use crate::chain::cosmos::version; use crate::chain::cosmos::BLOCK_MAX_BYTES_MAX_FRACTION; @@ -281,10 +276,6 @@ define_error! { [ tendermint_error::Error ] |_| { "ICS 07 error" }, - Ics18 - [ relayer_error::Error ] - |_| { "ICS 18 error" }, - Ics23 [ commitment_error::Error ] |_| { "ICS 23 error" }, @@ -691,6 +682,7 @@ impl GrpcStatusSubdetail { fn parse_sequences_in_mismatch_error_message(message: &str) -> Option<(u64, u64)> { let re = Regex::new(r"account sequence mismatch, expected (?P\d+), got (?P\d+)") .unwrap(); + match re.captures(message) { None => None, Some(captures) => match (captures["expected"].parse(), captures["got"].parse()) { diff --git a/crates/relayer/src/event.rs b/crates/relayer/src/event.rs index 7d3e958505..b07ef50a84 100644 --- a/crates/relayer/src/event.rs +++ b/crates/relayer/src/event.rs @@ -8,7 +8,7 @@ use ibc_relayer_types::{ core::ics02_client::{ error::Error as ClientError, events::{self as client_events, Attributes as ClientAttributes, HEADER_ATTRIBUTE_KEY}, - header::Header, + header::{decode_header, AnyHeader}, height::HeightErrorDetail, }, core::ics03_connection::{ @@ -25,8 +25,6 @@ use ibc_relayer_types::{ Height, }; -use crate::light_client::decode_header; - pub mod bus; pub mod error; pub mod source; @@ -327,7 +325,7 @@ fn client_extract_attributes_from_tx(event: &AbciEvent) -> Result Result, ClientError> { +pub fn extract_header_from_tx(event: &AbciEvent) -> Result { for tag in &event.attributes { if tag.key == HEADER_ATTRIBUTE_KEY { let header_bytes = @@ -335,6 +333,7 @@ pub fn extract_header_from_tx(event: &AbciEvent) -> Result, Clie return decode_header(&header_bytes); } } + Err(ClientError::missing_raw_header()) } @@ -463,10 +462,9 @@ mod tests { use super::*; use ibc_proto::google::protobuf::Any; - use ibc_proto::protobuf::Protobuf; + use ibc_proto::Protobuf; use ibc_relayer_types::clients::ics07_tendermint::header::test_util::get_dummy_ics07_header; - use ibc_relayer_types::clients::ics07_tendermint::header::Header as TmHeader; - use ibc_relayer_types::core::ics02_client::header::downcast_header; + use ibc_relayer_types::core::ics02_client::header::{decode_header, AnyHeader}; use ibc_relayer_types::core::ics04_channel::packet::Sequence; use ibc_relayer_types::timestamp::Timestamp; @@ -474,12 +472,12 @@ mod tests { fn extract_header() { let header = get_dummy_ics07_header(); let mut header_bytes = Vec::new(); - Protobuf::::encode(&header, &mut header_bytes).unwrap(); + Protobuf::::encode(header.clone(), &mut header_bytes).unwrap(); let decoded_dyn_header = decode_header(&header_bytes).unwrap(); - let decoded_tm_header: &TmHeader = downcast_header(decoded_dyn_header.as_ref()).unwrap(); + let AnyHeader::Tendermint(decoded_tm_header) = decoded_dyn_header; - assert_eq!(&header, decoded_tm_header); + assert_eq!(header, decoded_tm_header); } #[test] diff --git a/crates/relayer/src/foreign_client.rs b/crates/relayer/src/foreign_client.rs index 008737e052..e1f7cc5d52 100644 --- a/crates/relayer/src/foreign_client.rs +++ b/crates/relayer/src/foreign_client.rs @@ -13,10 +13,11 @@ use itertools::Itertools; use tracing::{debug, error, info, instrument, trace, warn}; use flex_error::define_error; +use ibc_relayer_types::applications::ics28_ccv::msgs::ccv_misbehaviour::MsgSubmitIcsConsumerMisbehaviour; use ibc_relayer_types::core::ics02_client::client_state::ClientState; use ibc_relayer_types::core::ics02_client::error::Error as ClientError; use ibc_relayer_types::core::ics02_client::events::UpdateClient; -use ibc_relayer_types::core::ics02_client::header::Header; +use ibc_relayer_types::core::ics02_client::header::{AnyHeader, Header}; use ibc_relayer_types::core::ics02_client::msgs::create_client::MsgCreateClient; use ibc_relayer_types::core::ics02_client::msgs::misbehaviour::MsgSubmitMisbehaviour; use ibc_relayer_types::core::ics02_client::msgs::update_client::MsgUpdateClient; @@ -34,11 +35,11 @@ use crate::chain::handle::ChainHandle; use crate::chain::requests::*; use crate::chain::tracking::TrackedMsgs; use crate::client_state::AnyClientState; +use crate::config::ChainConfig; use crate::consensus_state::AnyConsensusState; use crate::error::Error as RelayerError; use crate::event::IbcEventWithHeight; -use crate::light_client::AnyHeader; -use crate::misbehaviour::MisbehaviourEvidence; +use crate::misbehaviour::{AnyMisbehaviour, MisbehaviourEvidence}; use crate::telemetry; use crate::util::collate::CollatedIterExt; use crate::util::pretty::{PrettyDuration, PrettySlice}; @@ -47,6 +48,21 @@ const MAX_MISBEHAVIOUR_CHECK_DURATION: Duration = Duration::from_secs(120); const MAX_RETRIES: usize = 5; +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum ExpiredOrFrozen { + Expired, + Frozen, +} + +impl fmt::Display for ExpiredOrFrozen { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + ExpiredOrFrozen::Expired => write!(f, "expired"), + ExpiredOrFrozen::Frozen => write!(f, "frozen"), + } + } +} + define_error! { ForeignClientError { ClientCreate @@ -224,13 +240,14 @@ define_error! { ExpiredOrFrozen { + status: ExpiredOrFrozen, client_id: ClientId, chain_id: ChainId, description: String, } |e| { - format_args!("client {0} on chain id {1} is expired or frozen: {2}", - e.client_id, e.chain_id, e.description) + format_args!("client {0} on chain id {1} is {2}: {3}", + e.client_id, e.chain_id, e.status, e.description) }, ConsensusStateNotTrusted @@ -252,6 +269,14 @@ define_error! { format_args!("error raised while checking for misbehaviour evidence: {0}", e.description) }, + MisbehaviourDesc + { + description: String, + } + |e| { + format_args!("error raised while checking for misbehaviour evidence: {0}", e.description) + }, + MisbehaviourExit { reason: String } |e| { @@ -286,18 +311,39 @@ define_error! { } pub trait HasExpiredOrFrozenError { - fn is_expired_or_frozen_error(&self) -> bool; + fn is_expired_error(&self) -> bool; + fn is_frozen_error(&self) -> bool; + + fn is_expired_or_frozen_error(&self) -> bool { + self.is_expired_error() || self.is_frozen_error() + } } impl HasExpiredOrFrozenError for ForeignClientErrorDetail { - fn is_expired_or_frozen_error(&self) -> bool { - matches!(self, Self::ExpiredOrFrozen(_)) + fn is_expired_error(&self) -> bool { + if let Self::ExpiredOrFrozen(e) = self { + e.status == ExpiredOrFrozen::Expired + } else { + false + } + } + + fn is_frozen_error(&self) -> bool { + if let Self::ExpiredOrFrozen(e) = self { + e.status == ExpiredOrFrozen::Frozen + } else { + false + } } } impl HasExpiredOrFrozenError for ForeignClientError { - fn is_expired_or_frozen_error(&self) -> bool { - self.detail().is_expired_or_frozen_error() + fn is_expired_error(&self) -> bool { + self.detail().is_expired_error() + } + + fn is_frozen_error(&self) -> bool { + self.detail().is_frozen_error() } } @@ -706,6 +752,7 @@ impl ForeignClient ForeignClient Ok((client_state, Some(elapsed))), @@ -786,6 +834,20 @@ impl ForeignClient bool { + match self.validated_client_state() { + Ok(_) => false, + Err(e) => e.is_frozen_error(), + } + } + + pub fn is_expired(&self) -> bool { + match self.validated_client_state() { + Ok(_) => false, + Err(e) => e.is_expired_error(), + } + } + pub fn is_expired_or_frozen(&self) -> bool { match self.validated_client_state() { Ok(_) => false, @@ -1467,10 +1529,7 @@ impl ForeignClient ForeignClient ForeignClient config.ccv_consumer_chain, + }; + let mut msgs = vec![]; for header in evidence.supporting_headers { @@ -1656,6 +1726,30 @@ impl ForeignClient Some(tm_misbehaviour.clone()), + #[cfg(test)] + _ => None, + } + .ok_or_else(|| { + ForeignClientError::misbehaviour_desc(format!( + "underlying evidence is not a Tendermint misbehaviour: {:?}", + evidence.misbehaviour + )) + })?; + + // If the misbehaving chain is a CCV consumer chain, we need to add + // the corresponding CCV message for the provider. + if is_ccv_consumer_chain { + msgs.push( + MsgSubmitIcsConsumerMisbehaviour { + submitter: signer.clone(), + misbehaviour: tm_misbehaviour, + } + .to_any(), + ); + } + msgs.push( MsgSubmitMisbehaviour { misbehaviour: evidence.misbehaviour.into(), @@ -1686,7 +1780,7 @@ impl ForeignClient ForeignClient match e.detail() { ForeignClientErrorDetail::MisbehaviourExit(s) => { - error!("misbehaviour checking is being disabled, reason: {}", s); + error!("misbehaviour checking is being disabled, reason: {s}"); MisbehaviourResults::CannotExecute } ForeignClientErrorDetail::ExpiredOrFrozen(_) => { - error!("cannot check misbehavior on frozen or expired client",); + error!("cannot check misbehavior on frozen or expired client"); MisbehaviourResults::CannotExecute } // FIXME: This is fishy - _ if update_event.is_some() => MisbehaviourResults::CannotExecute, + e if update_event.is_some() => { + error!("encountered unexpected error while checking misbehaviour: {e}"); + debug!("update event: {}", update_event.unwrap()); + + MisbehaviourResults::CannotExecute + } // FIXME: This is fishy _ => { - warn!("misbehaviour checking result: {}", e); + warn!("misbehaviour checking result: {e}"); MisbehaviourResults::ValidClient } diff --git a/crates/relayer/src/keyring.rs b/crates/relayer/src/keyring.rs index b5967b24a7..1260de235e 100644 --- a/crates/relayer/src/keyring.rs +++ b/crates/relayer/src/keyring.rs @@ -21,7 +21,6 @@ use std::path::PathBuf; use ibc_relayer_types::core::ics24_host::identifier::ChainId; use serde::{Deserialize, Serialize}; -use crate::{chain::ChainType, config::ChainConfig}; use errors::Error; pub const KEYSTORE_DEFAULT_FOLDER: &str = ".hermes/keys/"; @@ -287,24 +286,7 @@ impl KeyRing { } } -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, - &config.key_store_folder, - )?; - keyring - .keys()? - .into_iter() - .map(|(key_name, keys)| (key_name, keys.into())) - .collect() - } - }; - Ok(keys) -} +// Why is this not a method on `ChainConfig`? fn disk_store_path(folder_name: &str, keystore_folder: &Option) -> Result { let ks_folder = match keystore_folder { diff --git a/crates/relayer/src/light_client.rs b/crates/relayer/src/light_client.rs index 5f19bba177..2cea5a6ac6 100644 --- a/crates/relayer/src/light_client.rs +++ b/crates/relayer/src/light_client.rs @@ -1,21 +1,8 @@ pub mod io; pub mod tendermint; -use core::ops::Deref; - -use ibc_proto::google::protobuf::Any; -use ibc_proto::ibc::lightclients::tendermint::v1::Header as RawTmHeader; -use ibc_proto::protobuf::Protobuf as ErasedProtobuf; -use ibc_relayer_types::clients::ics07_tendermint::header::{ - decode_header as tm_decode_header, Header as TendermintHeader, TENDERMINT_HEADER_TYPE_URL, -}; -use ibc_relayer_types::core::ics02_client::client_type::ClientType; -use ibc_relayer_types::core::ics02_client::error::Error; use ibc_relayer_types::core::ics02_client::events::UpdateClient; -use ibc_relayer_types::core::ics02_client::header::Header; -use ibc_relayer_types::timestamp::Timestamp; use ibc_relayer_types::Height; -use serde::{Deserialize, Serialize}; use crate::chain::endpoint::ChainEndpoint; use crate::client_state::AnyClientState; @@ -67,75 +54,3 @@ pub trait LightClient: Send + Sync { /// Fetch a header from the chain at the given height, without verifying it fn fetch(&mut self, height: Height) -> Result; } - -/// Decodes an encoded header into a known `Header` type, -pub fn decode_header(header_bytes: &[u8]) -> Result, Error> { - // For now, we only have tendermint; however when there is more than one, we - // can try decoding into all the known types, and return an error only if - // none work - let header: TendermintHeader = - ErasedProtobuf::::decode(header_bytes).map_err(Error::invalid_raw_header)?; - - Ok(Box::new(header)) -} - -#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] -#[allow(clippy::large_enum_variant)] -pub enum AnyHeader { - Tendermint(TendermintHeader), -} - -impl Header for AnyHeader { - fn client_type(&self) -> ClientType { - match self { - Self::Tendermint(header) => header.client_type(), - } - } - - fn height(&self) -> Height { - match self { - Self::Tendermint(header) => header.height(), - } - } - - fn timestamp(&self) -> Timestamp { - match self { - Self::Tendermint(header) => header.timestamp(), - } - } -} - -impl ErasedProtobuf for AnyHeader {} - -impl TryFrom for AnyHeader { - type Error = Error; - - fn try_from(raw: Any) -> Result { - match raw.type_url.as_str() { - TENDERMINT_HEADER_TYPE_URL => { - let val = tm_decode_header(raw.value.deref())?; - - Ok(AnyHeader::Tendermint(val)) - } - - _ => Err(Error::unknown_header_type(raw.type_url)), - } - } -} - -impl From for Any { - fn from(value: AnyHeader) -> Self { - match value { - AnyHeader::Tendermint(header) => Any { - type_url: TENDERMINT_HEADER_TYPE_URL.to_string(), - value: ErasedProtobuf::::encode_vec(&header), - }, - } - } -} - -impl From for AnyHeader { - fn from(header: TendermintHeader) -> Self { - Self::Tendermint(header) - } -} diff --git a/crates/relayer/src/light_client/tendermint.rs b/crates/relayer/src/light_client/tendermint.rs index 5e3d4c3fae..a0f1a111e6 100644 --- a/crates/relayer/src/light_client/tendermint.rs +++ b/crates/relayer/src/light_client/tendermint.rs @@ -20,23 +20,21 @@ use tendermint_light_client::{ use tendermint_light_client_detector::Divergence; use tendermint_rpc as rpc; -use ibc_relayer_types::{ - clients::ics07_tendermint::{ - header::Header as TmHeader, misbehaviour::Misbehaviour as TmMisbehaviour, - }, - core::{ - ics02_client::{client_type::ClientType, events::UpdateClient, header::downcast_header}, - ics24_host::identifier::ChainId, - }, - downcast, Height as ICSHeight, -}; +use ibc_relayer_types::clients::ics07_tendermint::header::Header as TmHeader; +use ibc_relayer_types::clients::ics07_tendermint::misbehaviour::Misbehaviour as TmMisbehaviour; +use ibc_relayer_types::core::ics02_client::events::UpdateClient; +use ibc_relayer_types::core::ics02_client::header::AnyHeader; +use ibc_relayer_types::core::ics24_host::identifier::ChainId; +use ibc_relayer_types::Height as ICSHeight; + +#[cfg(test)] +use ibc_relayer_types::core::ics02_client::client_type::ClientType; use crate::{ + chain::cosmos::config::CosmosSdkConfig, chain::cosmos::CosmosSdkChain, client_state::AnyClientState, - config::ChainConfig, error::Error, - light_client::AnyHeader, misbehaviour::{AnyMisbehaviour, MisbehaviourEvidence}, }; @@ -139,28 +137,26 @@ impl super::LightClient for LightClient { } ); - let update_header = update.header.as_ref().ok_or_else(|| { + let any_header = update.header.as_ref().ok_or_else(|| { Error::misbehaviour(format!( "missing header in update client event {}", self.chain_id )) })?; - let update_header: &TmHeader = - downcast_header(update_header.as_ref()).ok_or_else(|| { - Error::misbehaviour(format!( - "header type incompatible for chain {}", - self.chain_id - )) - })?; + let update_header: &TmHeader = match any_header { + AnyHeader::Tendermint(header) => Ok(header), + }?; - let client_state = - downcast!(client_state => AnyClientState::Tendermint).ok_or_else(|| { - Error::misbehaviour(format!( - "client type incompatible for chain {}", - self.chain_id - )) - })?; + let client_state = match client_state { + AnyClientState::Tendermint(client_state) => Ok(client_state), + + #[cfg(test)] + _ => Err(Error::misbehaviour(format!( + "client type incompatible for chain {}", + self.chain_id + ))), + }?; let next_validators = self .io @@ -207,13 +203,18 @@ impl super::LightClient for LightClient { challenging_block, })) => { warn!("misbehavior detected, reporting evidence to RPC witness node and primary chain"); + debug!("evidence: {evidence:#?}"); + debug!("challenging block: {challenging_block:#?}"); + + warn!("waiting 5 seconds before reporting evidence to RPC witness node"); + std::thread::sleep(Duration::from_secs(5)); match detector::report_evidence( self.io.rpc_client().clone(), evidence.against_primary, ) { Ok(hash) => warn!("evidence reported to RPC witness node with hash: {hash}"), - Err(e) => error!("failed to report evidence to RPC witness node: {}", e), + Err(e) => error!("failed to report evidence to RPC witness node: {e}"), } let target_block = self.fetch(update_header.height())?; @@ -267,7 +268,10 @@ fn io_for_addr( } impl LightClient { - pub fn from_config(config: &ChainConfig, peer_id: PeerId) -> Result { + pub fn from_cosmos_sdk_config( + config: &CosmosSdkConfig, + peer_id: PeerId, + ) -> Result { let live_io = io_for_addr(&config.rpc_addr, peer_id, Some(config.rpc_timeout))?; let io = match &config.genesis_restart { @@ -310,10 +314,15 @@ impl LightClient { let verifier = ProdVerifier::default(); let scheduler = components::scheduler::basic_bisecting_schedule; - let client_state = - downcast!(client_state => AnyClientState::Tendermint).ok_or_else(|| { - Error::client_type_mismatch(ClientType::Tendermint, client_state.client_type()) - })?; + let client_state = match client_state { + AnyClientState::Tendermint(client_state) => Ok(client_state), + + #[cfg(test)] + _ => Err(Error::client_type_mismatch( + ClientType::Tendermint, + client_state.client_type(), + )), + }?; Ok(TmLightClient::new( self.peer_id, diff --git a/crates/relayer/src/link/error.rs b/crates/relayer/src/link/error.rs index 697c8cf994..adf8142ec8 100644 --- a/crates/relayer/src/link/error.rs +++ b/crates/relayer/src/link/error.rs @@ -152,16 +152,27 @@ define_error! { } impl HasExpiredOrFrozenError for LinkErrorDetail { - fn is_expired_or_frozen_error(&self) -> bool { + fn is_frozen_error(&self) -> bool { match self { - Self::Client(e) => e.source.is_expired_or_frozen_error(), + Self::Client(e) => e.source.is_frozen_error(), + _ => false, + } + } + + fn is_expired_error(&self) -> bool { + match self { + Self::Client(e) => e.source.is_expired_error(), _ => false, } } } impl HasExpiredOrFrozenError for LinkError { - fn is_expired_or_frozen_error(&self) -> bool { - self.detail().is_expired_or_frozen_error() + fn is_frozen_error(&self) -> bool { + self.detail().is_frozen_error() + } + + fn is_expired_error(&self) -> bool { + self.detail().is_expired_error() } } diff --git a/crates/relayer/src/link/relay_path.rs b/crates/relayer/src/link/relay_path.rs index dc01a71f70..b055bf1268 100644 --- a/crates/relayer/src/link/relay_path.rs +++ b/crates/relayer/src/link/relay_path.rs @@ -294,7 +294,7 @@ impl RelayPath { .src_chain() .config() .map_err(LinkError::relayer)? - .max_block_time) + .max_block_time()) } pub(crate) fn dst_max_block_time(&self) -> Result { @@ -302,7 +302,7 @@ impl RelayPath { .dst_chain() .config() .map_err(LinkError::relayer)? - .max_block_time) + .max_block_time()) } fn unordered_channel(&self) -> bool { diff --git a/crates/relayer/src/misbehaviour.rs b/crates/relayer/src/misbehaviour.rs index 3b0c95b9a3..4d11974149 100644 --- a/crates/relayer/src/misbehaviour.rs +++ b/crates/relayer/src/misbehaviour.rs @@ -1,19 +1,20 @@ -use ibc_proto::{google::protobuf::Any, protobuf::Protobuf}; +use serde::{Deserialize, Serialize}; + +use ibc_proto::google::protobuf::Any; use ibc_relayer_types::clients::ics07_tendermint::misbehaviour::{ Misbehaviour as TmMisbehaviour, TENDERMINT_MISBEHAVIOR_TYPE_URL, }; -use ibc_relayer_types::core::{ - ics02_client::{error::Error, misbehaviour::Misbehaviour}, - ics24_host::identifier::ClientId, -}; +use ibc_relayer_types::core::ics02_client::error::Error; +use ibc_relayer_types::core::ics02_client::header::AnyHeader; +use ibc_relayer_types::core::ics02_client::misbehaviour::Misbehaviour; +use ibc_relayer_types::core::ics24_host::identifier::ClientId; +use ibc_relayer_types::Height; +use tendermint_proto::Protobuf; + #[cfg(test)] use ibc_relayer_types::mock::misbehaviour::Misbehaviour as MockMisbehaviour; #[cfg(test)] use ibc_relayer_types::mock::misbehaviour::MOCK_MISBEHAVIOUR_TYPE_URL; -use ibc_relayer_types::Height; -use serde::{Deserialize, Serialize}; - -use crate::light_client::AnyHeader; #[derive(Clone, Debug, PartialEq, Eq)] pub struct MisbehaviourEvidence { diff --git a/crates/relayer/src/object.rs b/crates/relayer/src/object.rs index 9f7349734d..285856d041 100644 --- a/crates/relayer/src/object.rs +++ b/crates/relayer/src/object.rs @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize}; use ibc_relayer_types::applications::ics29_fee::events::IncentivizedPacket; use ibc_relayer_types::core::{ - ics02_client::{client_state::ClientState, events::UpdateClient}, + ics02_client::events::UpdateClient, ics03_connection::events::Attributes as ConnectionAttributes, ics04_channel::events::{ Attributes, CloseInit, SendPacket, TimeoutPacket, WriteAcknowledgement, diff --git a/crates/relayer/src/rest.rs b/crates/relayer/src/rest.rs index bf46c4678e..8894c58330 100644 --- a/crates/relayer/src/rest.rs +++ b/crates/relayer/src/rest.rs @@ -62,7 +62,7 @@ pub fn process_incoming_requests(config: &Config, channel: &Receiver) -> Option< trace!("GetChains"); reply_to - .send(Ok(config.chains.iter().map(|c| c.id.clone()).collect())) + .send(Ok(config.chains.iter().map(|c| c.id().clone()).collect())) .unwrap_or_else(|e| error!("error replying to a REST request {}", e)); } diff --git a/crates/relayer/src/spawn.rs b/crates/relayer/src/spawn.rs index f71a65eb70..113ac1f6a7 100644 --- a/crates/relayer/src/spawn.rs +++ b/crates/relayer/src/spawn.rs @@ -6,8 +6,8 @@ use tokio::runtime::Runtime as TokioRuntime; use ibc_relayer_types::core::ics24_host::identifier::ChainId; use crate::{ - chain::{cosmos::CosmosSdkChain, handle::ChainHandle, runtime::ChainRuntime, ChainType}, - config::Config, + chain::{cosmos::CosmosSdkChain, handle::ChainHandle, runtime::ChainRuntime}, + config::{ChainConfig, Config}, error::Error as RelayerError, }; @@ -52,8 +52,36 @@ pub fn spawn_chain_runtime( .cloned() .ok_or_else(|| SpawnError::missing_chain_config(chain_id.clone()))?; - let handle = match chain_config.r#type { - ChainType::CosmosSdk => ChainRuntime::::spawn::(chain_config, rt), + spawn_chain_runtime_with_config(chain_config, rt) +} + +/// Spawns a chain runtime from the configuration and given a chain identifier, +/// allowing the caller to modify the chain config. +/// Returns the corresponding handle if successful. +pub fn spawn_chain_runtime_with_modified_config( + config: &Config, + chain_id: &ChainId, + rt: Arc, + modify: impl FnOnce(&mut ChainConfig), +) -> Result { + let mut chain_config = config + .find_chain(chain_id) + .cloned() + .ok_or_else(|| SpawnError::missing_chain_config(chain_id.clone()))?; + + modify(&mut chain_config); + + spawn_chain_runtime_with_config(chain_config, rt) +} + +/// Spawns a chain runtime from the given chain configuration +/// Returns the corresponding handle if successful. +pub fn spawn_chain_runtime_with_config( + config: ChainConfig, + rt: Arc, +) -> Result { + let handle = match config { + ChainConfig::CosmosSdk(_) => ChainRuntime::::spawn(config, rt), } .map_err(SpawnError::relayer)?; diff --git a/crates/relayer/src/supervisor.rs b/crates/relayer/src/supervisor.rs index 8a28d07605..cab6f55c82 100644 --- a/crates/relayer/src/supervisor.rs +++ b/crates/relayer/src/supervisor.rs @@ -619,7 +619,7 @@ fn health_check(config: &Config, registry: &mut Registry( let mut subscriptions = Vec::with_capacity(chains.len()); for chain_config in chains { - let chain = match registry.get_or_spawn(&chain_config.id) { + let chain = match registry.get_or_spawn(chain_config.id()) { Ok(chain) => chain, Err(e) => { error!( "failed to spawn chain runtime for {}: {}", - chain_config.id, e + chain_config.id(), + e ); continue; @@ -667,7 +668,8 @@ fn init_subscriptions( Ok(subscription) => subscriptions.push((chain, subscription)), Err(e) => error!( "failed to subscribe to events of {}: {}", - chain_config.id, e + chain_config.id(), + e ), } } diff --git a/crates/relayer/src/supervisor/client_state_filter.rs b/crates/relayer/src/supervisor/client_state_filter.rs index 0203b563f4..87133e89b7 100644 --- a/crates/relayer/src/supervisor/client_state_filter.rs +++ b/crates/relayer/src/supervisor/client_state_filter.rs @@ -4,7 +4,6 @@ use flex_error::define_error; use ibc_relayer_types::core::ics02_client::trust_threshold::TrustThreshold; use tracing::{debug, trace}; -use ibc_relayer_types::core::ics02_client::client_state::ClientState; use ibc_relayer_types::core::ics03_connection::connection::ConnectionEnd; use ibc_relayer_types::core::ics04_channel::error::Error as ChannelError; use ibc_relayer_types::core::ics24_host::identifier::{ diff --git a/crates/relayer/src/supervisor/scan.rs b/crates/relayer/src/supervisor/scan.rs index 1b4cf705e2..d5dd77d364 100644 --- a/crates/relayer/src/supervisor/scan.rs +++ b/crates/relayer/src/supervisor/scan.rs @@ -5,7 +5,6 @@ use itertools::Itertools; use tracing::{debug, error, error_span, info, warn}; use ibc_relayer_types::core::{ - ics02_client::client_state::ClientState, ics03_connection::connection::{IdentifiedConnectionEnd, State as ConnectionState}, ics04_channel::{ channel::{IdentifiedChannelEnd, State as ChannelState}, @@ -302,14 +301,14 @@ impl<'a, Chain: ChainHandle> ChainScanner<'a, Chain> { } pub fn scan_chain(&mut self, chain_config: &ChainConfig) -> Result { - let span = error_span!("scan.chain", chain = %chain_config.id); + let span = error_span!("scan.chain", chain = %chain_config.id()); let _guard = span.enter(); info!("scanning chain..."); - telemetry!(init_per_chain, &chain_config.id); + telemetry!(init_per_chain, chain_config.id()); - let chain = match self.registry.get_or_spawn(&chain_config.id) { + let chain = match self.registry.get_or_spawn(chain_config.id()) { Ok(chain_handle) => chain_handle, Err(e) => { error!( @@ -321,7 +320,7 @@ impl<'a, Chain: ChainHandle> ChainScanner<'a, Chain> { } }; - let mut scan = ChainScan::new(chain_config.id.clone()); + let mut scan = ChainScan::new(chain_config.id().clone()); match self.use_allow_list(chain_config) { Some(spec) if self.scan_mode == ScanMode::Auto => { @@ -589,7 +588,7 @@ impl<'a, Chain: ChainHandle> ChainScanner<'a, Chain> { return None; } - match chain_config.packet_filter.channel_policy { + match chain_config.packet_filter().channel_policy { ChannelPolicy::Allow(ref filters) if filters.is_exact() => Some(filters), _ => None, } diff --git a/crates/relayer/src/supervisor/spawn.rs b/crates/relayer/src/supervisor/spawn.rs index c7ffd2a240..b1b608875c 100644 --- a/crates/relayer/src/supervisor/spawn.rs +++ b/crates/relayer/src/supervisor/spawn.rs @@ -1,7 +1,7 @@ use tracing::{error, info}; use ibc_relayer_types::core::{ - ics02_client::client_state::ClientState, ics03_connection::connection::IdentifiedConnectionEnd, + ics03_connection::connection::IdentifiedConnectionEnd, ics04_channel::channel::State as ChannelState, }; diff --git a/crates/relayer/src/upgrade_chain.rs b/crates/relayer/src/upgrade_chain.rs index d885fa5a0e..8da417e8e0 100644 --- a/crates/relayer/src/upgrade_chain.rs +++ b/crates/relayer/src/upgrade_chain.rs @@ -109,7 +109,7 @@ pub fn build_and_send_ibc_upgrade_proposal( client_state.upgrade( upgraded_client_latest_height, - &upgrade_options, + upgrade_options, opts.upgraded_chain_id.clone(), ); diff --git a/crates/relayer/src/worker.rs b/crates/relayer/src/worker.rs index 571be7792a..aceef04eba 100644 --- a/crates/relayer/src/worker.rs +++ b/crates/relayer/src/worker.rs @@ -132,12 +132,14 @@ pub fn spawn_worker_tasks( let link = Arc::new(Mutex::new(link)); let resubmit = Resubmit::from_clear_interval(packets_config.clear_interval); - let src_chain_config = - config.chains.iter().find(|chain| chain.id == chains.a.id()); + let src_chain_config = config + .chains + .iter() + .find(|chain| *chain.id() == chains.a.id()); let fee_filter = match src_chain_config { Some(chain_config) => chain_config - .packet_filter + .packet_filter() .min_fees .iter() .find(|(channel, _)| channel.matches(&path.src_channel_id)) diff --git a/crates/relayer/src/worker/channel.rs b/crates/relayer/src/worker/channel.rs index a6204a3df4..df80e9252b 100644 --- a/crates/relayer/src/worker/channel.rs +++ b/crates/relayer/src/worker/channel.rs @@ -19,11 +19,11 @@ fn max_block_times( ) -> Duration { let a_block_time = match chains.a.config() { Err(_e) => Duration::from_millis(500), - Ok(config) => config.max_block_time, + Ok(config) => config.max_block_time(), }; let b_block_time = match chains.b.config() { Err(_e) => Duration::from_millis(500), - Ok(config) => config.max_block_time, + Ok(config) => config.max_block_time(), }; a_block_time.max(b_block_time) } diff --git a/crates/relayer/tests/config/fixtures/relayer_conf_example.toml b/crates/relayer/tests/config/fixtures/relayer_conf_example.toml index ea41a2888f..3665bb595f 100644 --- a/crates/relayer/tests/config/fixtures/relayer_conf_example.toml +++ b/crates/relayer/tests/config/fixtures/relayer_conf_example.toml @@ -21,6 +21,7 @@ clear_on_start = true tx_confirmation = true [[chains]] +type = "CosmosSdk" id = 'chain_A' rpc_addr = 'http://127.0.0.1:26657' grpc_addr = 'http://127.0.0.1:9090' @@ -46,6 +47,7 @@ list = [ ] [[chains]] +type = "CosmosSdk" id = 'chain_B' rpc_addr = 'http://127.0.0.1:26557' grpc_addr = 'http://127.0.0.1:9090' diff --git a/crates/relayer/tests/config/fixtures/relayer_conf_example_decoding_size.toml b/crates/relayer/tests/config/fixtures/relayer_conf_example_decoding_size.toml index 6df007f2f7..254b603ad1 100644 --- a/crates/relayer/tests/config/fixtures/relayer_conf_example_decoding_size.toml +++ b/crates/relayer/tests/config/fixtures/relayer_conf_example_decoding_size.toml @@ -21,6 +21,7 @@ clear_on_start = true tx_confirmation = true [[chains]] +type = "CosmosSdk" id = 'chain_A' rpc_addr = 'http://127.0.0.1:26657' grpc_addr = 'http://127.0.0.1:9090' @@ -40,6 +41,7 @@ trust_threshold = { numerator = '1', denominator = '3' } address_type = { derivation = 'cosmos' } [[chains]] +type = "CosmosSdk" id = 'chain_B' rpc_addr = 'http://127.0.0.1:26557' grpc_addr = 'http://127.0.0.1:9090' diff --git a/crates/relayer/tests/config/fixtures/relayer_conf_example_fee_filter.toml b/crates/relayer/tests/config/fixtures/relayer_conf_example_fee_filter.toml index 60a0cc7e0c..f85cca1ca7 100644 --- a/crates/relayer/tests/config/fixtures/relayer_conf_example_fee_filter.toml +++ b/crates/relayer/tests/config/fixtures/relayer_conf_example_fee_filter.toml @@ -21,6 +21,7 @@ clear_on_start = true tx_confirmation = true [[chains]] +type = "CosmosSdk" id = 'chain_A' rpc_addr = 'http://127.0.0.1:26657' grpc_addr = 'http://127.0.0.1:9090' @@ -52,6 +53,7 @@ recv = [ { amount = 20, denom = 'stake' }, { amount = 10, denom = 'uatom' } ] recv = [ { amount = 0 }] [[chains]] +type = "CosmosSdk" id = 'chain_B' rpc_addr = 'http://127.0.0.1:26557' grpc_addr = 'http://127.0.0.1:9090' diff --git a/crates/relayer/tests/config/fixtures/relayer_conf_example_invalid_telemetry.toml b/crates/relayer/tests/config/fixtures/relayer_conf_example_invalid_telemetry.toml index 3e44c53a7d..29acbcf517 100644 --- a/crates/relayer/tests/config/fixtures/relayer_conf_example_invalid_telemetry.toml +++ b/crates/relayer/tests/config/fixtures/relayer_conf_example_invalid_telemetry.toml @@ -30,6 +30,7 @@ latency_submitted = { start = 5000, end = 1000, buckets = 10 } # start can't be latency_confirmed = { start = 5000, end = 10000, buckets = 10 } [[chains]] +type = "CosmosSdk" id = 'chain_A' rpc_addr = 'http://127.0.0.1:26657' grpc_addr = 'http://127.0.0.1:9090' @@ -55,6 +56,7 @@ list = [ ] [[chains]] +type = "CosmosSdk" id = 'chain_B' rpc_addr = 'http://127.0.0.1:26557' grpc_addr = 'http://127.0.0.1:9090' diff --git a/crates/relayer/tests/config/fixtures/relayer_conf_example_valid_telemetry.toml b/crates/relayer/tests/config/fixtures/relayer_conf_example_valid_telemetry.toml index ca0ae487ec..5e6111e61d 100644 --- a/crates/relayer/tests/config/fixtures/relayer_conf_example_valid_telemetry.toml +++ b/crates/relayer/tests/config/fixtures/relayer_conf_example_valid_telemetry.toml @@ -30,6 +30,7 @@ latency_submitted = { start = 5000, end = 10000, buckets = 10 } latency_confirmed = { start = 5000, end = 10000, buckets = 10 } [[chains]] +type = "CosmosSdk" id = 'chain_A' rpc_addr = 'http://127.0.0.1:26657' grpc_addr = 'http://127.0.0.1:9090' @@ -55,6 +56,7 @@ list = [ ] [[chains]] +type = "CosmosSdk" id = 'chain_B' rpc_addr = 'http://127.0.0.1:26557' grpc_addr = 'http://127.0.0.1:9090' diff --git a/crates/telemetry/Cargo.toml b/crates/telemetry/Cargo.toml index d519b0224c..524831d48d 100644 --- a/crates/telemetry/Cargo.toml +++ b/crates/telemetry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ibc-telemetry" -version = "0.25.0" +version = "0.26.0" edition = "2021" license = "Apache-2.0" readme = "README.md" @@ -13,13 +13,13 @@ description = """ """ [dependencies] -ibc-relayer-types = { version = "0.25.0", path = "../relayer-types" } +ibc-relayer-types = { version = "0.26.0", path = "../relayer-types" } once_cell = "1.17.0" opentelemetry = { version = "0.19.0", features = ["metrics"] } opentelemetry-prometheus = "0.12.0" prometheus = "0.13.2" -moka = "0.11.3" +moka = { version = "0.12.0", features = ["sync"] } dashmap = "5.4.0" serde_json = "1.0.94" serde = "1.0.166" diff --git a/flake.lock b/flake.lock index 6c1750e11d..bfe6dd2ef7 100644 --- a/flake.lock +++ b/flake.lock @@ -54,17 +54,34 @@ "centauri-src": { "flake": false, "locked": { - "lastModified": 1692209286, - "narHash": "sha256-fabsZyaSCnWnhvG9nO8y39t85u+MZNyEKzU+0fSueLM=", + "lastModified": 1697027127, + "narHash": "sha256-zdEJr4VfwKq20rGx7JZYV7cnz5APwnPSMJrjX9S/bT8=", "owner": "dzmitry-lahoda-forks", "repo": "composable-centauri", - "rev": "9fa53d8b47d17219d1270146a146e4e386bc2a29", + "rev": "9a296e3dcca3ff390dd5622ab3cfbdfa0b68d2e9", "type": "github" }, "original": { "owner": "dzmitry-lahoda-forks", "repo": "composable-centauri", - "rev": "9fa53d8b47d17219d1270146a146e4e386bc2a29", + "rev": "9a296e3dcca3ff390dd5622ab3cfbdfa0b68d2e9", + "type": "github" + } + }, + "cometbft-src": { + "flake": false, + "locked": { + "lastModified": 1694550324, + "narHash": "sha256-G5gchJMn/BFzwYx8/ikPDL5fS/TuFIBF4DKJbkalp/M=", + "owner": "cometbft", + "repo": "cometbft", + "rev": "66a5a9da9f7a3306f382eb9142ccb9c9f7997d3f", + "type": "github" + }, + "original": { + "owner": "cometbft", + "ref": "v0.38.0", + "repo": "cometbft", "type": "github" } }, @@ -74,6 +91,7 @@ "apalache-src": "apalache-src", "beaker-src": "beaker-src", "centauri-src": "centauri-src", + "cometbft-src": "cometbft-src", "cosmos-sdk-src": "cosmos-sdk-src", "cosmwasm-src": "cosmwasm-src", "crescent-src": "crescent-src", @@ -136,15 +154,16 @@ "wasmvm_1_beta7-src": "wasmvm_1_beta7-src" }, "locked": { - "lastModified": 1697035289, - "narHash": "sha256-2yPPi/n4IrKZ0Y0BwPSmHGP5UJoY5u5XY6BnKxsuGnc=", + "lastModified": 1697211608, + "narHash": "sha256-YlzCO80psDkP3hGNaXHMq3K8LfTldUZt3K/hALV8j+g=", "owner": "informalsystems", "repo": "cosmos.nix", - "rev": "e26774d7889a508ad3ac021a886bc6b8cf11cf7e", + "rev": "07651f41e38276acd7e8c4f20519f6c4cbf00f7b", "type": "github" }, "original": { "owner": "informalsystems", + "ref": "update-ics", "repo": "cosmos.nix", "type": "github" } @@ -716,16 +735,16 @@ "interchain-security-src": { "flake": false, "locked": { - "lastModified": 1662985265, - "narHash": "sha256-MhH5R1eEKel8nX1UIw4PAsSTPraP7ivrPU/+StqaD6U=", + "lastModified": 1694449275, + "narHash": "sha256-yLB2utj3hSB4jw/fc/TJhDcybzZJ+soc8tZlL4jxtk8=", "owner": "cosmos", "repo": "interchain-security", - "rev": "1162655c89221588d4b440717b2ca1c65170aec2", + "rev": "c881a1aad37f2f8041c913468602edaf69fef9bf", "type": "github" }, "original": { "owner": "cosmos", - "ref": "v0.1.4", + "ref": "feat/ics-misbehaviour-handling", "repo": "interchain-security", "type": "github" } @@ -896,11 +915,11 @@ }, "nixpkgs_4": { "locked": { - "lastModified": 1696757521, - "narHash": "sha256-cfgtLNCBLFx2qOzRLI6DHfqTdfWI+UbvsKYa3b3fvaA=", + "lastModified": 1697009197, + "narHash": "sha256-viVRhBTFT8fPJTb1N3brQIpFZnttmwo3JVKNuWRVc3s=", "owner": "nixos", "repo": "nixpkgs", - "rev": "2646b294a146df2781b1ca49092450e8a32814e1", + "rev": "01441e14af5e29c9d27ace398e6dd0b293e25a54", "type": "github" }, "original": { @@ -913,16 +932,16 @@ "osmosis-src": { "flake": false, "locked": { - "lastModified": 1692886846, - "narHash": "sha256-VdM6hGqcDyCNx7AR8s7SxE3pEMxHiIhCJ7592sDp3uc=", + "lastModified": 1695859760, + "narHash": "sha256-Ad2Z4rzD0HQtnj2aQ4GD6ic5sxOHVPsaW4iNKZEDTiw=", "owner": "osmosis-labs", "repo": "osmosis", - "rev": "1c5f25d04f19d6302e0bdd585ba1d7a2cc96e397", + "rev": "38d1d2b748d161fd23f966d88b23b66a63c9a284", "type": "github" }, "original": { "owner": "osmosis-labs", - "ref": "v18.0.0", + "ref": "v19.2.0", "repo": "osmosis", "type": "github" } diff --git a/flake.nix b/flake.nix index 7cadfe5970..5ce8b295ce 100644 --- a/flake.nix +++ b/flake.nix @@ -4,7 +4,7 @@ inputs = { nixpkgs.url = github:nixos/nixpkgs/nixpkgs-unstable; flake-utils.url = github:numtide/flake-utils; - cosmos-nix.url = github:informalsystems/cosmos.nix; + cosmos-nix.url = github:informalsystems/cosmos.nix/update-ics; }; outputs = inputs: let @@ -27,6 +27,7 @@ packages = { inherit (cosmos-nix) + cometbft gaia6-ordered gaia12 osmosis @@ -37,6 +38,7 @@ ibc-go-v5-simapp ibc-go-v6-simapp ibc-go-v7-simapp + interchain-security apalache evmos juno diff --git a/guide/README.md b/guide/README.md index 6d9677da15..53bdf34be5 100644 --- a/guide/README.md +++ b/guide/README.md @@ -10,7 +10,7 @@ mdBook is a utility to create modern online books from Markdown files. This guide should be permanently deployed at its latest stable version at [hermes.informal.systems](https://hermes.informal.systems). -Current version: `v1.6.0`. +Current version: `v1.7.0`. The version of this guide is aligned with the [versioning of the ibc crates](../README.md). diff --git a/guide/src/SUMMARY.md b/guide/src/SUMMARY.md index 3264a2214f..1bf6f93f51 100644 --- a/guide/src/SUMMARY.md +++ b/guide/src/SUMMARY.md @@ -1,6 +1,6 @@ # Summary -# Hermes v1.6.0 +# Hermes v1.7.0 --- - [Introduction](./index.md) diff --git a/guide/src/documentation/configuration/configure-hermes.md b/guide/src/documentation/configuration/configure-hermes.md index 1527c9ed9d..776322ac7d 100644 --- a/guide/src/documentation/configuration/configure-hermes.md +++ b/guide/src/documentation/configuration/configure-hermes.md @@ -160,16 +160,17 @@ event_source = { mode = 'push', url = 'wss://hello:world@mydomain.com:26657/webs ## Configuring Support for Wasm Relaying -As of version 1.6.0, Hermes supports the relaying of wasm messages natively. This is facilitated by configuring +As of version 1.7.0, Hermes supports the relaying of wasm messages natively. This is facilitated by configuring Hermes to use pull-based relaying by polling for IBC events via the `/block_results` RPC endpoint. Set -the `event_source` parameter to pull mode in `config.toml`: +the `event_source` parameter to pull mode in `config.toml` like so: ```toml -event_source = 'poll' +# When specified like this, Hermes defaults to a poll interval of 1 second +event_source = { mode = 'pull' } ``` The default interval at which Hermes polls the RPC endpoint is 1 second. If you need to change the interval, -you can do so like this: +you can specify it like so: ```toml event_source = { mode = 'pull', interval = '2s' } diff --git a/guide/src/templates/commands/hermes/clear/packets_1.md b/guide/src/templates/commands/hermes/clear/packets_1.md index 4efdb9b81d..2799fe42d1 100644 --- a/guide/src/templates/commands/hermes/clear/packets_1.md +++ b/guide/src/templates/commands/hermes/clear/packets_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] clear packets[[#OPTIONS]] --chain [[#CHAIN_ID]] --port [[#PORT_ID]] --channel [[#CHANNEL_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] clear packets[[#OPTIONS]] --chain [[#CHAIN_ID]] --port [[#PORT_ID]] --channel [[#CHANNEL_ID]] diff --git a/guide/src/templates/commands/hermes/clear_1.md b/guide/src/templates/commands/hermes/clear_1.md index 5df52fc125..7b516a5a57 100644 --- a/guide/src/templates/commands/hermes/clear_1.md +++ b/guide/src/templates/commands/hermes/clear_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] clear [[#SUBCOMMAND]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] clear [[#SUBCOMMAND]] diff --git a/guide/src/templates/commands/hermes/completions_1.md b/guide/src/templates/commands/hermes/completions_1.md index a06d20d797..0e8ee9cd41 100644 --- a/guide/src/templates/commands/hermes/completions_1.md +++ b/guide/src/templates/commands/hermes/completions_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] completions --shell [[#SHELL]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] completions --shell [[#SHELL]] diff --git a/guide/src/templates/commands/hermes/config/auto_1.md b/guide/src/templates/commands/hermes/config/auto_1.md index 6886505229..c7c4e932b0 100644 --- a/guide/src/templates/commands/hermes/config/auto_1.md +++ b/guide/src/templates/commands/hermes/config/auto_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] config auto[[#OPTIONS]] --output [[#PATH]] --chains [[#CHAIN_NAME:OPTIONAL_KEY_NAME]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] config auto[[#OPTIONS]] --output [[#PATH]] --chains [[#CHAIN_NAME:OPTIONAL_KEY_NAME]] diff --git a/guide/src/templates/commands/hermes/config/validate_1.md b/guide/src/templates/commands/hermes/config/validate_1.md index f7ca4895e6..2c10ddddee 100644 --- a/guide/src/templates/commands/hermes/config/validate_1.md +++ b/guide/src/templates/commands/hermes/config/validate_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] config validate \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] config validate diff --git a/guide/src/templates/commands/hermes/config_1.md b/guide/src/templates/commands/hermes/config_1.md index c9bf9b3a06..c0df196bd0 100644 --- a/guide/src/templates/commands/hermes/config_1.md +++ b/guide/src/templates/commands/hermes/config_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] config [[#SUBCOMMAND]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] config [[#SUBCOMMAND]] diff --git a/guide/src/templates/commands/hermes/create/channel_1.md b/guide/src/templates/commands/hermes/create/channel_1.md index 91966e911e..f3c0134625 100644 --- a/guide/src/templates/commands/hermes/create/channel_1.md +++ b/guide/src/templates/commands/hermes/create/channel_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] create channel[[#OPTIONS]] --a-chain [[#A_CHAIN_ID]] --a-connection [[#A_CONNECTION_ID]] --a-port [[#A_PORT_ID]] --b-port [[#B_PORT_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] create channel[[#OPTIONS]] --a-chain [[#A_CHAIN_ID]] --a-connection [[#A_CONNECTION_ID]] --a-port [[#A_PORT_ID]] --b-port [[#B_PORT_ID]] diff --git a/guide/src/templates/commands/hermes/create/channel_2.md b/guide/src/templates/commands/hermes/create/channel_2.md index 57ac622e56..51384fe2d7 100644 --- a/guide/src/templates/commands/hermes/create/channel_2.md +++ b/guide/src/templates/commands/hermes/create/channel_2.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] create channel[[#OPTIONS]] --a-chain [[#A_CHAIN_ID]] --b-chain [[#B_CHAIN_ID]] --a-port [[#A_PORT_ID]] --b-port [[#B_PORT_ID]] --new-client-connection \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] create channel[[#OPTIONS]] --a-chain [[#A_CHAIN_ID]] --b-chain [[#B_CHAIN_ID]] --a-port [[#A_PORT_ID]] --b-port [[#B_PORT_ID]] --new-client-connection diff --git a/guide/src/templates/commands/hermes/create/client_1.md b/guide/src/templates/commands/hermes/create/client_1.md index b52b9d7cff..0a9015c42d 100644 --- a/guide/src/templates/commands/hermes/create/client_1.md +++ b/guide/src/templates/commands/hermes/create/client_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] create client[[#OPTIONS]] --host-chain [[#HOST_CHAIN_ID]] --reference-chain [[#REFERENCE_CHAIN_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] create client[[#OPTIONS]] --host-chain [[#HOST_CHAIN_ID]] --reference-chain [[#REFERENCE_CHAIN_ID]] diff --git a/guide/src/templates/commands/hermes/create/connection_1.md b/guide/src/templates/commands/hermes/create/connection_1.md index 019f5e2485..51c0d41fa7 100644 --- a/guide/src/templates/commands/hermes/create/connection_1.md +++ b/guide/src/templates/commands/hermes/create/connection_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] create connection[[#OPTIONS]] --a-chain [[#A_CHAIN_ID]] --b-chain [[#B_CHAIN_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] create connection[[#OPTIONS]] --a-chain [[#A_CHAIN_ID]] --b-chain [[#B_CHAIN_ID]] diff --git a/guide/src/templates/commands/hermes/create/connection_2.md b/guide/src/templates/commands/hermes/create/connection_2.md index 40d4f5ebc5..3035a7ec2b 100644 --- a/guide/src/templates/commands/hermes/create/connection_2.md +++ b/guide/src/templates/commands/hermes/create/connection_2.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] create connection[[#OPTIONS]] --a-chain [[#A_CHAIN_ID]] --a-client [[#A_CLIENT_ID]] --b-client [[#B_CLIENT_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] create connection[[#OPTIONS]] --a-chain [[#A_CHAIN_ID]] --a-client [[#A_CLIENT_ID]] --b-client [[#B_CLIENT_ID]] diff --git a/guide/src/templates/commands/hermes/create_1.md b/guide/src/templates/commands/hermes/create_1.md index 3fe37680fb..24f9bef0f4 100644 --- a/guide/src/templates/commands/hermes/create_1.md +++ b/guide/src/templates/commands/hermes/create_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] create [[#SUBCOMMAND]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] create [[#SUBCOMMAND]] diff --git a/guide/src/templates/commands/hermes/evidence_1.md b/guide/src/templates/commands/hermes/evidence_1.md new file mode 100644 index 0000000000..4db7cc285b --- /dev/null +++ b/guide/src/templates/commands/hermes/evidence_1.md @@ -0,0 +1 @@ +[[#BINARY hermes]][[#GLOBALOPTIONS]] evidence[[#OPTIONS]] --chain [[#CHAIN_ID]] \ No newline at end of file diff --git a/guide/src/templates/commands/hermes/fee/register-counterparty-payee_1.md b/guide/src/templates/commands/hermes/fee/register-counterparty-payee_1.md index 16ba2d7833..efe09b308e 100644 --- a/guide/src/templates/commands/hermes/fee/register-counterparty-payee_1.md +++ b/guide/src/templates/commands/hermes/fee/register-counterparty-payee_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] fee register-counterparty-payee --chain [[#CHAIN_ID]] --channel [[#CHANNEL_ID]] --port [[#PORT_ID]] --counterparty-payee [[#COUNTERPARTY_PAYEE_ADDRESS]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] fee register-counterparty-payee --chain [[#CHAIN_ID]] --channel [[#CHANNEL_ID]] --port [[#PORT_ID]] --counterparty-payee [[#COUNTERPARTY_PAYEE_ADDRESS]] diff --git a/guide/src/templates/commands/hermes/fee/register-payee_1.md b/guide/src/templates/commands/hermes/fee/register-payee_1.md index aa6093733f..115f865185 100644 --- a/guide/src/templates/commands/hermes/fee/register-payee_1.md +++ b/guide/src/templates/commands/hermes/fee/register-payee_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] fee register-payee --chain [[#CHAIN_ID]] --channel [[#CHANNEL_ID]] --port [[#PORT_ID]] --payee [[#PAYEE_ADDRESS]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] fee register-payee --chain [[#CHAIN_ID]] --channel [[#CHANNEL_ID]] --port [[#PORT_ID]] --payee [[#PAYEE_ADDRESS]] diff --git a/guide/src/templates/commands/hermes/fee/transfer_1.md b/guide/src/templates/commands/hermes/fee/transfer_1.md index ebd0e125c2..b45b830f42 100644 --- a/guide/src/templates/commands/hermes/fee/transfer_1.md +++ b/guide/src/templates/commands/hermes/fee/transfer_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] fee transfer[[#OPTIONS]] --dst-chain [[#DST_CHAIN_ID]] --src-chain [[#SRC_CHAIN_ID]] --src-port [[#SRC_PORT_ID]] --src-channel [[#SRC_CHANNEL_ID]] --amount [[#AMOUNT]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] fee transfer[[#OPTIONS]] --dst-chain [[#DST_CHAIN_ID]] --src-chain [[#SRC_CHAIN_ID]] --src-port [[#SRC_PORT_ID]] --src-channel [[#SRC_CHANNEL_ID]] --amount [[#AMOUNT]] diff --git a/guide/src/templates/commands/hermes/fee_1.md b/guide/src/templates/commands/hermes/fee_1.md index 0020a68d1c..c1d759e6ca 100644 --- a/guide/src/templates/commands/hermes/fee_1.md +++ b/guide/src/templates/commands/hermes/fee_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] fee [[#SUBCOMMAND]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] fee [[#SUBCOMMAND]] diff --git a/guide/src/templates/commands/hermes/health-check_1.md b/guide/src/templates/commands/hermes/health-check_1.md index 3d9d581618..7db1cbe8d6 100644 --- a/guide/src/templates/commands/hermes/health-check_1.md +++ b/guide/src/templates/commands/hermes/health-check_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] health-check \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] health-check diff --git a/guide/src/templates/commands/hermes/help_1.md b/guide/src/templates/commands/hermes/help_1.md index 9753c06c15..6a007e56db 100644 --- a/guide/src/templates/commands/hermes/help_1.md +++ b/guide/src/templates/commands/hermes/help_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]][[#OPTIONS]][[#SUBCOMMAND]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]][[#OPTIONS]][[#SUBCOMMAND]] diff --git a/guide/src/templates/commands/hermes/keys/add_1.md b/guide/src/templates/commands/hermes/keys/add_1.md index 2231677013..087039e1fa 100644 --- a/guide/src/templates/commands/hermes/keys/add_1.md +++ b/guide/src/templates/commands/hermes/keys/add_1.md @@ -1 +1 @@ -Add a key from a Comet keyring file: \ No newline at end of file +Add a key from a Comet keyring file: diff --git a/guide/src/templates/commands/hermes/keys/add_2.md b/guide/src/templates/commands/hermes/keys/add_2.md index 8cec138867..9a4899358b 100644 --- a/guide/src/templates/commands/hermes/keys/add_2.md +++ b/guide/src/templates/commands/hermes/keys/add_2.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] keys add[[#OPTIONS]] --chain [[#CHAIN_ID]] --key-file [[#KEY_FILE]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] keys add[[#OPTIONS]] --chain [[#CHAIN_ID]] --key-file [[#KEY_FILE]] diff --git a/guide/src/templates/commands/hermes/keys/add_3.md b/guide/src/templates/commands/hermes/keys/add_3.md index 7fb69f8bb9..3bb7522ed4 100644 --- a/guide/src/templates/commands/hermes/keys/add_3.md +++ b/guide/src/templates/commands/hermes/keys/add_3.md @@ -1 +1 @@ -Add a key from a file containing its mnemonic: \ No newline at end of file +Add a key from a file containing its mnemonic: diff --git a/guide/src/templates/commands/hermes/keys/add_4.md b/guide/src/templates/commands/hermes/keys/add_4.md index 75c51f8afb..fbb33ef2b7 100644 --- a/guide/src/templates/commands/hermes/keys/add_4.md +++ b/guide/src/templates/commands/hermes/keys/add_4.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] keys add[[#OPTIONS]] --chain [[#CHAIN_ID]] --mnemonic-file [[#MNEMONIC_FILE]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] keys add[[#OPTIONS]] --chain [[#CHAIN_ID]] --mnemonic-file [[#MNEMONIC_FILE]] diff --git a/guide/src/templates/commands/hermes/keys/add_5.md b/guide/src/templates/commands/hermes/keys/add_5.md index 4c46acd7fd..e44c2b922b 100644 --- a/guide/src/templates/commands/hermes/keys/add_5.md +++ b/guide/src/templates/commands/hermes/keys/add_5.md @@ -1 +1 @@ -On flake.nix platforms, both flags also accept `/dev/stdin` as a value, which will read the key or the mnemonic from stdin. \ No newline at end of file +On flake.nix platforms, both flags also accept `/dev/stdin` as a value, which will read the key or the mnemonic from stdin. diff --git a/guide/src/templates/commands/hermes/keys/balance_1.md b/guide/src/templates/commands/hermes/keys/balance_1.md index c946f3c227..60c9ab52f7 100644 --- a/guide/src/templates/commands/hermes/keys/balance_1.md +++ b/guide/src/templates/commands/hermes/keys/balance_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] keys balance[[#OPTIONS]] --chain [[#CHAIN_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] keys balance[[#OPTIONS]] --chain [[#CHAIN_ID]] diff --git a/guide/src/templates/commands/hermes/keys/delete_1.md b/guide/src/templates/commands/hermes/keys/delete_1.md index 235209dbf6..d3023a493c 100644 --- a/guide/src/templates/commands/hermes/keys/delete_1.md +++ b/guide/src/templates/commands/hermes/keys/delete_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] keys delete --chain [[#CHAIN_ID]] --key-name [[#KEY_NAME]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] keys delete --chain [[#CHAIN_ID]] --key-name [[#KEY_NAME]] diff --git a/guide/src/templates/commands/hermes/keys/delete_2.md b/guide/src/templates/commands/hermes/keys/delete_2.md index e32669c4f3..7c3dba6638 100644 --- a/guide/src/templates/commands/hermes/keys/delete_2.md +++ b/guide/src/templates/commands/hermes/keys/delete_2.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] keys delete --chain [[#CHAIN_ID]] --all \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] keys delete --chain [[#CHAIN_ID]] --all diff --git a/guide/src/templates/commands/hermes/keys/list_1.md b/guide/src/templates/commands/hermes/keys/list_1.md index a1887c6b3e..52a6aa7c6a 100644 --- a/guide/src/templates/commands/hermes/keys/list_1.md +++ b/guide/src/templates/commands/hermes/keys/list_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] keys list --chain [[#CHAIN_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] keys list --chain [[#CHAIN_ID]] diff --git a/guide/src/templates/commands/hermes/keys_1.md b/guide/src/templates/commands/hermes/keys_1.md index 2fa18be15c..d5f2d2416c 100644 --- a/guide/src/templates/commands/hermes/keys_1.md +++ b/guide/src/templates/commands/hermes/keys_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] keys [[#SUBCOMMAND]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] keys [[#SUBCOMMAND]] diff --git a/guide/src/templates/commands/hermes/listen_1.md b/guide/src/templates/commands/hermes/listen_1.md index b596520871..7c040d78a1 100644 --- a/guide/src/templates/commands/hermes/listen_1.md +++ b/guide/src/templates/commands/hermes/listen_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] listen[[#OPTIONS]] --chain [[#CHAIN_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] listen[[#OPTIONS]] --chain [[#CHAIN_ID]] diff --git a/guide/src/templates/commands/hermes/logs/reset_1.md b/guide/src/templates/commands/hermes/logs/reset_1.md index f5ab35bf6d..dadb22dbe0 100644 --- a/guide/src/templates/commands/hermes/logs/reset_1.md +++ b/guide/src/templates/commands/hermes/logs/reset_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] logs reset \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] logs reset diff --git a/guide/src/templates/commands/hermes/logs/set-log-level_1.md b/guide/src/templates/commands/hermes/logs/set-log-level_1.md index 5485b576de..164fe55d1b 100644 --- a/guide/src/templates/commands/hermes/logs/set-log-level_1.md +++ b/guide/src/templates/commands/hermes/logs/set-log-level_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] logs set-log-level[[#OPTIONS]] --log-level [[#LOG_LEVEL]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] logs set-log-level[[#OPTIONS]] --log-level [[#LOG_LEVEL]] diff --git a/guide/src/templates/commands/hermes/logs/set-raw-filter_1.md b/guide/src/templates/commands/hermes/logs/set-raw-filter_1.md index eeabc079e5..53cb0bd24c 100644 --- a/guide/src/templates/commands/hermes/logs/set-raw-filter_1.md +++ b/guide/src/templates/commands/hermes/logs/set-raw-filter_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] logs set-raw-filter --raw-filter [[#RAW_FILTER]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] logs set-raw-filter --raw-filter [[#RAW_FILTER]] diff --git a/guide/src/templates/commands/hermes/logs_1.md b/guide/src/templates/commands/hermes/logs_1.md index fd983789c1..d8377bcf68 100644 --- a/guide/src/templates/commands/hermes/logs_1.md +++ b/guide/src/templates/commands/hermes/logs_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] logs [[#SUBCOMMAND]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] logs [[#SUBCOMMAND]] diff --git a/guide/src/templates/commands/hermes/misbehaviour_1.md b/guide/src/templates/commands/hermes/misbehaviour_1.md index 93118a0269..96a77cba42 100644 --- a/guide/src/templates/commands/hermes/misbehaviour_1.md +++ b/guide/src/templates/commands/hermes/misbehaviour_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] misbehaviour --chain [[#CHAIN_ID]] --client [[#CLIENT_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] misbehaviour --chain [[#CHAIN_ID]] --client [[#CLIENT_ID]] diff --git a/guide/src/templates/commands/hermes/query/channel/client_1.md b/guide/src/templates/commands/hermes/query/channel/client_1.md index 775d1a558c..eb85e91db8 100644 --- a/guide/src/templates/commands/hermes/query/channel/client_1.md +++ b/guide/src/templates/commands/hermes/query/channel/client_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] query channel client --chain [[#CHAIN_ID]] --port [[#PORT_ID]] --channel [[#CHANNEL_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] query channel client --chain [[#CHAIN_ID]] --port [[#PORT_ID]] --channel [[#CHANNEL_ID]] diff --git a/guide/src/templates/commands/hermes/query/channel/end_1.md b/guide/src/templates/commands/hermes/query/channel/end_1.md index 4ae001d634..e6e07b133d 100644 --- a/guide/src/templates/commands/hermes/query/channel/end_1.md +++ b/guide/src/templates/commands/hermes/query/channel/end_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] query channel end[[#OPTIONS]] --chain [[#CHAIN_ID]] --port [[#PORT_ID]] --channel [[#CHANNEL_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] query channel end[[#OPTIONS]] --chain [[#CHAIN_ID]] --port [[#PORT_ID]] --channel [[#CHANNEL_ID]] diff --git a/guide/src/templates/commands/hermes/query/channel/ends_1.md b/guide/src/templates/commands/hermes/query/channel/ends_1.md index fa0bdd8cdc..241db662e6 100644 --- a/guide/src/templates/commands/hermes/query/channel/ends_1.md +++ b/guide/src/templates/commands/hermes/query/channel/ends_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] query channel ends[[#OPTIONS]] --chain [[#CHAIN_ID]] --port [[#PORT_ID]] --channel [[#CHANNEL_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] query channel ends[[#OPTIONS]] --chain [[#CHAIN_ID]] --port [[#PORT_ID]] --channel [[#CHANNEL_ID]] diff --git a/guide/src/templates/commands/hermes/query/channel_1.md b/guide/src/templates/commands/hermes/query/channel_1.md index 56adaeab53..330cf87fee 100644 --- a/guide/src/templates/commands/hermes/query/channel_1.md +++ b/guide/src/templates/commands/hermes/query/channel_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] query channel [[#SUBCOMMAND]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] query channel [[#SUBCOMMAND]] diff --git a/guide/src/templates/commands/hermes/query/channels_1.md b/guide/src/templates/commands/hermes/query/channels_1.md index ca716b9afd..245229e3a7 100644 --- a/guide/src/templates/commands/hermes/query/channels_1.md +++ b/guide/src/templates/commands/hermes/query/channels_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] query channels[[#OPTIONS]] --chain [[#CHAIN_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] query channels[[#OPTIONS]] --chain [[#CHAIN_ID]] diff --git a/guide/src/templates/commands/hermes/query/client/connections_1.md b/guide/src/templates/commands/hermes/query/client/connections_1.md index c424906882..c106c18560 100644 --- a/guide/src/templates/commands/hermes/query/client/connections_1.md +++ b/guide/src/templates/commands/hermes/query/client/connections_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] query client connections[[#OPTIONS]] --chain [[#CHAIN_ID]] --client [[#CLIENT_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] query client connections[[#OPTIONS]] --chain [[#CHAIN_ID]] --client [[#CLIENT_ID]] diff --git a/guide/src/templates/commands/hermes/query/client/consensus_1.md b/guide/src/templates/commands/hermes/query/client/consensus_1.md index 330ee1b64e..66b04bde7c 100644 --- a/guide/src/templates/commands/hermes/query/client/consensus_1.md +++ b/guide/src/templates/commands/hermes/query/client/consensus_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] query client consensus[[#OPTIONS]] --chain [[#CHAIN_ID]] --client [[#CLIENT_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] query client consensus[[#OPTIONS]] --chain [[#CHAIN_ID]] --client [[#CLIENT_ID]] diff --git a/guide/src/templates/commands/hermes/query/client/header_1.md b/guide/src/templates/commands/hermes/query/client/header_1.md index b0738bd191..ab1ba2afbf 100644 --- a/guide/src/templates/commands/hermes/query/client/header_1.md +++ b/guide/src/templates/commands/hermes/query/client/header_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] query client header[[#OPTIONS]] --chain [[#CHAIN_ID]] --client [[#CLIENT_ID]] --consensus-height [[#CONSENSUS_HEIGHT]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] query client header[[#OPTIONS]] --chain [[#CHAIN_ID]] --client [[#CLIENT_ID]] --consensus-height [[#CONSENSUS_HEIGHT]] diff --git a/guide/src/templates/commands/hermes/query/client/state_1.md b/guide/src/templates/commands/hermes/query/client/state_1.md index df51c517ac..372d2d04ec 100644 --- a/guide/src/templates/commands/hermes/query/client/state_1.md +++ b/guide/src/templates/commands/hermes/query/client/state_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] query client state[[#OPTIONS]] --chain [[#CHAIN_ID]] --client [[#CLIENT_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] query client state[[#OPTIONS]] --chain [[#CHAIN_ID]] --client [[#CLIENT_ID]] diff --git a/guide/src/templates/commands/hermes/query/client/status_1.md b/guide/src/templates/commands/hermes/query/client/status_1.md index 7d1ff654ed..b4f56996ed 100644 --- a/guide/src/templates/commands/hermes/query/client/status_1.md +++ b/guide/src/templates/commands/hermes/query/client/status_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] query client status --chain [[#CHAIN_ID]] --client [[#CLIENT_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] query client status --chain [[#CHAIN_ID]] --client [[#CLIENT_ID]] diff --git a/guide/src/templates/commands/hermes/query/client_1.md b/guide/src/templates/commands/hermes/query/client_1.md index 4bab05d621..d2621fa192 100644 --- a/guide/src/templates/commands/hermes/query/client_1.md +++ b/guide/src/templates/commands/hermes/query/client_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] query client [[#SUBCOMMAND]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] query client [[#SUBCOMMAND]] diff --git a/guide/src/templates/commands/hermes/query/clients_1.md b/guide/src/templates/commands/hermes/query/clients_1.md index e8d7359e6a..3daedb2a1e 100644 --- a/guide/src/templates/commands/hermes/query/clients_1.md +++ b/guide/src/templates/commands/hermes/query/clients_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] query clients[[#OPTIONS]] --host-chain [[#HOST_CHAIN_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] query clients[[#OPTIONS]] --host-chain [[#HOST_CHAIN_ID]] diff --git a/guide/src/templates/commands/hermes/query/connection/channels_1.md b/guide/src/templates/commands/hermes/query/connection/channels_1.md index bd25265ff4..6125e9e967 100644 --- a/guide/src/templates/commands/hermes/query/connection/channels_1.md +++ b/guide/src/templates/commands/hermes/query/connection/channels_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] query connection channels --chain [[#CHAIN_ID]] --connection [[#CONNECTION_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] query connection channels --chain [[#CHAIN_ID]] --connection [[#CONNECTION_ID]] diff --git a/guide/src/templates/commands/hermes/query/connection/end_1.md b/guide/src/templates/commands/hermes/query/connection/end_1.md index 950e792e2a..0c5400ae39 100644 --- a/guide/src/templates/commands/hermes/query/connection/end_1.md +++ b/guide/src/templates/commands/hermes/query/connection/end_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] query connection end[[#OPTIONS]] --chain [[#CHAIN_ID]] --connection [[#CONNECTION_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] query connection end[[#OPTIONS]] --chain [[#CHAIN_ID]] --connection [[#CONNECTION_ID]] diff --git a/guide/src/templates/commands/hermes/query/connection_1.md b/guide/src/templates/commands/hermes/query/connection_1.md index cf99893668..d1bc7e1515 100644 --- a/guide/src/templates/commands/hermes/query/connection_1.md +++ b/guide/src/templates/commands/hermes/query/connection_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] query connection [[#SUBCOMMAND]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] query connection [[#SUBCOMMAND]] diff --git a/guide/src/templates/commands/hermes/query/connections_1.md b/guide/src/templates/commands/hermes/query/connections_1.md index 56be68f377..0319641ecd 100644 --- a/guide/src/templates/commands/hermes/query/connections_1.md +++ b/guide/src/templates/commands/hermes/query/connections_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] query connections[[#OPTIONS]] --chain [[#CHAIN_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] query connections[[#OPTIONS]] --chain [[#CHAIN_ID]] diff --git a/guide/src/templates/commands/hermes/query/packet/ack_1.md b/guide/src/templates/commands/hermes/query/packet/ack_1.md index e264dc1b7a..f719128c22 100644 --- a/guide/src/templates/commands/hermes/query/packet/ack_1.md +++ b/guide/src/templates/commands/hermes/query/packet/ack_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] query packet ack[[#OPTIONS]] --chain [[#CHAIN_ID]] --port [[#PORT_ID]] --channel [[#CHANNEL_ID]] --sequence [[#SEQUENCE]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] query packet ack[[#OPTIONS]] --chain [[#CHAIN_ID]] --port [[#PORT_ID]] --channel [[#CHANNEL_ID]] --sequence [[#SEQUENCE]] diff --git a/guide/src/templates/commands/hermes/query/packet/acks_1.md b/guide/src/templates/commands/hermes/query/packet/acks_1.md index 7463c22a19..3b0d5143ec 100644 --- a/guide/src/templates/commands/hermes/query/packet/acks_1.md +++ b/guide/src/templates/commands/hermes/query/packet/acks_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] query packet acks --chain [[#CHAIN_ID]] --port [[#PORT_ID]] --channel [[#CHANNEL_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] query packet acks --chain [[#CHAIN_ID]] --port [[#PORT_ID]] --channel [[#CHANNEL_ID]] diff --git a/guide/src/templates/commands/hermes/query/packet/commitment_1.md b/guide/src/templates/commands/hermes/query/packet/commitment_1.md index 51f7b4ab0f..fdf68791ce 100644 --- a/guide/src/templates/commands/hermes/query/packet/commitment_1.md +++ b/guide/src/templates/commands/hermes/query/packet/commitment_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] query packet commitment[[#OPTIONS]] --chain [[#CHAIN_ID]] --port [[#PORT_ID]] --channel [[#CHANNEL_ID]] --sequence [[#SEQUENCE]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] query packet commitment[[#OPTIONS]] --chain [[#CHAIN_ID]] --port [[#PORT_ID]] --channel [[#CHANNEL_ID]] --sequence [[#SEQUENCE]] diff --git a/guide/src/templates/commands/hermes/query/packet/commitments_1.md b/guide/src/templates/commands/hermes/query/packet/commitments_1.md index c76599c8b6..57b807de52 100644 --- a/guide/src/templates/commands/hermes/query/packet/commitments_1.md +++ b/guide/src/templates/commands/hermes/query/packet/commitments_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] query packet commitments --chain [[#CHAIN_ID]] --port [[#PORT_ID]] --channel [[#CHANNEL_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] query packet commitments --chain [[#CHAIN_ID]] --port [[#PORT_ID]] --channel [[#CHANNEL_ID]] diff --git a/guide/src/templates/commands/hermes/query/packet/pending-acks_1.md b/guide/src/templates/commands/hermes/query/packet/pending-acks_1.md index 4295fb7a63..28abad7ab1 100644 --- a/guide/src/templates/commands/hermes/query/packet/pending-acks_1.md +++ b/guide/src/templates/commands/hermes/query/packet/pending-acks_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] query packet pending-acks --chain [[#CHAIN_ID]] --port [[#PORT_ID]] --channel [[#CHANNEL_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] query packet pending-acks --chain [[#CHAIN_ID]] --port [[#PORT_ID]] --channel [[#CHANNEL_ID]] diff --git a/guide/src/templates/commands/hermes/query/packet/pending-sends_1.md b/guide/src/templates/commands/hermes/query/packet/pending-sends_1.md index ba812f7f55..db32ee3c67 100644 --- a/guide/src/templates/commands/hermes/query/packet/pending-sends_1.md +++ b/guide/src/templates/commands/hermes/query/packet/pending-sends_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] query packet pending-sends --chain [[#CHAIN_ID]] --port [[#PORT_ID]] --channel [[#CHANNEL_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] query packet pending-sends --chain [[#CHAIN_ID]] --port [[#PORT_ID]] --channel [[#CHANNEL_ID]] diff --git a/guide/src/templates/commands/hermes/query/packet/pending_1.md b/guide/src/templates/commands/hermes/query/packet/pending_1.md index 8c5ffdac8e..d44ecfd5d0 100644 --- a/guide/src/templates/commands/hermes/query/packet/pending_1.md +++ b/guide/src/templates/commands/hermes/query/packet/pending_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] query packet pending --chain [[#CHAIN_ID]] --port [[#PORT_ID]] --channel [[#CHANNEL_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] query packet pending --chain [[#CHAIN_ID]] --port [[#PORT_ID]] --channel [[#CHANNEL_ID]] diff --git a/guide/src/templates/commands/hermes/query/packet_1.md b/guide/src/templates/commands/hermes/query/packet_1.md index e01562e4ec..90d389b6a6 100644 --- a/guide/src/templates/commands/hermes/query/packet_1.md +++ b/guide/src/templates/commands/hermes/query/packet_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] query packet [[#SUBCOMMAND]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] query packet [[#SUBCOMMAND]] diff --git a/guide/src/templates/commands/hermes/query/transfer/denom-trace_1.md b/guide/src/templates/commands/hermes/query/transfer/denom-trace_1.md index 892ff84086..030469df6d 100644 --- a/guide/src/templates/commands/hermes/query/transfer/denom-trace_1.md +++ b/guide/src/templates/commands/hermes/query/transfer/denom-trace_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] query transfer denom-trace --chain [[#CHAIN_ID]] --hash [[#HASH]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] query transfer denom-trace --chain [[#CHAIN_ID]] --hash [[#HASH]] diff --git a/guide/src/templates/commands/hermes/query/transfer_1.md b/guide/src/templates/commands/hermes/query/transfer_1.md index 75329ad655..373bdebdcc 100644 --- a/guide/src/templates/commands/hermes/query/transfer_1.md +++ b/guide/src/templates/commands/hermes/query/transfer_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] query transfer [[#SUBCOMMAND]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] query transfer [[#SUBCOMMAND]] diff --git a/guide/src/templates/commands/hermes/query/tx/events_1.md b/guide/src/templates/commands/hermes/query/tx/events_1.md index 75fad32a46..7f732710c5 100644 --- a/guide/src/templates/commands/hermes/query/tx/events_1.md +++ b/guide/src/templates/commands/hermes/query/tx/events_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] query tx events --chain [[#CHAIN_ID]] --hash [[#HASH]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] query tx events --chain [[#CHAIN_ID]] --hash [[#HASH]] diff --git a/guide/src/templates/commands/hermes/query/tx_1.md b/guide/src/templates/commands/hermes/query/tx_1.md index fa8e272808..c1ceebdd7c 100644 --- a/guide/src/templates/commands/hermes/query/tx_1.md +++ b/guide/src/templates/commands/hermes/query/tx_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] query tx [[#SUBCOMMAND]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] query tx [[#SUBCOMMAND]] diff --git a/guide/src/templates/commands/hermes/query_1.md b/guide/src/templates/commands/hermes/query_1.md index 642eb68ddb..02b47178b8 100644 --- a/guide/src/templates/commands/hermes/query_1.md +++ b/guide/src/templates/commands/hermes/query_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] query [[#SUBCOMMAND]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] query [[#SUBCOMMAND]] diff --git a/guide/src/templates/commands/hermes/start_1.md b/guide/src/templates/commands/hermes/start_1.md index 7ca2807b18..ea42387c81 100644 --- a/guide/src/templates/commands/hermes/start_1.md +++ b/guide/src/templates/commands/hermes/start_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] start[[#OPTIONS]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] start[[#OPTIONS]] diff --git a/guide/src/templates/commands/hermes/tx/chan-close-confirm_1.md b/guide/src/templates/commands/hermes/tx/chan-close-confirm_1.md index a709e4ca61..7946270032 100644 --- a/guide/src/templates/commands/hermes/tx/chan-close-confirm_1.md +++ b/guide/src/templates/commands/hermes/tx/chan-close-confirm_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] tx chan-close-confirm --dst-chain [[#DST_CHAIN_ID]] --src-chain [[#SRC_CHAIN_ID]] --dst-connection [[#DST_CONNECTION_ID]] --dst-port [[#DST_PORT_ID]] --src-port [[#SRC_PORT_ID]] --dst-channel [[#DST_CHANNEL_ID]] --src-channel [[#SRC_CHANNEL_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] tx chan-close-confirm --dst-chain [[#DST_CHAIN_ID]] --src-chain [[#SRC_CHAIN_ID]] --dst-connection [[#DST_CONNECTION_ID]] --dst-port [[#DST_PORT_ID]] --src-port [[#SRC_PORT_ID]] --dst-channel [[#DST_CHANNEL_ID]] --src-channel [[#SRC_CHANNEL_ID]] diff --git a/guide/src/templates/commands/hermes/tx/chan-close-init_1.md b/guide/src/templates/commands/hermes/tx/chan-close-init_1.md index e056033eeb..3e3385a0d7 100644 --- a/guide/src/templates/commands/hermes/tx/chan-close-init_1.md +++ b/guide/src/templates/commands/hermes/tx/chan-close-init_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] tx chan-close-init --dst-chain [[#DST_CHAIN_ID]] --src-chain [[#SRC_CHAIN_ID]] --dst-connection [[#DST_CONNECTION_ID]] --dst-port [[#DST_PORT_ID]] --src-port [[#SRC_PORT_ID]] --dst-channel [[#DST_CHANNEL_ID]] --src-channel [[#SRC_CHANNEL_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] tx chan-close-init --dst-chain [[#DST_CHAIN_ID]] --src-chain [[#SRC_CHAIN_ID]] --dst-connection [[#DST_CONNECTION_ID]] --dst-port [[#DST_PORT_ID]] --src-port [[#SRC_PORT_ID]] --dst-channel [[#DST_CHANNEL_ID]] --src-channel [[#SRC_CHANNEL_ID]] diff --git a/guide/src/templates/commands/hermes/tx/chan-open-ack_1.md b/guide/src/templates/commands/hermes/tx/chan-open-ack_1.md index c9ad37a8c6..4f4ad5367d 100644 --- a/guide/src/templates/commands/hermes/tx/chan-open-ack_1.md +++ b/guide/src/templates/commands/hermes/tx/chan-open-ack_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] tx chan-open-ack --dst-chain [[#DST_CHAIN_ID]] --src-chain [[#SRC_CHAIN_ID]] --dst-connection [[#DST_CONNECTION_ID]] --dst-port [[#DST_PORT_ID]] --src-port [[#SRC_PORT_ID]] --dst-channel [[#DST_CHANNEL_ID]] --src-channel [[#SRC_CHANNEL_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] tx chan-open-ack --dst-chain [[#DST_CHAIN_ID]] --src-chain [[#SRC_CHAIN_ID]] --dst-connection [[#DST_CONNECTION_ID]] --dst-port [[#DST_PORT_ID]] --src-port [[#SRC_PORT_ID]] --dst-channel [[#DST_CHANNEL_ID]] --src-channel [[#SRC_CHANNEL_ID]] diff --git a/guide/src/templates/commands/hermes/tx/chan-open-confirm_1.md b/guide/src/templates/commands/hermes/tx/chan-open-confirm_1.md index 0016c1871a..a415d2f369 100644 --- a/guide/src/templates/commands/hermes/tx/chan-open-confirm_1.md +++ b/guide/src/templates/commands/hermes/tx/chan-open-confirm_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] tx chan-open-confirm --dst-chain [[#DST_CHAIN_ID]] --src-chain [[#SRC_CHAIN_ID]] --dst-connection [[#DST_CONNECTION_ID]] --dst-port [[#DST_PORT_ID]] --src-port [[#SRC_PORT_ID]] --dst-channel [[#DST_CHANNEL_ID]] --src-channel [[#SRC_CHANNEL_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] tx chan-open-confirm --dst-chain [[#DST_CHAIN_ID]] --src-chain [[#SRC_CHAIN_ID]] --dst-connection [[#DST_CONNECTION_ID]] --dst-port [[#DST_PORT_ID]] --src-port [[#SRC_PORT_ID]] --dst-channel [[#DST_CHANNEL_ID]] --src-channel [[#SRC_CHANNEL_ID]] diff --git a/guide/src/templates/commands/hermes/tx/chan-open-init_1.md b/guide/src/templates/commands/hermes/tx/chan-open-init_1.md index 6b6d67c4e1..ff22d6c62a 100644 --- a/guide/src/templates/commands/hermes/tx/chan-open-init_1.md +++ b/guide/src/templates/commands/hermes/tx/chan-open-init_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] tx chan-open-init[[#OPTIONS]] --dst-chain [[#DST_CHAIN_ID]] --src-chain [[#SRC_CHAIN_ID]] --dst-connection [[#DST_CONNECTION_ID]] --dst-port [[#DST_PORT_ID]] --src-port [[#SRC_PORT_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] tx chan-open-init[[#OPTIONS]] --dst-chain [[#DST_CHAIN_ID]] --src-chain [[#SRC_CHAIN_ID]] --dst-connection [[#DST_CONNECTION_ID]] --dst-port [[#DST_PORT_ID]] --src-port [[#SRC_PORT_ID]] diff --git a/guide/src/templates/commands/hermes/tx/chan-open-try_1.md b/guide/src/templates/commands/hermes/tx/chan-open-try_1.md index eb4df9cd61..8d8c6dfe55 100644 --- a/guide/src/templates/commands/hermes/tx/chan-open-try_1.md +++ b/guide/src/templates/commands/hermes/tx/chan-open-try_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] tx chan-open-try[[#OPTIONS]] --dst-chain [[#DST_CHAIN_ID]] --src-chain [[#SRC_CHAIN_ID]] --dst-connection [[#DST_CONNECTION_ID]] --dst-port [[#DST_PORT_ID]] --src-port [[#SRC_PORT_ID]] --src-channel [[#SRC_CHANNEL_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] tx chan-open-try[[#OPTIONS]] --dst-chain [[#DST_CHAIN_ID]] --src-chain [[#SRC_CHAIN_ID]] --dst-connection [[#DST_CONNECTION_ID]] --dst-port [[#DST_PORT_ID]] --src-port [[#SRC_PORT_ID]] --src-channel [[#SRC_CHANNEL_ID]] diff --git a/guide/src/templates/commands/hermes/tx/conn-ack_1.md b/guide/src/templates/commands/hermes/tx/conn-ack_1.md index 94528b9445..95382a52c0 100644 --- a/guide/src/templates/commands/hermes/tx/conn-ack_1.md +++ b/guide/src/templates/commands/hermes/tx/conn-ack_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] tx conn-ack --dst-chain [[#DST_CHAIN_ID]] --src-chain [[#SRC_CHAIN_ID]] --dst-client [[#DST_CLIENT_ID]] --src-client [[#SRC_CLIENT_ID]] --dst-connection [[#DST_CONNECTION_ID]] --src-connection [[#SRC_CONNECTION_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] tx conn-ack --dst-chain [[#DST_CHAIN_ID]] --src-chain [[#SRC_CHAIN_ID]] --dst-client [[#DST_CLIENT_ID]] --src-client [[#SRC_CLIENT_ID]] --dst-connection [[#DST_CONNECTION_ID]] --src-connection [[#SRC_CONNECTION_ID]] diff --git a/guide/src/templates/commands/hermes/tx/conn-confirm_1.md b/guide/src/templates/commands/hermes/tx/conn-confirm_1.md index f356aa953e..e7b7c6ae54 100644 --- a/guide/src/templates/commands/hermes/tx/conn-confirm_1.md +++ b/guide/src/templates/commands/hermes/tx/conn-confirm_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] tx conn-confirm --dst-chain [[#DST_CHAIN_ID]] --src-chain [[#SRC_CHAIN_ID]] --dst-client [[#DST_CLIENT_ID]] --src-client [[#SRC_CLIENT_ID]] --dst-connection [[#DST_CONNECTION_ID]] --src-connection [[#SRC_CONNECTION_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] tx conn-confirm --dst-chain [[#DST_CHAIN_ID]] --src-chain [[#SRC_CHAIN_ID]] --dst-client [[#DST_CLIENT_ID]] --src-client [[#SRC_CLIENT_ID]] --dst-connection [[#DST_CONNECTION_ID]] --src-connection [[#SRC_CONNECTION_ID]] diff --git a/guide/src/templates/commands/hermes/tx/conn-init_1.md b/guide/src/templates/commands/hermes/tx/conn-init_1.md index 12add1670d..b8cf68ee2c 100644 --- a/guide/src/templates/commands/hermes/tx/conn-init_1.md +++ b/guide/src/templates/commands/hermes/tx/conn-init_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] tx conn-init --dst-chain [[#DST_CHAIN_ID]] --src-chain [[#SRC_CHAIN_ID]] --dst-client [[#DST_CLIENT_ID]] --src-client [[#SRC_CLIENT_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] tx conn-init --dst-chain [[#DST_CHAIN_ID]] --src-chain [[#SRC_CHAIN_ID]] --dst-client [[#DST_CLIENT_ID]] --src-client [[#SRC_CLIENT_ID]] diff --git a/guide/src/templates/commands/hermes/tx/conn-try_1.md b/guide/src/templates/commands/hermes/tx/conn-try_1.md index 3cd0532eeb..772d25d5af 100644 --- a/guide/src/templates/commands/hermes/tx/conn-try_1.md +++ b/guide/src/templates/commands/hermes/tx/conn-try_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] tx conn-try[[#OPTIONS]] --dst-chain [[#DST_CHAIN_ID]] --src-chain [[#SRC_CHAIN_ID]] --dst-client [[#DST_CLIENT_ID]] --src-client [[#SRC_CLIENT_ID]] --src-connection [[#SRC_CONNECTION_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] tx conn-try[[#OPTIONS]] --dst-chain [[#DST_CHAIN_ID]] --src-chain [[#SRC_CHAIN_ID]] --dst-client [[#DST_CLIENT_ID]] --src-client [[#SRC_CLIENT_ID]] --src-connection [[#SRC_CONNECTION_ID]] diff --git a/guide/src/templates/commands/hermes/tx/ft-transfer_1.md b/guide/src/templates/commands/hermes/tx/ft-transfer_1.md index 4cb657344a..0f75e26c48 100644 --- a/guide/src/templates/commands/hermes/tx/ft-transfer_1.md +++ b/guide/src/templates/commands/hermes/tx/ft-transfer_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] tx ft-transfer[[#OPTIONS]] --dst-chain [[#DST_CHAIN_ID]] --src-chain [[#SRC_CHAIN_ID]] --src-port [[#SRC_PORT_ID]] --src-channel [[#SRC_CHANNEL_ID]] --amount [[#AMOUNT]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] tx ft-transfer[[#OPTIONS]] --dst-chain [[#DST_CHAIN_ID]] --src-chain [[#SRC_CHAIN_ID]] --src-port [[#SRC_PORT_ID]] --src-channel [[#SRC_CHANNEL_ID]] --amount [[#AMOUNT]] diff --git a/guide/src/templates/commands/hermes/tx/packet-ack_1.md b/guide/src/templates/commands/hermes/tx/packet-ack_1.md index 8002a26bf9..0ae1302cd4 100644 --- a/guide/src/templates/commands/hermes/tx/packet-ack_1.md +++ b/guide/src/templates/commands/hermes/tx/packet-ack_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] tx packet-ack[[#OPTIONS]] --dst-chain [[#DST_CHAIN_ID]] --src-chain [[#SRC_CHAIN_ID]] --src-port [[#SRC_PORT_ID]] --src-channel [[#SRC_CHANNEL_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] tx packet-ack[[#OPTIONS]] --dst-chain [[#DST_CHAIN_ID]] --src-chain [[#SRC_CHAIN_ID]] --src-port [[#SRC_PORT_ID]] --src-channel [[#SRC_CHANNEL_ID]] diff --git a/guide/src/templates/commands/hermes/tx/packet-recv_1.md b/guide/src/templates/commands/hermes/tx/packet-recv_1.md index 7e7242f6db..391607bf19 100644 --- a/guide/src/templates/commands/hermes/tx/packet-recv_1.md +++ b/guide/src/templates/commands/hermes/tx/packet-recv_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] tx packet-recv[[#OPTIONS]] --dst-chain [[#DST_CHAIN_ID]] --src-chain [[#SRC_CHAIN_ID]] --src-port [[#SRC_PORT_ID]] --src-channel [[#SRC_CHANNEL_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] tx packet-recv[[#OPTIONS]] --dst-chain [[#DST_CHAIN_ID]] --src-chain [[#SRC_CHAIN_ID]] --src-port [[#SRC_PORT_ID]] --src-channel [[#SRC_CHANNEL_ID]] diff --git a/guide/src/templates/commands/hermes/tx/upgrade-chain_1.md b/guide/src/templates/commands/hermes/tx/upgrade-chain_1.md index aceb9f48c1..8151701a16 100644 --- a/guide/src/templates/commands/hermes/tx/upgrade-chain_1.md +++ b/guide/src/templates/commands/hermes/tx/upgrade-chain_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] tx upgrade-chain[[#OPTIONS]] --reference-chain [[#REFERENCE_CHAIN_ID]] --host-chain [[#HOST_CHAIN_ID]] --host-client [[#HOST_CLIENT_ID]] --amount [[#AMOUNT]] --height-offset [[#HEIGHT_OFFSET]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] tx upgrade-chain[[#OPTIONS]] --reference-chain [[#REFERENCE_CHAIN_ID]] --host-chain [[#HOST_CHAIN_ID]] --host-client [[#HOST_CLIENT_ID]] --amount [[#AMOUNT]] --height-offset [[#HEIGHT_OFFSET]] diff --git a/guide/src/templates/commands/hermes/tx_1.md b/guide/src/templates/commands/hermes/tx_1.md index eca9bc54c0..2619d479d0 100644 --- a/guide/src/templates/commands/hermes/tx_1.md +++ b/guide/src/templates/commands/hermes/tx_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] tx [[#SUBCOMMAND]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] tx [[#SUBCOMMAND]] diff --git a/guide/src/templates/commands/hermes/update/client_1.md b/guide/src/templates/commands/hermes/update/client_1.md index 242df424bd..7cfb119475 100644 --- a/guide/src/templates/commands/hermes/update/client_1.md +++ b/guide/src/templates/commands/hermes/update/client_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] update client[[#OPTIONS]] --host-chain [[#HOST_CHAIN_ID]] --client [[#CLIENT_ID]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] update client[[#OPTIONS]] --host-chain [[#HOST_CHAIN_ID]] --client [[#CLIENT_ID]] diff --git a/guide/src/templates/commands/hermes/update_1.md b/guide/src/templates/commands/hermes/update_1.md index f2a78315ec..7b0b60456b 100644 --- a/guide/src/templates/commands/hermes/update_1.md +++ b/guide/src/templates/commands/hermes/update_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] update [[#SUBCOMMAND]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] update [[#SUBCOMMAND]] diff --git a/guide/src/templates/commands/hermes/upgrade/client_1.md b/guide/src/templates/commands/hermes/upgrade/client_1.md index 9952a4147b..2577c7c284 100644 --- a/guide/src/templates/commands/hermes/upgrade/client_1.md +++ b/guide/src/templates/commands/hermes/upgrade/client_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] upgrade client --host-chain [[#HOST_CHAIN_ID]] --client [[#CLIENT_ID]] --upgrade-height [[#REFERENCE_UPGRADE_HEIGHT]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] upgrade client --host-chain [[#HOST_CHAIN_ID]] --client [[#CLIENT_ID]] --upgrade-height [[#REFERENCE_UPGRADE_HEIGHT]] diff --git a/guide/src/templates/commands/hermes/upgrade/clients_1.md b/guide/src/templates/commands/hermes/upgrade/clients_1.md index 0d9cd56554..d9853d84e4 100644 --- a/guide/src/templates/commands/hermes/upgrade/clients_1.md +++ b/guide/src/templates/commands/hermes/upgrade/clients_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] upgrade clients[[#OPTIONS]] --reference-chain [[#REFERENCE_CHAIN_ID]] --upgrade-height [[#REFERENCE_UPGRADE_HEIGHT]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] upgrade clients[[#OPTIONS]] --reference-chain [[#REFERENCE_CHAIN_ID]] --upgrade-height [[#REFERENCE_UPGRADE_HEIGHT]] diff --git a/guide/src/templates/commands/hermes/upgrade_1.md b/guide/src/templates/commands/hermes/upgrade_1.md index 0fc1bac6f8..35da035cf5 100644 --- a/guide/src/templates/commands/hermes/upgrade_1.md +++ b/guide/src/templates/commands/hermes/upgrade_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] upgrade [[#SUBCOMMAND]] \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] upgrade [[#SUBCOMMAND]] diff --git a/guide/src/templates/commands/hermes/version_1.md b/guide/src/templates/commands/hermes/version_1.md index ad6c83dabf..1623e03d4c 100644 --- a/guide/src/templates/commands/hermes/version_1.md +++ b/guide/src/templates/commands/hermes/version_1.md @@ -1 +1 @@ -[[#BINARY hermes]][[#GLOBALOPTIONS]] version \ No newline at end of file +[[#BINARY hermes]][[#GLOBALOPTIONS]] version diff --git a/guide/src/templates/files/hermes/local-chains/config.toml b/guide/src/templates/files/hermes/local-chains/config.toml index 04893b2475..4b3acac443 100644 --- a/guide/src/templates/files/hermes/local-chains/config.toml +++ b/guide/src/templates/files/hermes/local-chains/config.toml @@ -27,6 +27,7 @@ port = 3001 [[chains]] id = 'ibc-0' +type = "CosmosSdk" rpc_addr = 'http://localhost:27030' grpc_addr = 'http://localhost:27032' event_source = { mode = 'push', url = 'ws://localhost:27030/websocket', batch_delay = '200ms' } @@ -55,6 +56,7 @@ trust_threshold = { numerator = '2', denominator = '3' } [[chains]] id = 'ibc-1' +type = "CosmosSdk" rpc_addr = 'http://localhost:27040' grpc_addr = 'http://localhost:27042' event_source = { mode = 'push', url = 'ws://localhost:27040/websocket', batch_delay = '200ms' } diff --git a/guide/src/templates/files/hermes/production/config.toml b/guide/src/templates/files/hermes/production/config.toml index 90f4a1cca8..ad6c2d5808 100644 --- a/guide/src/templates/files/hermes/production/config.toml +++ b/guide/src/templates/files/hermes/production/config.toml @@ -103,4 +103,4 @@ list = [[ ]] [chains.address_type] -derivation = 'cosmos' \ No newline at end of file +derivation = 'cosmos' diff --git a/guide/src/templates/help_templates/evidence.md b/guide/src/templates/help_templates/evidence.md new file mode 100644 index 0000000000..a8a2cdea05 --- /dev/null +++ b/guide/src/templates/help_templates/evidence.md @@ -0,0 +1,19 @@ +DESCRIPTION: +Listen to block events and handles evidence + +USAGE: + hermes evidence [OPTIONS] --chain + +OPTIONS: + --check-past-blocks + Check the last NUM_BLOCKS blocks for misbehaviour (default: 100) [default: 100] + + -h, --help + Print help information + + --key-name + Use the given signing key name for sending the misbehaviour evidence detected (default: + `key_name` config) + +REQUIRED: + --chain Identifier of the chain where blocks are monitored for misbehaviour diff --git a/guide/src/templates/help_templates/fee/register-counterparty-payee.md b/guide/src/templates/help_templates/fee/register-counterparty-payee.md index cd1ba0d1bc..afbd774b4c 100644 --- a/guide/src/templates/help_templates/fee/register-counterparty-payee.md +++ b/guide/src/templates/help_templates/fee/register-counterparty-payee.md @@ -15,7 +15,13 @@ FLAGS: Identifier of the channel [aliases: chan] --counterparty-payee - Address of the counterparty payee + Address of the counterparty payee. + + Note that there exists a configuration parameter `auto_register_counterparty_payee` that + can be enabled in order to have Hermes automatically register the counterparty payee on + the destination chain to the relayer's address on the source chain. This option can be + used for simple configuration of the relayer to receive fees for relaying RecvPackets on + fee-enabled channels. --port Identifier of the port diff --git a/guide/src/templates/help_templates/help.md b/guide/src/templates/help_templates/help.md index 11aa32e2af..8a0011bd76 100644 --- a/guide/src/templates/help_templates/help.md +++ b/guide/src/templates/help_templates/help.md @@ -17,13 +17,14 @@ SUBCOMMANDS: clear Clear objects, such as outstanding packets on a channel config Generate a new Hermes configuration file or validate an existing one create Create objects (client, connection, or channel) on chains + evidence Listen to block events and handles evidence fee Interact with the fee middleware health-check Performs a health check of all chains in the the config help Print this message or the help of the given subcommand(s) keys Manage keys in the relayer for each chain listen Listen to and display IBC events emitted by a chain logs Update tracing log directives - misbehaviour Listen to client update IBC events and handles misbehaviour + misbehaviour Listen to client update IBC events and handle misbehaviour query Query objects from the chain start Start the relayer in multi-chain mode tx Create and send IBC transactions diff --git a/guide/src/templates/help_templates/misbehaviour.md b/guide/src/templates/help_templates/misbehaviour.md index 5344c12d13..e669d63344 100644 --- a/guide/src/templates/help_templates/misbehaviour.md +++ b/guide/src/templates/help_templates/misbehaviour.md @@ -1,5 +1,5 @@ DESCRIPTION: -Listen to client update IBC events and handles misbehaviour +Listen to client update IBC events and handle misbehaviour USAGE: hermes misbehaviour --chain --client diff --git a/guide/src/templates/hermes-version.md b/guide/src/templates/hermes-version.md index a7e7c99725..a20e2d82d2 100644 --- a/guide/src/templates/hermes-version.md +++ b/guide/src/templates/hermes-version.md @@ -1 +1 @@ -v1.6.0+1c1cf02 +v1.7.0 diff --git a/scripts/auto_gen_templates.sh b/scripts/auto_gen_templates.sh old mode 100644 new mode 100755 index d7eb557357..aaf0c605d8 --- a/scripts/auto_gen_templates.sh +++ b/scripts/auto_gen_templates.sh @@ -192,7 +192,7 @@ function generate_templates(){ do # Create a template for every usage filename=$COMMAND_DIR$path"_$cpt.md" - echo -n $line > $TMP_PATH + echo $line > $TMP_PATH local cpt=$((cpt+1)) if ! cmp -s $TMP_PATH $filename; then if [ $MODE = "update" ]; then diff --git a/scripts/one-chain b/scripts/one-chain index 30a1af787b..47bf41365e 100755 --- a/scripts/one-chain +++ b/scripts/one-chain @@ -146,7 +146,7 @@ fi # Start gaia echo "Start gaia on grpc port: $GRPC_PORT..." -$BINARY --home $CHAIN_DIR/$CHAIN_ID start --pruning=nothing --grpc.address="0.0.0.0:$GRPC_PORT" --log_level error > $CHAIN_DIR/$CHAIN_ID.log 2>&1 & +$BINARY --home $CHAIN_DIR/$CHAIN_ID start --pruning=nothing --grpc.address="0.0.0.0:$GRPC_PORT" --log_level info > $CHAIN_DIR/$CHAIN_ID.log 2>&1 & # Show validator's and user's balance sleep 3 diff --git a/tools/check-guide/Cargo.lock b/tools/check-guide/Cargo.lock index b6e0dbe517..b5ddef7a45 100644 --- a/tools/check-guide/Cargo.lock +++ b/tools/check-guide/Cargo.lock @@ -43,9 +43,9 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ "gimli", ] @@ -58,18 +58,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aho-corasick" -version = "0.7.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" -dependencies = [ - "memchr", -] - -[[package]] -name = "aho-corasick" -version = "1.0.2" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab" dependencies = [ "memchr", ] @@ -104,30 +95,29 @@ dependencies = [ [[package]] name = "anstream" -version = "0.3.2" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", - "is-terminal", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.1" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" [[package]] name = "anstyle-parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" dependencies = [ "utf8parse", ] @@ -143,9 +133,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "1.0.1" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" dependencies = [ "anstyle", "windows-sys 0.48.0", @@ -153,9 +143,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.71" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "arc-swap" @@ -182,18 +172,18 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.37", ] [[package]] name = "async-trait" -version = "0.1.72" +version = "0.1.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.37", ] [[package]] @@ -209,7 +199,7 @@ dependencies = [ "rustls-native-certs", "tokio", "tokio-rustls", - "tungstenite 0.20.1", + "tungstenite", ] [[package]] @@ -231,9 +221,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "axum" -version = "0.6.18" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8175979259124331c1d7bf6586ee7e0da434155e4b2d48ec2c8386281d8df39" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" dependencies = [ "async-trait", "axum-core", @@ -280,9 +270,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", @@ -307,9 +297,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.2" +version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" [[package]] name = "base64ct" @@ -376,9 +366,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" [[package]] name = "block-buffer" @@ -409,9 +399,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.6.0" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05" +checksum = "4c2f7349907b712260e64b0afe2f84692af14a454be26187d9df565c7f69266a" dependencies = [ "memchr", "regex-automata 0.3.9", @@ -420,9 +410,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "byte-unit" @@ -436,9 +426,9 @@ dependencies = [ [[package]] name = "bytecount" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c" +checksum = "ad152d03a2c813c80bb94fedbf3a3f02b28f793e39e7c214c8a0bcc196343de7" [[package]] name = "byteorder" @@ -448,9 +438,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" dependencies = [ "serde", ] @@ -472,9 +462,9 @@ checksum = "e6e9e01327e6c86e92ec72b1c798d4a94810f147209bbe3ffab6a86954937a6f" [[package]] name = "cargo-platform" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27" +checksum = "2cfa25e60aea747ec7e1124f238816749faa93759c6ff5b31f1ccdda137f4479" dependencies = [ "serde", ] @@ -494,9 +484,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.79" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -524,14 +517,14 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.26" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", - "winapi", + "windows-targets 0.48.5", ] [[package]] @@ -553,23 +546,22 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.11" +version = "4.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1640e5cc7fb47dbb8338fd471b105e7ed6c3cb2aeb00c2e067127ffd3764a05d" +checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.3.11" +version = "4.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98c59138d527eeaf9b53f35a77fcc1fad9d883116070c63d5de1c7dc7b00c72b" +checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45" dependencies = [ "anstream", "anstyle", - "clap_lex 0.5.0", - "once_cell", + "clap_lex 0.5.1", "strsim", "terminal_size", ] @@ -585,11 +577,11 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.3.2" +version = "4.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc443334c81a804575546c5a8a79b4913b50e28d69232903604cada1de817ce" +checksum = "e3ae8ba90b9d8b007efe66e55e48fb936272f5ca00349b5b0e89877520d35ea7" dependencies = [ - "clap 4.3.11", + "clap 4.4.6", ] [[package]] @@ -616,9 +608,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" +checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" [[package]] name = "color-eyre" @@ -668,9 +660,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "795bc6e66a8e340f075fcf6227e417a2dc976b92b91f3cdc778bb858778b6747" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "contracts" @@ -769,9 +761,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4c2f4e1afd912bc40bfd6fed5d9dc1f288e0ba01bfcc835cc5bc3eb13efe15" +checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" dependencies = [ "generic-array", "rand_core", @@ -791,9 +783,9 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.0.0" +version = "4.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f711ade317dd348950a9910f81c5947e3d8907ebd2b83f76203ff1807e6a2bc2" +checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" dependencies = [ "cfg-if 1.0.0", "cpufeatures", @@ -814,7 +806,7 @@ checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.37", ] [[package]] @@ -832,12 +824,12 @@ dependencies = [ [[package]] name = "dashmap" -version = "5.5.0" +version = "5.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6943ae99c34386c84a470c499d3414f66502a41340aa895406e0d2e4a207b91d" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if 1.0.0", - "hashbrown 0.14.0", + "hashbrown 0.14.1", "lock_api", "once_cell", "parking_lot_core", @@ -851,14 +843,20 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "der" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7ed52955ce76b1554f509074bb357d3fb8ac9b51288a65a3fd480d1dfba946" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", "zeroize", ] +[[package]] +name = "deranged" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" + [[package]] name = "derivation-path" version = "0.2.0" @@ -930,17 +928,11 @@ dependencies = [ "winapi", ] -[[package]] -name = "dyn-clone" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "304e6508efa593091e97a9abbc10f90aa7ca635b6d2784feff3c89d41dd12272" - [[package]] name = "ecdsa" -version = "0.16.7" +version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0997c976637b606099b9985693efa3581e84e41f5c11ba5255f88711058ad428" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" dependencies = [ "der", "digest 0.10.7", @@ -984,7 +976,7 @@ dependencies = [ "ed25519", "rand_core", "serde", - "sha2 0.10.7", + "sha2 0.10.8", "zeroize", ] @@ -997,14 +989,14 @@ dependencies = [ "derivation-path", "ed25519-dalek", "hmac", - "sha2 0.10.7", + "sha2 0.10.8", ] [[package]] name = "either" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "elasticlunr-rs" @@ -1020,9 +1012,9 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.13.5" +version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" +checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" dependencies = [ "base16ct", "crypto-bigint", @@ -1045,9 +1037,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.32" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" dependencies = [ "cfg-if 1.0.0", ] @@ -1084,20 +1076,11 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" -[[package]] -name = "erased-serde" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f94c0e13118e7d7533271f754a168ae8400e6a1cc043f2bfd53cc7290f1a1de3" -dependencies = [ - "serde", -] - [[package]] name = "errno" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "add4f07d43996f76ef320709726a556a9d4f965d9410d8d0271132d2f8293480" dependencies = [ "errno-dragonfly", "libc", @@ -1145,12 +1128,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.9.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" [[package]] name = "ff" @@ -1164,19 +1144,19 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.1.20" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77" +checksum = "d0870c84016d4b481be5c9f323c24f65e31e901ae618f0e80f4308fb00de1d2d" [[package]] name = "filetime" -version = "0.2.21" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cbc844cecaee9d4443931972e1289c8ff485cb4cc2767cb03ca139ed6885153" +checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall 0.2.16", + "redox_syscall 0.3.5", "windows-sys 0.48.0", ] @@ -1296,7 +1276,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.37", ] [[package]] @@ -1355,9 +1335,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.3" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "glob" @@ -1367,11 +1347,11 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "globset" -version = "0.4.10" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc" +checksum = "759c97c1e17c55525b57192c06a267cda0ac5210b222d6b82189a2338fa1c13d" dependencies = [ - "aho-corasick 0.7.20", + "aho-corasick", "bstr", "fnv", "log", @@ -1411,9 +1391,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.20" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" +checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" dependencies = [ "bytes", "fnv", @@ -1436,9 +1416,9 @@ checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" [[package]] name = "handlebars" -version = "4.3.7" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c3372087601b532857d332f5957cbae686da52bb7810bf038c3e3c3cc2fa0d" +checksum = "c39b3bc2a8f715298032cf5087e58573809374b08160aa7d750582bdb82d2683" dependencies = [ "log", "pest", @@ -1456,9 +1436,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" [[package]] name = "hdpath" @@ -1471,12 +1451,11 @@ dependencies = [ [[package]] name = "headers" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" +checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" dependencies = [ - "base64 0.13.1", - "bitflags 1.3.2", + "base64 0.21.4", "bytes", "headers-core", "http", @@ -1511,9 +1490,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" [[package]] name = "hex" @@ -1580,9 +1559,9 @@ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "humantime" @@ -1617,7 +1596,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2", + "socket2 0.4.9", "tokio", "tower-service", "tracing", @@ -1683,7 +1662,7 @@ dependencies = [ "http", "ibc-proto", "ibc-relayer-types", - "itertools", + "itertools 0.10.5", "reqwest", "serde", "serde_json", @@ -1694,11 +1673,11 @@ dependencies = [ [[package]] name = "ibc-proto" -version = "0.37.0" +version = "0.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "725fd83c94e9859fd967cd706996679799171eba940740f071f0046fb6f6e031" +checksum = "93cbf4cbe9e5113cc7c70f3208a7029b2205c629502cbb2ae7ea0a09a97d3005" dependencies = [ - "base64 0.21.2", + "base64 0.21.4", "bytes", "flex-error", "ics23", @@ -1737,7 +1716,7 @@ dependencies = [ "ibc-proto", "ibc-relayer-types", "ibc-telemetry", - "itertools", + "itertools 0.10.5", "moka", "num-bigint", "num-rational", @@ -1751,23 +1730,24 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "sha2 0.10.7", + "sha2 0.10.8", "signature", "strum", "subtle-encoding", "tendermint", "tendermint-light-client", "tendermint-light-client-detector", + "tendermint-proto", "tendermint-rpc", "thiserror", "tiny-bip39", "tiny-keccak", "tokio", "tokio-stream", - "toml 0.7.6", + "toml 0.7.8", "tonic", "tracing", - "uuid 1.4.0", + "uuid 1.4.1", ] [[package]] @@ -1793,7 +1773,7 @@ dependencies = [ "ibc-relayer-rest", "ibc-relayer-types", "ibc-telemetry", - "itertools", + "itertools 0.10.5", "oneline-eyre", "regex", "serde", @@ -1828,12 +1808,10 @@ version = "0.25.0" dependencies = [ "bytes", "derive_more", - "dyn-clone", - "erased-serde", "flex-error", "ibc-proto", "ics23", - "itertools", + "itertools 0.10.5", "num-rational", "primitive-types", "prost", @@ -1882,7 +1860,7 @@ dependencies = [ "prost", "ripemd", "serde", - "sha2 0.10.7", + "sha2 0.10.8", "sha3", ] @@ -1946,12 +1924,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" dependencies = [ "equivalent", - "hashbrown 0.14.0", + "hashbrown 0.14.1", ] [[package]] @@ -1984,26 +1962,6 @@ dependencies = [ "libc", ] -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi 0.3.2", - "libc", - "windows-sys 0.48.0", -] - [[package]] name = "ipnet" version = "2.8.0" @@ -2016,8 +1974,8 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ - "hermit-abi 0.3.2", - "rustix 0.38.4", + "hermit-abi 0.3.3", + "rustix", "windows-sys 0.48.0", ] @@ -2030,11 +1988,20 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + [[package]] name = "itoa" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "js-sys" @@ -2054,7 +2021,7 @@ dependencies = [ "cfg-if 1.0.0", "ecdsa", "elliptic-curve", - "sha2 0.10.7", + "sha2 0.10.8", ] [[package]] @@ -2068,9 +2035,9 @@ dependencies = [ [[package]] name = "kqueue" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c8fc60ba15bf51257aa9807a48a61013db043fcf3a78cb0d916e8e396dcad98" +checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c" dependencies = [ "kqueue-sys", "libc", @@ -2078,9 +2045,9 @@ dependencies = [ [[package]] name = "kqueue-sys" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8367585489f01bc55dd27404dcf56b95e6da061a256a666ab23be9ba96a2e587" +checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" dependencies = [ "bitflags 1.3.2", "libc", @@ -2094,21 +2061,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.147" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" - -[[package]] -name = "linux-raw-sys" -version = "0.3.8" +version = "0.2.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" [[package]] name = "linux-raw-sys" -version = "0.4.3" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" +checksum = "3852614a3bd9ca9804678ba6be5e3b8ce76dfc902cae004e3e0c44051b6e88db" [[package]] name = "lock_api" @@ -2122,9 +2083,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "mac" @@ -2172,9 +2133,9 @@ dependencies = [ [[package]] name = "matchit" -version = "0.7.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" [[package]] name = "maybe-uninit" @@ -2184,15 +2145,15 @@ checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" [[package]] name = "mdbook" -version = "0.4.31" +version = "0.4.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b67ee4a744f36e6280792016c17e69921b51df357181d1eb17d620fcc3609f3" +checksum = "1c3f88addd34930bc5f01b9dc19f780447e51c92bf2536e3ded058018271775d" dependencies = [ "ammonia", "anyhow", "chrono", - "clap 4.3.11", - "clap_complete 4.3.2", + "clap 4.4.6", + "clap_complete 4.4.3", "elasticlunr-rs", "env_logger 0.10.0", "futures-util", @@ -2304,7 +2265,7 @@ dependencies = [ "tagptr", "thiserror", "triomphe", - "uuid 1.4.0", + "uuid 1.4.1", ] [[package]] @@ -2313,29 +2274,39 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" +[[package]] +name = "normpath" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec60c60a693226186f5d6edf073232bfb6464ed97eb22cf3b01c1e8198fd97f5" +dependencies = [ + "windows-sys 0.48.0", +] + [[package]] name = "notify" -version = "5.2.0" +version = "6.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "729f63e1ca555a43fe3efa4f3efdf4801c479da85b432242a7b726f353c88486" +checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.0", "crossbeam-channel 0.5.8", "filetime", "fsevent-sys", "inotify", "kqueue", "libc", + "log", "mio", "walkdir", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] name = "notify-debouncer-mini" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e23e9fa24f094b143c1eb61f90ac6457de87be6987bc70746e0179f7dbc9007b" +checksum = "e55ee272914f4563a2f8b8553eb6811f3c0caea81c756346bad15b7e3ef969f0" dependencies = [ "crossbeam-channel 0.5.8", "notify", @@ -2353,9 +2324,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" dependencies = [ "autocfg", "num-integer", @@ -2399,9 +2370,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", ] @@ -2412,15 +2383,15 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.3.2", + "hermit-abi 0.3.3", "libc", ] [[package]] name = "object" -version = "0.31.1" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] @@ -2448,11 +2419,12 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "opener" -version = "0.5.2" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "293c15678e37254c15bd2f092314abb4e51d7fdde05c2021279c12631b54f005" +checksum = "6c62dcb6174f9cb326eac248f07e955d5d559c272730b6c03e396b443b562788" dependencies = [ "bstr", + "normpath", "winapi", ] @@ -2557,14 +2529,14 @@ dependencies = [ "libc", "redox_syscall 0.3.5", "smallvec", - "windows-targets 0.48.1", + "windows-targets 0.48.5", ] [[package]] name = "paste" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4b27ab7be369122c218afc2079489cdcb4b517c0a3fc386ff11e1fedfcc2b35" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "pbkdf2" @@ -2610,19 +2582,20 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pest" -version = "2.7.0" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73935e4d55e2abf7f130186537b19e7a4abc886a0252380b59248af473a3fc9" +checksum = "c022f1e7b65d6a24c0dbbd5fb344c66881bc01f3e5ae74a1c8100f2f985d98a4" dependencies = [ + "memchr", "thiserror", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.7.0" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aef623c9bbfa0eedf5a0efba11a5ee83209c326653ca31ff019bec3a95bfff2b" +checksum = "35513f630d46400a977c4cb58f78e1bfbe01434316e60c37d27b9ad6139c66d8" dependencies = [ "pest", "pest_generator", @@ -2630,26 +2603,26 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.0" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e8cba4ec22bada7fc55ffe51e2deb6a0e0db2d0b7ab0b103acc80d2510c190" +checksum = "bc9fc1b9e7057baba189b5c626e2d6f40681ae5b6eb064dc7c7834101ec8123a" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.37", ] [[package]] name = "pest_meta" -version = "2.7.0" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a01f71cb40bd8bb94232df14b946909e14660e33fc05db3e50ae2a82d7ea0ca0" +checksum = "1df74e9e7ec4053ceb980e7c0c8bd3594e977fde1af91daba9c928e8e8c6708d" dependencies = [ "once_cell", "pest", - "sha2 0.10.7", + "sha2 0.10.8", ] [[package]] @@ -2692,29 +2665,29 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.37", ] [[package]] name = "pin-project-lite" -version = "0.2.10" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -2734,9 +2707,9 @@ dependencies = [ [[package]] name = "platforms" -version = "3.0.2" +version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d7ddaed09e0eb771a79ab0fd64609ba0afb0a8366421957936ad14cbd13630" +checksum = "4503fa043bf02cee09a9582e9554b4c6403b2ef55e4612e96561d294419429f8" [[package]] name = "ppv-lite86" @@ -2787,9 +2760,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.64" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da" +checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" dependencies = [ "unicode-ident", ] @@ -2826,10 +2799,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "265baba7fabd416cf5078179f7d2cbeca4ce7a9041111900675ea7c4cb8a4c32" dependencies = [ "anyhow", - "itertools", + "itertools 0.11.0", "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.37", ] [[package]] @@ -2876,9 +2849,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.29" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -2957,7 +2930,7 @@ version = "1.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebee201405406dbf528b8b672104ae6d6d63e6d118cb10e4d51abbc7b58044ff" dependencies = [ - "aho-corasick 1.0.2", + "aho-corasick", "memchr", "regex-automata 0.3.9", "regex-syntax 0.7.5", @@ -2978,7 +2951,7 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9" dependencies = [ - "aho-corasick 1.0.2", + "aho-corasick", "memchr", "regex-syntax 0.7.5", ] @@ -3001,7 +2974,7 @@ version = "0.11.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" dependencies = [ - "base64 0.21.2", + "base64 0.21.4", "bytes", "encoding_rs", "futures-core", @@ -3099,28 +3072,14 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.23" +version = "0.38.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" +checksum = "f25469e9ae0f3d0047ca8b93fc56843f38e6774f0914a107ff8b41be8be8e0b7" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.0", "errno", - "io-lifetimes", "libc", - "linux-raw-sys 0.3.8", - "windows-sys 0.48.0", -] - -[[package]] -name = "rustix" -version = "0.38.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" -dependencies = [ - "bitflags 2.3.3", - "errno", - "libc", - "linux-raw-sys 0.4.3", + "linux-raw-sys", "windows-sys 0.48.0", ] @@ -3154,7 +3113,7 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.2", + "base64 0.21.4", ] [[package]] @@ -3169,15 +3128,15 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc31bd9b61a32c31f9650d18add92aa83a49ba979c143eefd27fe7177b05bd5f" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "ryu" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "same-file" @@ -3214,9 +3173,9 @@ checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sct" @@ -3230,9 +3189,9 @@ dependencies = [ [[package]] name = "sec1" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0aec48e813d6b90b15f0b8948af3c63483992dee44c03e9930b3eebdabe046e" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", "der", @@ -3275,9 +3234,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.1" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -3288,9 +3247,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" dependencies = [ "core-foundation-sys", "libc", @@ -3298,27 +3257,27 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.17" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" +checksum = "ad977052201c6de01a8ef2aa3378c4bd23217a056337d1d6da40468d267a4fb0" dependencies = [ "serde", ] [[package]] name = "serde" -version = "1.0.171" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.11" +version = "0.11.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a16be4fe5320ade08736447e3198294a5ea9a6d44dde6f35f0a5e06859c427a" +checksum = "ab33ec92f677585af6d88c65593ae2375adde54efdbf16d597f2cbc7a6d368ff" dependencies = [ "serde", ] @@ -3335,20 +3294,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.171" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.37", ] [[package]] name = "serde_json" -version = "1.0.102" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5062a995d481b2308b6064e9af76011f2921c35f97b0468811ed9f6cd91dfed" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" dependencies = [ "itoa", "ryu", @@ -3357,9 +3316,9 @@ dependencies = [ [[package]] name = "serde_path_to_error" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc4422959dd87a76cb117c191dcbffc20467f06c9100b76721dab370f24d3a" +checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335" dependencies = [ "itoa", "serde", @@ -3367,13 +3326,13 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.14" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d89a8107374290037607734c0b73a85db7ed80cae314b3c5791f192a496e731" +checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.37", ] [[package]] @@ -3399,9 +3358,9 @@ dependencies = [ [[package]] name = "sha1" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if 1.0.0", "cpufeatures", @@ -3423,9 +3382,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if 1.0.0", "cpufeatures", @@ -3444,9 +3403,9 @@ dependencies = [ [[package]] name = "sharded-slab" -version = "0.1.4" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ "lazy_static", ] @@ -3459,9 +3418,9 @@ checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" [[package]] name = "shlex" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" +checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" [[package]] name = "signal-hook" @@ -3500,9 +3459,9 @@ checksum = "cc47a29ce97772ca5c927f75bac34866b16d64e07f330c3248e2d7226623901b" [[package]] name = "siphasher" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" [[package]] name = "skeptic" @@ -3521,18 +3480,18 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] [[package]] name = "smallvec" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "socket2" @@ -3544,6 +3503,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "socket2" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "spin" version = "0.5.2" @@ -3609,15 +3578,15 @@ dependencies = [ [[package]] name = "strum_macros" -version = "0.25.1" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6069ca09d878a33f883cc06aaa9718ede171841d3832450354410b718b097232" +checksum = "ad8d03b598d3d0fff69bf533ee3ef19b8eeb342729596df84bcc7e1f96ec4059" dependencies = [ "heck", "proc-macro2", "quote", "rustversion", - "syn 2.0.25", + "syn 2.0.37", ] [[package]] @@ -3654,9 +3623,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.25" +version = "2.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e3fc8c0c74267e2df136e5e5fb656a464158aa57624053375eb9c8c6e25ae2" +checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" dependencies = [ "proc-macro2", "quote", @@ -3710,15 +3679,14 @@ checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" [[package]] name = "tempfile" -version = "3.6.0" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ - "autocfg", "cfg-if 1.0.0", "fastrand", "redox_syscall 0.3.5", - "rustix 0.37.23", + "rustix", "windows-sys 0.48.0", ] @@ -3744,7 +3712,7 @@ dependencies = [ "serde_bytes", "serde_json", "serde_repr", - "sha2 0.10.7", + "sha2 0.10.8", "signature", "subtle", "subtle-encoding", @@ -3909,20 +3877,20 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64" dependencies = [ "winapi-util", ] [[package]] name = "terminal_size" -version = "0.2.6" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e6bf6f19e9f8ed8d4048dc22981458ebcf406d67e94cd422e5ecd73d63b3237" +checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" dependencies = [ - "rustix 0.37.23", + "rustix", "windows-sys 0.48.0", ] @@ -3934,22 +3902,22 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" -version = "1.0.43" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" +checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.43" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" +checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.37", ] [[package]] @@ -3964,10 +3932,11 @@ dependencies = [ [[package]] name = "time" -version = "0.3.23" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446" +checksum = "426f806f4089c493dcac0d24c29c01e2c38baf8e30f1b716ee37e83d200b18fe" dependencies = [ + "deranged", "serde", "time-core", "time-macros", @@ -3975,15 +3944,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.10" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ba15a897f3c86766b757e5ac7221554c6750054d74d5b28844fce5fb36a6c4" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" dependencies = [ "time-core", ] @@ -4000,7 +3969,7 @@ dependencies = [ "pbkdf2", "rand", "rustc-hash", - "sha2 0.10.7", + "sha2 0.10.8", "thiserror", "unicode-normalization", "wasm-bindgen", @@ -4033,11 +4002,10 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.29.1" +version = "1.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" +checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" dependencies = [ - "autocfg", "backtrace", "bytes", "libc", @@ -4046,7 +4014,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.5.4", "tokio-macros", "windows-sys 0.48.0", ] @@ -4069,7 +4037,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.37", ] [[package]] @@ -4095,21 +4063,21 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.18.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54319c93411147bced34cb5609a80e0a8e44c5999c93903a81cd866630ec0bfd" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", "tokio", - "tungstenite 0.18.0", + "tungstenite", ] [[package]] name = "tokio-util" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d" dependencies = [ "bytes", "futures-core", @@ -4130,9 +4098,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" dependencies = [ "serde", "serde_spanned", @@ -4151,11 +4119,11 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.19.12" +version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c500344a19072298cd05a7224b3c0c629348b78692bf48466c5238656e315a78" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.0.0", + "indexmap 2.0.2", "serde", "serde_spanned", "toml_datetime", @@ -4171,7 +4139,7 @@ dependencies = [ "async-stream", "async-trait", "axum", - "base64 0.21.2", + "base64 0.21.4", "bytes", "h2", "http", @@ -4252,7 +4220,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.37", ] [[package]] @@ -4329,25 +4297,6 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" -[[package]] -name = "tungstenite" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ee6ab729cd4cf0fd55218530c4522ed30b7b6081752839b68fcec8d0960788" -dependencies = [ - "base64 0.13.1", - "byteorder", - "bytes", - "http", - "httparse", - "log", - "rand", - "sha1", - "thiserror", - "url", - "utf-8", -] - [[package]] name = "tungstenite" version = "0.20.1" @@ -4370,9 +4319,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "ucd-trie" @@ -4394,9 +4343,9 @@ dependencies = [ [[package]] name = "unicase" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" dependencies = [ "version_check", ] @@ -4409,9 +4358,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.10" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" @@ -4424,9 +4373,9 @@ dependencies = [ [[package]] name = "unicode-width" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" [[package]] name = "unicode-xid" @@ -4453,9 +4402,9 @@ dependencies = [ [[package]] name = "urlencoding" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8db7427f936968176eaa7cdf81b7f98b980b18495ec28f1b5791ac3bfe3eea9" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" [[package]] name = "utf-8" @@ -4483,9 +4432,9 @@ checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" [[package]] name = "uuid" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d023da39d1fde5a8a3fe1f3e01ca9632ada0a63e9797de55a879d6e2236277be" +checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" dependencies = [ "getrandom", ] @@ -4513,9 +4462,9 @@ dependencies = [ [[package]] name = "walkdir" -version = "2.3.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" dependencies = [ "same-file", "winapi-util", @@ -4532,9 +4481,9 @@ dependencies = [ [[package]] name = "warp" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba431ef570df1287f7f8b07e376491ad54f84d26ac473489427231e1718e1f69" +checksum = "c1e92e22e03ff1230c03a1a8ee37d2f89cd489e2e541b7550d6afad96faed169" dependencies = [ "bytes", "futures-channel", @@ -4587,7 +4536,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.37", "wasm-bindgen-shared", ] @@ -4621,7 +4570,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.37", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4666,9 +4615,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi", ] @@ -4685,7 +4634,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets 0.48.1", + "windows-targets 0.48.5", ] [[package]] @@ -4703,7 +4652,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.1", + "windows-targets 0.48.5", ] [[package]] @@ -4723,17 +4672,17 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.1" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] @@ -4744,9 +4693,9 @@ checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" @@ -4756,9 +4705,9 @@ checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" @@ -4768,9 +4717,9 @@ checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" @@ -4780,9 +4729,9 @@ checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" @@ -4792,9 +4741,9 @@ checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" @@ -4804,9 +4753,9 @@ checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" @@ -4816,15 +4765,15 @@ checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "winnow" -version = "0.4.9" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81a2094c43cc94775293eaa0e499fbc30048a6d824ac82c0351a8c0bf9112529" +checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" dependencies = [ "memchr", ] @@ -4856,5 +4805,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.37", ] diff --git a/tools/check-guide/Cargo.toml b/tools/check-guide/Cargo.toml index 59b5956262..a69316ec10 100644 --- a/tools/check-guide/Cargo.toml +++ b/tools/check-guide/Cargo.toml @@ -13,3 +13,4 @@ lazy_static = "1.4.0" mdbook-template = "1.1.0" regex = "1" walkdir = "2.3.3" + diff --git a/tools/integration-test/Cargo.toml b/tools/integration-test/Cargo.toml index f5d69d9132..61a8849df7 100644 --- a/tools/integration-test/Cargo.toml +++ b/tools/integration-test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ibc-integration-test" -version = "0.25.0" +version = "0.26.0" edition = "2021" rust-version = "1.70" license = "Apache-2.0" diff --git a/tools/integration-test/src/bin/test_setup_with_binary_channel.rs b/tools/integration-test/src/bin/test_setup_with_binary_channel.rs index d2710d2ee9..336b0c1b23 100644 --- a/tools/integration-test/src/bin/test_setup_with_binary_channel.rs +++ b/tools/integration-test/src/bin/test_setup_with_binary_channel.rs @@ -25,6 +25,7 @@ ``` */ +use ibc_relayer::config::ChainConfig; use ibc_relayer::keyring::Store; use ibc_test_framework::prelude::*; use std::env; @@ -41,10 +42,14 @@ impl TestOverrides for Test { fn modify_relayer_config(&self, config: &mut Config) { for chain in config.chains.iter_mut() { - // Modify the key store type to `Store::Test` so that the wallet - // keys are stored to ~/.hermes/keys so that we can use them - // with external relayer commands. - chain.key_store_type = Store::Test; + match chain { + ChainConfig::CosmosSdk(chain_config) => { + // Modify the key store type to `Store::Test` so that the wallet + // keys are stored to ~/.hermes/keys so that we can use them + // with external relayer commands. + chain_config.key_store_type = Store::Test; + } + } } } diff --git a/tools/integration-test/src/bin/test_setup_with_fee_enabled_binary_channel.rs b/tools/integration-test/src/bin/test_setup_with_fee_enabled_binary_channel.rs index 77172a4c44..d7e7c5456f 100644 --- a/tools/integration-test/src/bin/test_setup_with_fee_enabled_binary_channel.rs +++ b/tools/integration-test/src/bin/test_setup_with_fee_enabled_binary_channel.rs @@ -25,6 +25,7 @@ ``` */ +use ibc_relayer::config::ChainConfig; use ibc_relayer::keyring::Store; use ibc_relayer_types::core::ics04_channel::version::Version; use ibc_test_framework::prelude::*; @@ -42,10 +43,14 @@ impl TestOverrides for Test { fn modify_relayer_config(&self, config: &mut Config) { for chain in config.chains.iter_mut() { - // Modify the key store type to `Store::Test` so that the wallet - // keys are stored to ~/.hermes/keys so that we can use them - // with external relayer commands. - chain.key_store_type = Store::Test; + match chain { + ChainConfig::CosmosSdk(chain_config) => { + // Modify the key store type to `Store::Test` so that the wallet + // keys are stored to ~/.hermes/keys so that we can use them + // with external relayer commands. + chain_config.key_store_type = Store::Test; + } + } } } diff --git a/tools/integration-test/src/bin/test_setup_with_ternary_channel.rs b/tools/integration-test/src/bin/test_setup_with_ternary_channel.rs index 79b4914592..050c81cdcd 100644 --- a/tools/integration-test/src/bin/test_setup_with_ternary_channel.rs +++ b/tools/integration-test/src/bin/test_setup_with_ternary_channel.rs @@ -25,6 +25,7 @@ ``` */ +use ibc_relayer::config::ChainConfig; use ibc_relayer::keyring::Store; use ibc_test_framework::prelude::*; use std::env; @@ -41,10 +42,14 @@ impl TestOverrides for Test { fn modify_relayer_config(&self, config: &mut Config) { for chain in config.chains.iter_mut() { - // Modify the key store type to `Store::Test` so that the wallet - // keys are stored to ~/.hermes/keys so that we can use them - // with external relayer commands. - chain.key_store_type = Store::Test; + match chain { + ChainConfig::CosmosSdk(chain_config) => { + // Modify the key store type to `Store::Test` so that the wallet + // keys are stored to ~/.hermes/keys so that we can use them + // with external relayer commands. + chain_config.key_store_type = Store::Test; + } + } } } diff --git a/tools/integration-test/src/mbt/transfer.rs b/tools/integration-test/src/mbt/transfer.rs index b2156a04da..846edc822f 100644 --- a/tools/integration-test/src/mbt/transfer.rs +++ b/tools/integration-test/src/mbt/transfer.rs @@ -2,8 +2,8 @@ use std::io::Write; use std::panic::{RefUnwindSafe, UnwindSafe}; use ibc_relayer::config::{ - Channels as ConfigChannels, Clients as ConfigClients, Connections as ConfigConnections, - ModeConfig, Packets as ConfigPackets, + ChainConfig, Channels as ConfigChannels, Clients as ConfigClients, + Connections as ConfigConnections, ModeConfig, Packets as ConfigPackets, }; use ibc_test_framework::prelude::*; @@ -158,7 +158,11 @@ impl TestOverrides for IbcTransferMBT { }; for chain_config in config.chains.iter_mut() { - chain_config.trusting_period = Some(CLIENT_EXPIRY); + match chain_config { + ChainConfig::CosmosSdk(chain_config) => { + chain_config.trusting_period = Some(CLIENT_EXPIRY); + } + } } } diff --git a/tools/integration-test/src/tests/client_expiration.rs b/tools/integration-test/src/tests/client_expiration.rs index acac61f055..007ac0b459 100644 --- a/tools/integration-test/src/tests/client_expiration.rs +++ b/tools/integration-test/src/tests/client_expiration.rs @@ -1,7 +1,7 @@ use core::time::Duration; use std::thread::sleep; -use ibc_relayer::config::{self, Config, ModeConfig}; +use ibc_relayer::config::{self, ChainConfig, Config, ModeConfig}; use ibc_relayer_types::core::ics03_connection::connection::State as ConnectionState; use ibc_relayer_types::core::ics04_channel::channel::State as ChannelState; @@ -116,7 +116,11 @@ impl TestOverrides for ExpirationTestOverrides { }; for chain_config in config.chains.iter_mut() { - chain_config.trusting_period = Some(CLIENT_EXPIRY); + match chain_config { + ChainConfig::CosmosSdk(chain_config) => { + chain_config.trusting_period = Some(CLIENT_EXPIRY); + } + } } } diff --git a/tools/integration-test/src/tests/client_refresh.rs b/tools/integration-test/src/tests/client_refresh.rs index c5e79c2e71..8c055e3fbd 100644 --- a/tools/integration-test/src/tests/client_refresh.rs +++ b/tools/integration-test/src/tests/client_refresh.rs @@ -1,5 +1,6 @@ use std::time::Duration; +use ibc_relayer::config::ChainConfig; use ibc_relayer_types::core::ics02_client::trust_threshold::TrustThreshold; use ibc_relayer::config::gas_multiplier::GasMultiplier; @@ -127,8 +128,13 @@ impl BinaryChainTest for ClientFailsTest { 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 ChainConfig::CosmosSdk(config_chain_a) = &mut config.chains[0]; + config_chain_a.gas_multiplier = Some(GasMultiplier::unsafe_new(0.8)); + } + + let ChainConfig::CosmosSdk(config_chain_b) = &mut config.chains[1]; + config_chain_b.gas_multiplier = Some(GasMultiplier::unsafe_new(0.8)); }, config, )?; diff --git a/tools/integration-test/src/tests/client_settings.rs b/tools/integration-test/src/tests/client_settings.rs index 7df6858101..2bc7ee02a3 100644 --- a/tools/integration-test/src/tests/client_settings.rs +++ b/tools/integration-test/src/tests/client_settings.rs @@ -1,5 +1,6 @@ use std::time::Duration; +use ibc_relayer::config::ChainConfig; use ibc_relayer_types::core::ics02_client::trust_threshold::TrustThreshold; use ibc_relayer::chain::requests::{IncludeProof, QueryClientStateRequest, QueryHeight}; @@ -27,15 +28,24 @@ struct ClientOptionsTest; impl TestOverrides for ClientDefaultsTest { fn modify_relayer_config(&self, config: &mut Config) { - config.chains[0].clock_drift = Duration::from_secs(3); - config.chains[0].max_block_time = Duration::from_secs(5); - config.chains[0].trusting_period = Some(Duration::from_secs(120_000)); - config.chains[0].trust_threshold = TrustThreshold::new(13, 23).unwrap().try_into().unwrap(); - - config.chains[1].clock_drift = Duration::from_secs(6); - config.chains[1].max_block_time = Duration::from_secs(15); - config.chains[1].trusting_period = Some(Duration::from_secs(340_000)); - config.chains[1].trust_threshold = TrustThreshold::TWO_THIRDS.try_into().unwrap(); + match &mut config.chains[0] { + ChainConfig::CosmosSdk(chain_config_a) => { + chain_config_a.clock_drift = Duration::from_secs(3); + chain_config_a.max_block_time = Duration::from_secs(5); + chain_config_a.trusting_period = Some(Duration::from_secs(120_000)); + chain_config_a.trust_threshold = + TrustThreshold::new(13, 23).unwrap().try_into().unwrap(); + } + } + + match &mut config.chains[1] { + ChainConfig::CosmosSdk(chain_config_b) => { + chain_config_b.clock_drift = Duration::from_secs(6); + chain_config_b.max_block_time = Duration::from_secs(15); + chain_config_b.trusting_period = Some(Duration::from_secs(340_000)); + chain_config_b.trust_threshold = TrustThreshold::TWO_THIRDS.try_into().unwrap(); + } + } } } diff --git a/tools/integration-test/src/tests/fee/filter_fees.rs b/tools/integration-test/src/tests/fee/filter_fees.rs index 64a4c00504..a6cd76b37d 100644 --- a/tools/integration-test/src/tests/fee/filter_fees.rs +++ b/tools/integration-test/src/tests/fee/filter_fees.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use ibc_relayer::config::filter::{ChannelPolicy, FeePolicy, FilterPattern, MinFee}; -use ibc_relayer::config::PacketFilter; +use ibc_relayer::config::{ChainConfig, PacketFilter}; use ibc_relayer_types::core::ics04_channel::version::Version; use ibc_test_framework::prelude::*; use ibc_test_framework::util::random::random_u128_range; @@ -27,7 +27,11 @@ impl TestOverrides for FilterIncentivizedFeesRelayerTest { HashMap::from([(FilterPattern::Wildcard("*".parse().unwrap()), fees_filters)]); let packet_filter = PacketFilter::new(ChannelPolicy::default(), min_fees); for chain_config in config.chains.iter_mut() { - chain_config.packet_filter = packet_filter.clone(); + match chain_config { + ChainConfig::CosmosSdk(chain_config) => { + chain_config.packet_filter = packet_filter.clone(); + } + } } } @@ -175,7 +179,11 @@ impl TestOverrides for FilterByChannelIncentivizedFeesRelayerTest { )]); let packet_filter = PacketFilter::new(ChannelPolicy::default(), min_fees); for chain_config in config.chains.iter_mut() { - chain_config.packet_filter = packet_filter.clone(); + match chain_config { + ChainConfig::CosmosSdk(chain_config) => { + chain_config.packet_filter = packet_filter.clone(); + } + } } } diff --git a/tools/integration-test/src/tests/fee_grant.rs b/tools/integration-test/src/tests/fee_grant.rs index 39a3984a73..dd4ef2a399 100644 --- a/tools/integration-test/src/tests/fee_grant.rs +++ b/tools/integration-test/src/tests/fee_grant.rs @@ -86,19 +86,19 @@ impl BinaryChannelTest for FeeGrantTest { let mut modified_relayer = relayer; - let new_chain_configs: Vec = modified_relayer + modified_relayer .config .chains .iter_mut() - .map(|c| { - if c.id == chains.node_a.chain_id().0.clone() { - c.fee_granter = Some("user2".to_owned()); + .for_each(|chain_config| { + if chain_config.id() == chains.node_a.chain_id().0 { + match chain_config { + ChainConfig::CosmosSdk(c) => { + c.fee_granter = Some("user2".to_owned()); + } + } } - c.clone() - }) - .collect(); - - modified_relayer.config.chains = new_chain_configs; + }); let mut modified_driver = chains.node_a.chain_driver().0.clone(); diff --git a/tools/integration-test/src/tests/ica.rs b/tools/integration-test/src/tests/ica.rs index dfcda16cea..8a7169ab0c 100644 --- a/tools/integration-test/src/tests/ica.rs +++ b/tools/integration-test/src/tests/ica.rs @@ -5,7 +5,7 @@ use ibc_relayer::chain::handle::ChainHandle; use ibc_relayer::chain::tracking::TrackedMsgs; use ibc_relayer::config::{ filter::{ChannelFilters, ChannelPolicy, FilterPattern}, - PacketFilter, + ChainConfig, PacketFilter, }; use ibc_relayer::event::IbcEventWithHeight; use ibc_relayer_types::applications::ics27_ica::msgs::send_tx::MsgSendTx; @@ -59,7 +59,11 @@ impl TestOverrides for IcaFilterTestAllow { config.mode.channels.enabled = true; for chain in &mut config.chains { - chain.packet_filter = self.packet_filter.clone(); + match chain { + ChainConfig::CosmosSdk(chain_config) => { + chain_config.packet_filter = self.packet_filter.clone(); + } + } } } @@ -210,10 +214,15 @@ impl TestOverrides for IcaFilterTestDeny { config.mode.channels.enabled = true; for chain in &mut config.chains { - chain.packet_filter.channel_policy = ChannelPolicy::Deny(ChannelFilters::new(vec![( - FilterPattern::Wildcard("ica*".parse().unwrap()), - FilterPattern::Wildcard("*".parse().unwrap()), - )])); + match chain { + ChainConfig::CosmosSdk(chain_config) => { + chain_config.packet_filter.channel_policy = + ChannelPolicy::Deny(ChannelFilters::new(vec![( + FilterPattern::Wildcard("ica*".parse().unwrap()), + FilterPattern::Wildcard("*".parse().unwrap()), + )])); + } + } } } } diff --git a/tools/integration-test/src/tests/manual/simulation.rs b/tools/integration-test/src/tests/manual/simulation.rs index 76442747e9..71feb2ad6d 100644 --- a/tools/integration-test/src/tests/manual/simulation.rs +++ b/tools/integration-test/src/tests/manual/simulation.rs @@ -12,7 +12,7 @@ */ use core::time::Duration; -use ibc_relayer::config::{types::MaxMsgNum, Config}; +use ibc_relayer::config::{types::MaxMsgNum, ChainConfig, Config}; use ibc_relayer::transfer::{build_and_send_transfer_messages, TransferOptions}; use ibc_relayer_types::events::IbcEvent; use ibc_test_framework::prelude::*; @@ -29,7 +29,11 @@ pub struct SimulationTest; impl TestOverrides for SimulationTest { fn modify_relayer_config(&self, config: &mut Config) { for chain in config.chains.iter_mut() { - chain.max_msg_num = MaxMsgNum::new(MAX_MSGS).unwrap(); + match chain { + ChainConfig::CosmosSdk(chain_config) => { + chain_config.max_msg_num = MaxMsgNum::new(MAX_MSGS).unwrap(); + } + } } } } diff --git a/tools/integration-test/src/tests/memo.rs b/tools/integration-test/src/tests/memo.rs index 9ad439cf95..2b44b90d48 100644 --- a/tools/integration-test/src/tests/memo.rs +++ b/tools/integration-test/src/tests/memo.rs @@ -4,6 +4,7 @@ //! You can find a more thorough walkthrough of this test at //! `tools/test-framework/src/docs/walkthroughs/memo.rs`. +use ibc_relayer::config::ChainConfig; use ibc_relayer::config::{types::Memo, Config}; use serde_json as json; @@ -25,7 +26,11 @@ pub struct MemoTest { impl TestOverrides for MemoTest { fn modify_relayer_config(&self, config: &mut Config) { for chain in config.chains.iter_mut() { - chain.memo_prefix = self.memo.clone(); + match chain { + ChainConfig::CosmosSdk(chain_config) => { + chain_config.memo_prefix = self.memo.clone(); + } + } } } } diff --git a/tools/integration-test/src/tests/ordered_channel_clear.rs b/tools/integration-test/src/tests/ordered_channel_clear.rs index 5590812164..696a536a27 100644 --- a/tools/integration-test/src/tests/ordered_channel_clear.rs +++ b/tools/integration-test/src/tests/ordered_channel_clear.rs @@ -1,4 +1,4 @@ -use ibc_relayer::config::types::MaxMsgNum; +use ibc_relayer::config::{types::MaxMsgNum, ChainConfig}; use ibc_relayer::link::{Link, LinkParameters}; use ibc_relayer::transfer::{build_and_send_transfer_messages, TransferOptions}; use ibc_relayer_types::events::IbcEvent; @@ -48,8 +48,21 @@ impl OrderedChannelClearTest { impl TestOverrides for OrderedChannelClearTest { fn modify_relayer_config(&self, config: &mut Config) { config.mode.packets.tx_confirmation = self.tx_confirmation; - config.chains[0].sequential_batch_tx = self.sequential_batch_tx; - config.chains[1].sequential_batch_tx = self.sequential_batch_tx; + { + let chain_a = &mut config.chains[0]; + match chain_a { + ChainConfig::CosmosSdk(chain_config) => { + chain_config.sequential_batch_tx = self.sequential_batch_tx; + } + } + } + + let chain_b = &mut config.chains[1]; + match chain_b { + ChainConfig::CosmosSdk(chain_config) => { + chain_config.sequential_batch_tx = self.sequential_batch_tx; + } + } } fn should_spawn_supervisor(&self) -> bool { @@ -171,12 +184,23 @@ pub struct OrderedChannelClearEqualCLITest; impl TestOverrides for OrderedChannelClearEqualCLITest { fn modify_relayer_config(&self, config: &mut Config) { config.mode.packets.tx_confirmation = true; + { + let chain_a = &mut config.chains[0]; + match chain_a { + ChainConfig::CosmosSdk(chain_config) => { + chain_config.sequential_batch_tx = true; + chain_config.max_msg_num = MaxMsgNum::new(3).unwrap(); + } + } + } - config.chains[0].sequential_batch_tx = true; - config.chains[0].max_msg_num = MaxMsgNum::new(3).unwrap(); - - config.chains[1].sequential_batch_tx = true; - config.chains[1].max_msg_num = MaxMsgNum::new(3).unwrap(); + let chain_b = &mut config.chains[1]; + match chain_b { + ChainConfig::CosmosSdk(chain_config) => { + chain_config.sequential_batch_tx = true; + chain_config.max_msg_num = MaxMsgNum::new(3).unwrap(); + } + } } fn should_spawn_supervisor(&self) -> bool { diff --git a/tools/integration-test/src/tests/python.rs b/tools/integration-test/src/tests/python.rs index 0fe5cff5ae..29d6457885 100644 --- a/tools/integration-test/src/tests/python.rs +++ b/tools/integration-test/src/tests/python.rs @@ -1,3 +1,4 @@ +use ibc_relayer::config::ChainConfig; use ibc_relayer::keyring::Store; use ibc_test_framework::prelude::*; use std::env; @@ -8,10 +9,14 @@ struct PythonTest; impl TestOverrides for PythonTest { fn modify_relayer_config(&self, config: &mut Config) { for chain in config.chains.iter_mut() { - // Modify the key store type to `Store::Test` so that the wallet - // keys are stored to ~/.hermes/keys so that we can use them - // with external relayer commands. - chain.key_store_type = Store::Test; + match chain { + ChainConfig::CosmosSdk(chain_config) => { + // Modify the key store type to `Store::Test` so that the wallet + // keys are stored to ~/.hermes/keys so that we can use them + // with external relayer commands. + chain_config.key_store_type = Store::Test; + } + } } } diff --git a/tools/integration-test/src/tests/tendermint/sequential.rs b/tools/integration-test/src/tests/tendermint/sequential.rs index b74d2ee366..be9d254873 100644 --- a/tools/integration-test/src/tests/tendermint/sequential.rs +++ b/tools/integration-test/src/tests/tendermint/sequential.rs @@ -2,6 +2,7 @@ use std::time::Instant; use ibc_relayer::chain::tracking::TrackedMsgs; use ibc_relayer::config::types::max_msg_num::MaxMsgNum; +use ibc_relayer::config::ChainConfig; use ibc_test_framework::chain::config; use ibc_test_framework::prelude::*; use ibc_test_framework::relayer::transfer::build_transfer_message; @@ -32,14 +33,19 @@ impl TestOverrides for SequentialCommitTest { fn modify_relayer_config(&self, config: &mut Config) { // Use sequential batching for chain A, and default parallel batching for chain B - - let chain_config_a = &mut config.chains[0]; - chain_config_a.max_msg_num = MaxMsgNum::new(MESSAGES_PER_BATCH).unwrap(); - chain_config_a.sequential_batch_tx = true; - - let chain_config_b = &mut config.chains[1]; - chain_config_b.max_msg_num = MaxMsgNum::new(MESSAGES_PER_BATCH).unwrap(); - chain_config_b.sequential_batch_tx = false; + match &mut config.chains[0] { + ChainConfig::CosmosSdk(chain_config_a) => { + chain_config_a.max_msg_num = MaxMsgNum::new(MESSAGES_PER_BATCH).unwrap(); + chain_config_a.sequential_batch_tx = true; + } + }; + + match &mut config.chains[1] { + ChainConfig::CosmosSdk(chain_config_b) => { + chain_config_b.max_msg_num = MaxMsgNum::new(MESSAGES_PER_BATCH).unwrap(); + chain_config_b.sequential_batch_tx = false; + } + }; } fn should_spawn_supervisor(&self) -> bool { diff --git a/tools/test-framework/Cargo.toml b/tools/test-framework/Cargo.toml index b9540e1141..d89286f158 100644 --- a/tools/test-framework/Cargo.toml +++ b/tools/test-framework/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ibc-test-framework" -version = "0.25.0" +version = "0.26.0" edition = "2021" license = "Apache-2.0" readme = "README.md" @@ -14,10 +14,10 @@ description = """ """ [dependencies] -ibc-relayer-types = { version = "=0.25.0", path = "../../crates/relayer-types" } -ibc-relayer = { version = "=0.25.0", path = "../../crates/relayer" } -ibc-relayer-cli = { version = "=1.6.0", path = "../../crates/relayer-cli" } -ibc-proto = { version = "0.37.0", features = ["serde"] } +ibc-relayer-types = { version = "=0.26.0", path = "../../crates/relayer-types" } +ibc-relayer = { version = "=0.26.0", path = "../../crates/relayer" } +ibc-relayer-cli = { version = "=1.7.0", path = "../../crates/relayer-cli" } +ibc-proto = { version = "0.38.0", features = ["serde"] } tendermint-rpc = { version = "0.34.0", features = ["http-client", "websocket-client"] } http = "0.2.9" diff --git a/tools/test-framework/src/relayer/chain.rs b/tools/test-framework/src/relayer/chain.rs index f4913315ec..bf095d57d9 100644 --- a/tools/test-framework/src/relayer/chain.rs +++ b/tools/test-framework/src/relayer/chain.rs @@ -40,10 +40,10 @@ use ibc_relayer::denom::DenomTrace; use ibc_relayer::error::Error; use ibc_relayer::event::IbcEventWithHeight; use ibc_relayer::keyring::AnySigningKeyPair; -use ibc_relayer::light_client::AnyHeader; use ibc_relayer::misbehaviour::MisbehaviourEvidence; use ibc_relayer_types::applications::ics31_icq::response::CrossChainQueryResponse; use ibc_relayer_types::core::ics02_client::events::UpdateClient; +use ibc_relayer_types::core::ics02_client::header::AnyHeader; use ibc_relayer_types::core::ics03_connection::connection::ConnectionEnd; use ibc_relayer_types::core::ics03_connection::connection::IdentifiedConnectionEnd; use ibc_relayer_types::core::ics03_connection::version::Version; @@ -430,4 +430,8 @@ where ) -> Result { self.value().query_incentivized_packet(request) } + + fn query_consumer_chains(&self) -> Result, Error> { + self.value().query_consumer_chains() + } } diff --git a/tools/test-framework/src/types/single/node.rs b/tools/test-framework/src/types/single/node.rs index 5aeced1f4b..36dbebecc0 100644 --- a/tools/test-framework/src/types/single/node.rs +++ b/tools/test-framework/src/types/single/node.rs @@ -6,7 +6,7 @@ use core::str::FromStr; use core::time::Duration; use eyre::eyre; use eyre::Report as Error; -use ibc_relayer::chain::ChainType; +use ibc_relayer::chain::cosmos::config::CosmosSdkConfig; use ibc_relayer::config; use ibc_relayer::config::gas_multiplier::GasMultiplier; use ibc_relayer::keyring::Store; @@ -134,9 +134,8 @@ impl FullNode { .display() .to_string(); - Ok(config::ChainConfig { + Ok(config::ChainConfig::CosmosSdk(CosmosSdkConfig { id: self.chain_driver.chain_id.clone(), - r#type: ChainType::CosmosSdk, rpc_addr: Url::from_str(&self.chain_driver.rpc_address())?, grpc_addr: Url::from_str(&self.chain_driver.grpc_address())?, event_source: config::EventSourceMode::Push { @@ -171,7 +170,7 @@ impl FullNode { proof_specs: Default::default(), extension_options: Default::default(), sequential_batch_tx: false, - }) + })) } /** diff --git a/tools/test-framework/src/util/interchain_security.rs b/tools/test-framework/src/util/interchain_security.rs index ab7d4e8254..ec808a539c 100644 --- a/tools/test-framework/src/util/interchain_security.rs +++ b/tools/test-framework/src/util/interchain_security.rs @@ -1,3 +1,5 @@ +use ibc_relayer::config::ChainConfig; + use crate::chain::config::set_voting_period; use crate::prelude::*; @@ -19,9 +21,14 @@ pub fn update_relayer_config_for_consumer_chain(config: &mut Config) { // specified in the Consumer chain proposal. The test framework uses 100s in // the proposal. for chain_config in config.chains.iter_mut() { - if chain_config.id == ChainId::from_string("ibcconsumer") { - chain_config.ccv_consumer_chain = true; - chain_config.trusting_period = Some(Duration::from_secs(99)); + match chain_config { + ChainConfig::CosmosSdk(chain_config) + if chain_config.id == ChainId::from_string("ibcconsumer") => + { + chain_config.ccv_consumer_chain = true; + chain_config.trusting_period = Some(Duration::from_secs(99)); + } + ChainConfig::CosmosSdk(_) => {} } } }