From 9e54b8a5e86f5a14fe8727691f30ba811d77168c Mon Sep 17 00:00:00 2001 From: srdtrk Date: Fri, 6 Dec 2024 15:36:17 +0800 Subject: [PATCH 01/26] feat: added boilerplate for tx builder --- .../src/tx_builder/cosmos_to_cosmos.rs | 40 +++++++++++++++++++ packages/relayer-lib/src/tx_builder/mod.rs | 1 + packages/relayer-lib/src/tx_builder/trait.rs | 1 - 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs diff --git a/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs b/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs new file mode 100644 index 000000000..6e3f2533 --- /dev/null +++ b/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs @@ -0,0 +1,40 @@ +//! The `ChainSubmitter` submits txs to [`CosmosSdk`] based on events from [`CosmosSdk`]. + +use anyhow::Result; +use tendermint_rpc::HttpClient; + +use crate::{chain::CosmosSdk, events::EurekaEvent}; + +use super::r#trait::TxBuilderService; + +/// The `TxBuilder` produces txs to [`EthEureka`] based on events from [`CosmosSdk`]. +#[allow(dead_code)] +pub struct TxBuilder { + /// The HTTP client for the source chain. + pub source_tm_client: HttpClient, + /// The HTTP client for the target chain. + pub target_tm_client: HttpClient, +} + +impl TxBuilder { + /// Creates a new `TxBuilder`. + #[must_use] + pub const fn new(source_tm_client: HttpClient, target_tm_client: HttpClient) -> Self { + Self { + source_tm_client, + target_tm_client, + } + } +} + +#[async_trait::async_trait] +impl TxBuilderService for TxBuilder { + async fn relay_events( + &self, + _src_events: Vec, + _target_events: Vec, + _target_channel_id: String, + ) -> Result> { + todo!() + } +} diff --git a/packages/relayer-lib/src/tx_builder/mod.rs b/packages/relayer-lib/src/tx_builder/mod.rs index 48514919..c2feba56 100644 --- a/packages/relayer-lib/src/tx_builder/mod.rs +++ b/packages/relayer-lib/src/tx_builder/mod.rs @@ -1,6 +1,7 @@ //! This module defines the [`TxBuilderService`] trait and some of its implementations. //! This interface is used to generate proofs and submit transactions to a chain. +pub mod cosmos_to_cosmos; #[cfg(feature = "sp1-toolchain")] pub mod eth_eureka; mod r#trait; diff --git a/packages/relayer-lib/src/tx_builder/trait.rs b/packages/relayer-lib/src/tx_builder/trait.rs index b84085cc..61cefaa7 100644 --- a/packages/relayer-lib/src/tx_builder/trait.rs +++ b/packages/relayer-lib/src/tx_builder/trait.rs @@ -5,7 +5,6 @@ use anyhow::Result; /// The `TxBuilderService` trait defines the interface for a service that submits transactions /// to a chain based on events from two chains. #[async_trait::async_trait] -#[allow(dead_code)] pub trait TxBuilderService { /// Generate a transaction to chain A based on the events from chain A and chain B. /// Events from chain A are often used for timeout purposes and can be left empty. From ea835a0c8d9edee4c53b9e1bf2bad87b13f23276 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Fri, 6 Dec 2024 17:04:20 +0800 Subject: [PATCH 02/26] deps: added ibc-proto-eureka and removed reqwest --- Cargo.lock | 185 ++++++++++++---------- Cargo.toml | 2 +- packages/relayer-lib/Cargo.toml | 2 + programs/operator/Cargo.toml | 1 - programs/operator/src/runners/operator.rs | 3 +- 5 files changed, 108 insertions(+), 85 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 20756acd..8011e520 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -79,9 +79,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "alloy" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44ab65cb6104c389b46df77b7990cab08780f57e41b412b46d6d12baf7e8c716" +checksum = "02b0561294ccedc6181e5528b850b4579e3fbde696507baa00109bfd9054c5bb" dependencies = [ "alloy-consensus", "alloy-contract", @@ -103,9 +103,9 @@ dependencies = [ [[package]] name = "alloy-chains" -version = "0.1.47" +version = "0.1.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18c5c520273946ecf715c0010b4e3503d7eba9893cd9ce6b7fff5654c4a3c470" +checksum = "a0161082e0edd9013d23083465cc04b20e44b7a15646d36ba7b0cdb7cd6fe18f" dependencies = [ "alloy-primitives 0.8.14", "num_enum 0.7.3", @@ -114,9 +114,9 @@ dependencies = [ [[package]] name = "alloy-consensus" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73dd0ab7003dfa3efd252e423873cd3bc241d1456147e752f995cc8aabd1d1f6" +checksum = "a101d4d016f47f13890a74290fdd17b05dd175191d9337bc600791fb96e4dea8" dependencies = [ "alloy-eips", "alloy-primitives 0.8.14", @@ -132,9 +132,9 @@ dependencies = [ [[package]] name = "alloy-consensus-any" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d08234c0eece0e08602db5095a16dc942cad91967cccfcfc2c6a42c25563964f" +checksum = "fa60357dda9a3d0f738f18844bd6d0f4a5924cc5cf00bfad2ff1369897966123" dependencies = [ "alloy-consensus", "alloy-eips", @@ -146,9 +146,9 @@ dependencies = [ [[package]] name = "alloy-contract" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a01f5593f6878452c6dde102ece391b60cba79801c5f606f8fe898ff57cd5d7" +checksum = "2869e4fb31331d3b8c58c7db567d1e4e4e94ef64640beda3b6dd9b7045690941" dependencies = [ "alloy-dyn-abi", "alloy-json-abi", @@ -220,9 +220,9 @@ dependencies = [ [[package]] name = "alloy-eips" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c242de43a1869bcb2fbce3b377130959d10dfd562b87ac7aa2f04d98baac51" +checksum = "8b6755b093afef5925f25079dd5a7c8d096398b804ba60cb5275397b06b31689" dependencies = [ "alloy-eip2930", "alloy-eip7702", @@ -238,12 +238,13 @@ dependencies = [ [[package]] name = "alloy-genesis" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd39b72f860cb0c542fac925f91d1939c2b14a0970b39d0ae304b5b7574a0ac" +checksum = "aeec8e6eab6e52b7c9f918748c9b811e87dbef7312a2e3a2ca1729a92966a6af" dependencies = [ "alloy-primitives 0.8.14", "alloy-serde", + "alloy-trie", "serde", ] @@ -261,9 +262,9 @@ dependencies = [ [[package]] name = "alloy-json-rpc" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c15c11661571a19a06896663c93e804ccf013159275a89a98e892014df514d8" +checksum = "4fa077efe0b834bcd89ff4ba547f48fb081e4fdc3673dd7da1b295a2cf2bb7b7" dependencies = [ "alloy-primitives 0.8.14", "alloy-sol-types 0.8.14", @@ -275,9 +276,9 @@ dependencies = [ [[package]] name = "alloy-network" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60dd0b99eaa5e715dd90d42021f7f08a0a70976ea84f41a0ad233770e0c1962b" +checksum = "209a1882a08e21aca4aac6e2a674dc6fcf614058ef8cb02947d63782b1899552" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -300,9 +301,9 @@ dependencies = [ [[package]] name = "alloy-network-primitives" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18abfc73ce48f074c8bc6e05c1f08ef0b1ddc9b04f191a821d0beb9470a42a29" +checksum = "c20219d1ad261da7a6331c16367214ee7ded41d001fabbbd656fbf71898b2773" dependencies = [ "alloy-consensus", "alloy-eips", @@ -313,9 +314,9 @@ dependencies = [ [[package]] name = "alloy-node-bindings" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a04cf8f3a19b024b2bc71b5774d423cd2edda7f67df6029daa1368c5c02da5" +checksum = "bffcf33dd319f21cd6f066d81cbdef0326d4bdaaf7cfe91110bc090707858e9f" dependencies = [ "alloy-genesis", "alloy-primitives 0.8.14", @@ -380,9 +381,9 @@ dependencies = [ [[package]] name = "alloy-provider" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4933c761f10e44d5e901804b56efb2ce6e0945e6c57d2fa1e5ace303fae6f74a" +checksum = "9eefa6f4c798ad01f9b4202d02cea75f5ec11fa180502f4701e2b47965a8c0bb" dependencies = [ "alloy-chains", "alloy-consensus", @@ -424,9 +425,9 @@ dependencies = [ [[package]] name = "alloy-pubsub" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808719714bfb2aa24b0eb2a38411ce8e654ba11c0ebf2a6648fcbe9fabfe696d" +checksum = "aac9a7210e0812b1d814118f426f57eb7fc260a419224dd1c76d169879c06907" dependencies = [ "alloy-json-rpc", "alloy-primitives 0.8.14", @@ -465,9 +466,9 @@ dependencies = [ [[package]] name = "alloy-rpc-client" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce26c25efb8290b6ba559ae6c40bf6630d337e107ae242e5790501420dba7b7" +checksum = "ed30bf1041e84cabc5900f52978ca345dd9969f2194a945e6fdec25b0620705c" dependencies = [ "alloy-json-rpc", "alloy-primitives 0.8.14", @@ -491,9 +492,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41080ce2640928f0df45c41d2af629b88db3cb31af3abbe614964ae10001ddac" +checksum = "5ab686b0fa475d2a4f5916c5f07797734a691ec58e44f0f55d4746ea39cbcefb" dependencies = [ "alloy-primitives 0.8.14", "alloy-rpc-types-engine", @@ -504,9 +505,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-anvil" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "252b7433e731e5d24f7eb7a54a368bc813a1086aaf84643ab10e99599a6ff16c" +checksum = "d33bc190844626c08e21897736dbd7956ab323c09e6f141b118d1c8b7aff689e" dependencies = [ "alloy-primitives 0.8.14", "alloy-rpc-types-eth", @@ -516,9 +517,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-any" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abca110e59f760259e26d0c84912121468008aba48dd227af0f306cfd7bce9ae" +checksum = "200661999b6e235d9840be5d60a6e8ae2f0af9eb2a256dd378786744660e36ec" dependencies = [ "alloy-consensus-any", "alloy-rpc-types-eth", @@ -527,9 +528,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-engine" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3b000c7f3469e7faa575ba70207294cf07e91dfd6ce4d04d5d5d8069f974a66" +checksum = "5d297268357e3eae834ddd6888b15f764cbc0f4b3be9265f5f6ec239013f3d68" dependencies = [ "alloy-consensus", "alloy-eips", @@ -543,9 +544,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-eth" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3468e7385fbb86b0fde5497d685c02f765ea09d36f7e07c5d1c9a52b077d38e2" +checksum = "a0600b8b5e2dc0cab12cbf91b5a885c35871789fb7b3a57b434bd4fced5b7a8b" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -563,9 +564,9 @@ dependencies = [ [[package]] name = "alloy-serde" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42de6002e2154b50b3568aea27e26bd9caf7b754658f43065f2e9b6ee0a8c839" +checksum = "9afa753a97002a33b2ccb707d9f15f31c81b8c1b786c95b73cc62bb1d1fd0c3f" dependencies = [ "alloy-primitives 0.8.14", "serde", @@ -574,9 +575,9 @@ dependencies = [ [[package]] name = "alloy-signer" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f288a9a25e2578dab17845fd8d2be1d32de33565783ed185ded161a65f92381b" +checksum = "9b2cbff01a673936c2efd7e00d4c0e9a4dbbd6d600e2ce298078d33efbb19cd7" dependencies = [ "alloy-primitives 0.8.14", "async-trait", @@ -588,9 +589,9 @@ dependencies = [ [[package]] name = "alloy-signer-local" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8081f589ddc11a959605e30c723d51cad2562d9072305f8e3ef311f077e5eb" +checksum = "bd6d988cb6cd7d2f428a74476515b1a6e901e08c796767f9f93311ab74005c8b" dependencies = [ "alloy-consensus", "alloy-network", @@ -736,9 +737,9 @@ dependencies = [ [[package]] name = "alloy-transport" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90352f4cf78017905c3244f48b38fadc345970bbc9095087c0f985a580550488" +checksum = "d69d36982b9e46075ae6b792b0f84208c6c2c15ad49f6c500304616ef67b70e0" dependencies = [ "alloy-json-rpc", "base64 0.22.1", @@ -756,9 +757,9 @@ dependencies = [ [[package]] name = "alloy-transport-http" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d26c94d51fa8b1aee3d15db113dd0773776c02bb36dbaa2590b900dadd7e7d0" +checksum = "2e02ffd5d93ffc51d72786e607c97de3b60736ca3e636ead0ec1f7dce68ea3fd" dependencies = [ "alloy-json-rpc", "alloy-transport", @@ -771,9 +772,9 @@ dependencies = [ [[package]] name = "alloy-transport-ipc" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c498fcdec50650be6b6a22ce7928a1b2738086b4f94f31b132e83498d45bbb" +checksum = "1b6f8b87cb84bae6d81ae6604b37741c8116f84f9784a0ecc6038c302e679d23" dependencies = [ "alloy-json-rpc", "alloy-pubsub", @@ -790,9 +791,9 @@ dependencies = [ [[package]] name = "alloy-transport-ws" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7b21335b55c9f715e2acca0228dc1d6880d961756916c13a9ce70f9f413e70" +checksum = "9c085c4e1e7680b723ffc558f61a22c061ed3f70eb3436f93f3936779c59cec1" dependencies = [ "alloy-pubsub", "alloy-transport", @@ -808,15 +809,16 @@ dependencies = [ [[package]] name = "alloy-trie" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6b2e366c0debf0af77766c23694a3f863b02633050e71e096e257ffbd395e50" +checksum = "3a5fd8fea044cc9a8c8a50bb6f28e31f0385d820f116c5b98f6f4e55d6e5590b" dependencies = [ "alloy-primitives 0.8.14", "alloy-rlp", "arrayvec", "derive_more 1.0.0", "nybbles", + "serde", "smallvec", "tracing", ] @@ -1035,6 +1037,9 @@ name = "arrayvec" version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +dependencies = [ + "serde", +] [[package]] name = "async-stream" @@ -1518,9 +1523,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.22" +version = "4.5.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69371e34337c4c984bbe322360c2547210bf632eb2814bbe78a6e87a2935bd2b" +checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" dependencies = [ "clap_builder", "clap_derive", @@ -1528,9 +1533,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.22" +version = "4.5.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e24c1b4099818523236a8ca881d2b45db98dadfb4625cf6608c12069fcbbde1" +checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" dependencies = [ "anstream", "anstyle", @@ -1552,9 +1557,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "coins-bip32" @@ -3097,7 +3102,7 @@ dependencies = [ "rustls 0.23.19", "rustls-pki-types", "tokio", - "tokio-rustls 0.26.0", + "tokio-rustls 0.26.1", "tower-service", "webpki-roots", ] @@ -3215,7 +3220,7 @@ dependencies = [ "ibc-core-commitment-types", "ibc-core-host-types", "ibc-primitives", - "ibc-proto", + "ibc-proto 0.51.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde", "tendermint", "tendermint-light-client-verifier", @@ -3235,7 +3240,7 @@ dependencies = [ "ibc-core-connection-types", "ibc-core-host-types", "ibc-primitives", - "ibc-proto", + "ibc-proto 0.51.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde", "sha2 0.10.8", "subtle-encoding", @@ -3284,7 +3289,7 @@ dependencies = [ "ibc-core-commitment-types", "ibc-core-host-types", "ibc-primitives", - "ibc-proto", + "ibc-proto 0.51.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde", "subtle-encoding", "tendermint", @@ -3300,7 +3305,7 @@ dependencies = [ "displaydoc", "ibc-core-host-types", "ibc-primitives", - "ibc-proto", + "ibc-proto 0.51.1 (registry+https://github.com/rust-lang/crates.io-index)", "ics23", "serde", "subtle-encoding", @@ -3318,7 +3323,7 @@ dependencies = [ "ibc-core-commitment-types", "ibc-core-host-types", "ibc-primitives", - "ibc-proto", + "ibc-proto 0.51.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde", "subtle-encoding", "tendermint", @@ -3339,7 +3344,7 @@ dependencies = [ "ibc-core-host-types", "ibc-core-router-types", "ibc-primitives", - "ibc-proto", + "ibc-proto 0.51.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde", "subtle-encoding", "tendermint", @@ -3388,7 +3393,7 @@ dependencies = [ "displaydoc", "ibc-core-host-types", "ibc-primitives", - "ibc-proto", + "ibc-proto 0.51.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde", "subtle-encoding", "tendermint", @@ -3405,6 +3410,7 @@ dependencies = [ "futures", "ibc-core-host-types", "ibc-eureka-solidity-types", + "ibc-proto 0.51.1 (git+https://github.com/srdtrk/ibc-proto-rs?branch=feat%2Fibc-eureka)", "prost", "serde", "sp1-ics07-tendermint-prover", @@ -3439,7 +3445,7 @@ checksum = "bca1c435942806567a4bec4fa6a936f32cc5333e8118d91fb7e001d9d75001c3" dependencies = [ "derive_more 1.0.0", "displaydoc", - "ibc-proto", + "ibc-proto 0.51.1 (registry+https://github.com/rust-lang/crates.io-index)", "prost", "serde", "time", @@ -3463,6 +3469,21 @@ dependencies = [ "tendermint-proto", ] +[[package]] +name = "ibc-proto" +version = "0.51.1" +source = "git+https://github.com/srdtrk/ibc-proto-rs?branch=feat%2Fibc-eureka#17aba4be3626f331d3d2f177f4c2a1123e1ae4a7" +dependencies = [ + "base64 0.22.1", + "bytes", + "cosmos-sdk-proto", + "flex-error", + "ics23", + "prost", + "subtle-encoding", + "tendermint-proto", +] + [[package]] name = "ics23" version = "0.12.0" @@ -4272,6 +4293,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95f06be0417d97f81fe4e5c86d7d01b392655a9cac9c19a848aa033e18937b23" dependencies = [ "const-hex", + "serde", "smallvec", ] @@ -5356,7 +5378,7 @@ dependencies = [ "system-configuration 0.6.1", "tokio", "tokio-native-tls", - "tokio-rustls 0.26.0", + "tokio-rustls 0.26.1", "tokio-util", "tower-service", "url", @@ -6105,6 +6127,9 @@ name = "smallvec" version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +dependencies = [ + "serde", +] [[package]] name = "snowbridge-amcl" @@ -6290,7 +6315,7 @@ dependencies = [ "bincode", "ibc-core-commitment-types", "ibc-eureka-solidity-types", - "ibc-proto", + "ibc-proto 0.51.1 (registry+https://github.com/rust-lang/crates.io-index)", "sp1-zkvm", ] @@ -6329,8 +6354,7 @@ dependencies = [ "ibc-core-client-types", "ibc-core-commitment-types", "ibc-eureka-solidity-types", - "ibc-proto", - "reqwest 0.12.9", + "ibc-proto 0.51.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde", "serde_json", "serde_with", @@ -6353,7 +6377,7 @@ dependencies = [ "ibc-client-tendermint-types", "ibc-core-commitment-types", "ibc-eureka-solidity-types", - "ibc-proto", + "ibc-proto 0.51.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_cbor", "sp1-helper", "sp1-sdk", @@ -6369,7 +6393,7 @@ dependencies = [ "ibc-client-tendermint-types", "ibc-core-commitment-types", "ibc-eureka-solidity-types", - "ibc-proto", + "ibc-proto 0.51.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_cbor", "sp1-ics07-tendermint-membership", "sp1-ics07-tendermint-update-client", @@ -7215,12 +7239,11 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" dependencies = [ "rustls 0.23.19", - "rustls-pki-types", "tokio", ] @@ -7247,16 +7270,16 @@ dependencies = [ "rustls 0.23.19", "rustls-pki-types", "tokio", - "tokio-rustls 0.26.0", + "tokio-rustls 0.26.1", "tungstenite", "webpki-roots", ] [[package]] name = "tokio-util" -version = "0.7.12" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" dependencies = [ "bytes", "futures-core", diff --git a/Cargo.toml b/Cargo.toml index ff10f5cb..9bfb4099 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,7 +38,6 @@ tokio = { version = "1.0", default-features = false } axum = { version = "0.7", default-features = false } tonic = { version = "0.12", default-features = false } tonic-build = { version = "0.12", default-features = false } -reqwest = { version = "0.12", default-features = false } tracing = { version = "0.1", default-features = false } tracing-subscriber = { version = "0.3", default-features = false } @@ -54,6 +53,7 @@ tendermint-rpc = { version = "0.40", default-features = false tendermint-light-client-verifier = { version = "0.40", default-features = false } ibc-proto = { version = "0.51", default-features = false } +ibc-proto-eureka = { package = "ibc-proto", git = "https://github.com/srdtrk/ibc-proto-rs", branch = "feat/ibc-eureka", default-features = false } cosmos-sdk-proto = { version = "0.26", default-features = false } ibc-primitives = { version = "0.56", default-features = false } diff --git a/packages/relayer-lib/Cargo.toml b/packages/relayer-lib/Cargo.toml index 3c6f0ada..3d58a36c 100644 --- a/packages/relayer-lib/Cargo.toml +++ b/packages/relayer-lib/Cargo.toml @@ -27,6 +27,8 @@ tracing = { workspace = true, default-features = true } tendermint = { workspace = true, features = ["std"] } tendermint-rpc = { workspace = true, features = ["http-client"] } +ibc-proto-eureka = { workspace = true } + ibc-core-host-types = { workspace = true } alloy = { workspace = true, features = ["full", "node-bindings"] } diff --git a/programs/operator/Cargo.toml b/programs/operator/Cargo.toml index 91c46a3e..0a30b073 100644 --- a/programs/operator/Cargo.toml +++ b/programs/operator/Cargo.toml @@ -14,7 +14,6 @@ serde_with = { workspace = true, features = ["hex", "macros"] } hex = { workspace = true } subtle-encoding = { workspace = true } -reqwest = { workspace = true } tokio = { workspace = true } futures = { workspace = true } dotenv = { workspace = true } diff --git a/programs/operator/src/runners/operator.rs b/programs/operator/src/runners/operator.rs index ac5a0b15..0e71613d 100644 --- a/programs/operator/src/runners/operator.rs +++ b/programs/operator/src/runners/operator.rs @@ -9,7 +9,6 @@ use anyhow::anyhow; use ibc_eureka_solidity_types::sp1_ics07::{ sp1_ics07_tendermint, ISP1Msgs::SP1Proof, IUpdateClientMsgs::MsgUpdateClient, }; -use reqwest::Url; use sp1_ics07_tendermint_prover::{ programs::UpdateClientProgram, prover::{SP1ICS07TendermintProver, SupportedProofType}, @@ -35,7 +34,7 @@ pub async fn run(args: Args) -> anyhow::Result<()> { let provider = ProviderBuilder::new() .with_recommended_fillers() .wallet(wallet) - .on_http(Url::parse(rpc_url.as_str())?); + .on_http(rpc_url.parse()?); let contract = sp1_ics07_tendermint::new(contract_address.parse()?, provider); let contract_client_state = contract.getClientState().call().await?._0; From a6080aeb5c323d06576fe6984df23664a48154ae Mon Sep 17 00:00:00 2001 From: srdtrk Date: Fri, 6 Dec 2024 17:30:42 +0800 Subject: [PATCH 03/26] imp: added helper rpc methods --- .../src/tx_builder/cosmos_to_cosmos.rs | 26 ++++++++++++++++++- packages/utils/src/rpc.rs | 19 ++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs b/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs index 6e3f2533..3302686f 100644 --- a/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs +++ b/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs @@ -1,7 +1,12 @@ //! The `ChainSubmitter` submits txs to [`CosmosSdk`] based on events from [`CosmosSdk`]. use anyhow::Result; -use tendermint_rpc::HttpClient; +use ibc_proto_eureka::ibc::core::channel::v2::{ + Channel, QueryChannelRequest, QueryChannelResponse, +}; +use prost::Message; +//use sp1_ics07_tendermint_utils::rpc::TendermintRpcExt; +use tendermint_rpc::{Client, HttpClient}; use crate::{chain::CosmosSdk, events::EurekaEvent}; @@ -25,6 +30,25 @@ impl TxBuilder { target_tm_client, } } + + /// Fetches the eureka channel state from the target chain. + /// # Errors + /// Returns an error if the channel state cannot be fetched or decoded. + pub async fn channel(&self, channel_id: String) -> Result { + let abci_resp = self + .target_tm_client + .abci_query( + Some("/ibc.core.channel.v2.Query/Channel".to_string()), + QueryChannelRequest { channel_id }.encode_to_vec(), + None, + false, + ) + .await?; + + QueryChannelResponse::decode(abci_resp.value.as_slice())? + .channel + .ok_or_else(|| anyhow::anyhow!("No channel state found")) + } } #[async_trait::async_trait] diff --git a/packages/utils/src/rpc.rs b/packages/utils/src/rpc.rs index f6908185..e12d9388 100644 --- a/packages/utils/src/rpc.rs +++ b/packages/utils/src/rpc.rs @@ -9,7 +9,9 @@ use cosmos_sdk_proto::{ cosmos::staking::v1beta1::{Params, QueryParamsRequest, QueryParamsResponse}, prost::Message, traits::MessageExt, + Any, }; +use ibc_core_client_types::proto::v1::{QueryClientStateRequest, QueryClientStateResponse}; use tendermint::{block::signed_header::SignedHeader, validator::Set}; use tendermint_light_client_verifier::types::{LightBlock, ValidatorSet}; use tendermint_rpc::{Client, HttpClient, Paging, Url}; @@ -33,6 +35,8 @@ pub trait TendermintRpcExt { async fn get_light_block(&self, block_height: Option) -> Result; /// Queries the Cosmos SDK for staking parameters. async fn sdk_staking_params(&self) -> Result; + /// Fetches the client state from the Tendermint node. + async fn client_state(&self, client_id: String) -> Result; } #[async_trait::async_trait] @@ -91,6 +95,21 @@ impl TendermintRpcExt for HttpClient { .params .ok_or_else(|| anyhow::anyhow!("No staking params found")) } + + async fn client_state(&self, client_id: String) -> Result { + let abci_resp = self + .abci_query( + Some("/ibc.core.client.v1.Query/ClientState".to_string()), + QueryClientStateRequest { client_id }.to_bytes()?, + None, + false, + ) + .await?; + + QueryClientStateResponse::decode(abci_resp.value.as_slice())? + .client_state + .ok_or_else(|| anyhow::anyhow!("No client state found")) + } } /// Sorts the signatures in the signed header based on the descending order of validators' power. From f52d7256b977932524703b1705b8653143c51fc2 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Fri, 6 Dec 2024 19:12:16 +0800 Subject: [PATCH 04/26] imp: save progress --- .../src/tx_builder/cosmos_to_cosmos.rs | 42 ++++++++++++++++--- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs b/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs index 3302686f..6c8d7397 100644 --- a/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs +++ b/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs @@ -1,11 +1,13 @@ //! The `ChainSubmitter` submits txs to [`CosmosSdk`] based on events from [`CosmosSdk`]. use anyhow::Result; -use ibc_proto_eureka::ibc::core::channel::v2::{ - Channel, QueryChannelRequest, QueryChannelResponse, +use futures::future; +use ibc_proto_eureka::ibc::{ + core::channel::v2::{Channel, QueryChannelRequest, QueryChannelResponse}, + lightclients::tendermint::v1::ClientState, }; use prost::Message; -//use sp1_ics07_tendermint_utils::rpc::TendermintRpcExt; +use sp1_ics07_tendermint_utils::rpc::TendermintRpcExt; use tendermint_rpc::{Client, HttpClient}; use crate::{chain::CosmosSdk, events::EurekaEvent}; @@ -56,9 +58,39 @@ impl TxBuilderService for TxBuilder { async fn relay_events( &self, _src_events: Vec, - _target_events: Vec, - _target_channel_id: String, + target_events: Vec, + target_channel_id: String, ) -> Result> { + let now = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH)? + .as_secs(); + + let channel = self.channel(target_channel_id).await?; + let client_state = ClientState::decode( + self.target_tm_client + .client_state(channel.client_id) + .await? + .value + .as_slice(), + )?; + + let light_block = self.source_tm_client.get_light_block(None).await?; + + //let timeout_msgs = future::try_join_all(target_events.into_iter().filter_map(|e| async { + // match e { + // EurekaEvent::SendPacket(se) => { + // if now >= se.packet.timeoutTimestamp + // && se.packet.sourceChannel == target_channel_id + // { + // todo!() + // } else { + // None + // } + // } + // _ => None, + // } + //})); + todo!() } } From f4a2011c7d895558f397f25356b0e4af0245eda7 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Sat, 7 Dec 2024 12:03:04 +0800 Subject: [PATCH 05/26] imp: save progress --- packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs b/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs index 6c8d7397..6ecf5ae9 100644 --- a/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs +++ b/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs @@ -82,6 +82,7 @@ impl TxBuilderService for TxBuilder { // if now >= se.packet.timeoutTimestamp // && se.packet.sourceChannel == target_channel_id // { + // let ibc_path = se.packet.receipt_commitment_path(); // todo!() // } else { // None From 6f94380b3332f8de1f98e0c9a661859558a001fe Mon Sep 17 00:00:00 2001 From: srdtrk Date: Sat, 7 Dec 2024 15:39:02 +0800 Subject: [PATCH 06/26] imp: save progress --- packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs b/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs index 6ecf5ae9..979120b1 100644 --- a/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs +++ b/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs @@ -3,7 +3,7 @@ use anyhow::Result; use futures::future; use ibc_proto_eureka::ibc::{ - core::channel::v2::{Channel, QueryChannelRequest, QueryChannelResponse}, + core::channel::v2::{Channel, MsgTimeout, QueryChannelRequest, QueryChannelResponse}, lightclients::tendermint::v1::ClientState, }; use prost::Message; @@ -75,6 +75,7 @@ impl TxBuilderService for TxBuilder { )?; let light_block = self.source_tm_client.get_light_block(None).await?; + let target_height = light_block.height().value().try_into()?; //let timeout_msgs = future::try_join_all(target_events.into_iter().filter_map(|e| async { // match e { @@ -83,6 +84,11 @@ impl TxBuilderService for TxBuilder { // && se.packet.sourceChannel == target_channel_id // { // let ibc_path = se.packet.receipt_commitment_path(); + // let (value, proof) = self + // .source_tm_client + // .prove_path(vec![b"ibc", ibc_path], target_height) + // .await.map(|v, p| MsgTimeout { + // }) // todo!() // } else { // None From 897df2bf79e8689e3248004aac2a7c988fc819fe Mon Sep 17 00:00:00 2001 From: srdtrk Date: Mon, 9 Dec 2024 16:56:09 +0800 Subject: [PATCH 07/26] imp: constructed timeout messages --- .../src/tx_builder/cosmos_to_cosmos.rs | 78 +++++++++++++------ .../relayer-lib/src/tx_builder/eth_eureka.rs | 2 + packages/solidity/src/ics26.rs | 24 ++++++ 3 files changed, 80 insertions(+), 24 deletions(-) diff --git a/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs b/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs index 979120b1..52045167 100644 --- a/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs +++ b/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs @@ -2,9 +2,15 @@ use anyhow::Result; use futures::future; -use ibc_proto_eureka::ibc::{ - core::channel::v2::{Channel, MsgTimeout, QueryChannelRequest, QueryChannelResponse}, - lightclients::tendermint::v1::ClientState, +use ibc_proto_eureka::{ + ibc::{ + core::{ + channel::v2::{Channel, MsgTimeout, QueryChannelRequest, QueryChannelResponse}, + client::v1::Height, + }, + lightclients::tendermint::v1::ClientState, + }, + Protobuf, }; use prost::Message; use sp1_ics07_tendermint_utils::rpc::TendermintRpcExt; @@ -65,7 +71,7 @@ impl TxBuilderService for TxBuilder { .duration_since(std::time::UNIX_EPOCH)? .as_secs(); - let channel = self.channel(target_channel_id).await?; + let channel = self.channel(target_channel_id.clone()).await?; let client_state = ClientState::decode( self.target_tm_client .client_state(channel.client_id) @@ -77,26 +83,50 @@ impl TxBuilderService for TxBuilder { let light_block = self.source_tm_client.get_light_block(None).await?; let target_height = light_block.height().value().try_into()?; - //let timeout_msgs = future::try_join_all(target_events.into_iter().filter_map(|e| async { - // match e { - // EurekaEvent::SendPacket(se) => { - // if now >= se.packet.timeoutTimestamp - // && se.packet.sourceChannel == target_channel_id - // { - // let ibc_path = se.packet.receipt_commitment_path(); - // let (value, proof) = self - // .source_tm_client - // .prove_path(vec![b"ibc", ibc_path], target_height) - // .await.map(|v, p| MsgTimeout { - // }) - // todo!() - // } else { - // None - // } - // } - // _ => None, - // } - //})); + let _timeout_msgs = future::try_join_all( + target_events + .into_iter() + .filter(|e| match e { + EurekaEvent::SendPacket(se) => { + now >= se.packet.timeoutTimestamp + && se.packet.sourceChannel == target_channel_id + } + _ => false, + }) + .map(|e| async { + match e { + EurekaEvent::SendPacket(se) => { + let ibc_path = se.packet.receipt_commitment_path(); + self.source_tm_client + .prove_path(&[b"ibc".to_vec(), ibc_path], target_height) + .await + .map(|(v, p)| { + if v.is_empty() { + Some(MsgTimeout { + packet: Some(se.packet.into()), + proof_unreceived: p.encode_vec(), + proof_height: Some(Height { + revision_number: client_state + .latest_height + .unwrap_or_default() + .revision_number, + revision_height: target_height.into(), + }), + signer: String::new(), + }) + } else { + None + } + }) + } + _ => unreachable!(), + } + }), + ) + .await? + .into_iter() + .flatten() + .collect::>(); todo!() } diff --git a/packages/relayer-lib/src/tx_builder/eth_eureka.rs b/packages/relayer-lib/src/tx_builder/eth_eureka.rs index 9d537fb7..867a89c9 100644 --- a/packages/relayer-lib/src/tx_builder/eth_eureka.rs +++ b/packages/relayer-lib/src/tx_builder/eth_eureka.rs @@ -146,6 +146,8 @@ where _ => None, }); + // TODO: We might wanna filter out send packets that have been actually received + let recv_and_ack_msgs = src_events.into_iter().filter_map(|e| match e { EurekaEvent::SendPacket(se) => { if se.packet.timeoutTimestamp > now && se.packet.destChannel == filter_channel { diff --git a/packages/solidity/src/ics26.rs b/packages/solidity/src/ics26.rs index 65f75164..ea120513 100644 --- a/packages/solidity/src/ics26.rs +++ b/packages/solidity/src/ics26.rs @@ -66,6 +66,18 @@ impl TryFrom for IICS26RouterMsgs::Packet { } } +impl From for Packet { + fn from(packet: IICS26RouterMsgs::Packet) -> Self { + Self { + sequence: packet.sequence.into(), + source_channel: packet.sourceChannel, + destination_channel: packet.destChannel, + timeout_timestamp: packet.timeoutTimestamp, + payloads: packet.payloads.into_iter().map(Into::into).collect(), + } + } +} + impl From for IICS26RouterMsgs::Payload { fn from(payload: Payload) -> Self { Self { @@ -77,3 +89,15 @@ impl From for IICS26RouterMsgs::Payload { } } } + +impl From for Payload { + fn from(payload: IICS26RouterMsgs::Payload) -> Self { + Self { + source_port: payload.sourcePort, + destination_port: payload.destPort, + version: payload.version, + encoding: payload.encoding, + value: payload.value.into(), + } + } +} From 2e8ba3b957d4b8438e1d756b101768774add1fe1 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Mon, 9 Dec 2024 17:11:51 +0800 Subject: [PATCH 08/26] imp: added _recv_msgs --- .../src/tx_builder/cosmos_to_cosmos.rs | 52 ++++++++++++++++++- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs b/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs index 52045167..b88c6219 100644 --- a/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs +++ b/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs @@ -5,7 +5,9 @@ use futures::future; use ibc_proto_eureka::{ ibc::{ core::{ - channel::v2::{Channel, MsgTimeout, QueryChannelRequest, QueryChannelResponse}, + channel::v2::{ + Channel, MsgRecvPacket, MsgTimeout, QueryChannelRequest, QueryChannelResponse, + }, client::v1::Height, }, lightclients::tendermint::v1::ClientState, @@ -61,9 +63,10 @@ impl TxBuilder { #[async_trait::async_trait] impl TxBuilderService for TxBuilder { + #[allow(clippy::too_many_lines)] async fn relay_events( &self, - _src_events: Vec, + src_events: Vec, target_events: Vec, target_channel_id: String, ) -> Result> { @@ -128,6 +131,51 @@ impl TxBuilderService for TxBuilder { .flatten() .collect::>(); + let _recv_msgs = future::try_join_all( + src_events + .into_iter() + .filter(|e| match e { + EurekaEvent::SendPacket(se) => { + se.packet.timeoutTimestamp > now + && se.packet.destChannel == target_channel_id + } + _ => false, + }) + .map(|e| async { + match e { + EurekaEvent::SendPacket(se) => { + let ibc_path = se.packet.commitment_path(); + self.source_tm_client + .prove_path(&[b"ibc".to_vec(), ibc_path], target_height) + .await + .map(|(v, p)| { + if v.is_empty() { + Some(MsgRecvPacket { + packet: Some(se.packet.into()), + proof_height: Some(Height { + revision_number: client_state + .latest_height + .unwrap_or_default() + .revision_number, + revision_height: target_height.into(), + }), + proof_commitment: p.encode_vec(), + signer: String::new(), + }) + } else { + None + } + }) + } + _ => unreachable!(), + } + }), + ) + .await? + .into_iter() + .flatten() + .collect::>(); + todo!() } } From 50fb45307f4e1330eb466c731a530f9021f5cdeb Mon Sep 17 00:00:00 2001 From: srdtrk Date: Tue, 10 Dec 2024 11:27:11 +0800 Subject: [PATCH 09/26] imp: all msgs added --- .../src/tx_builder/cosmos_to_cosmos.rs | 114 ++++++++++++------ 1 file changed, 75 insertions(+), 39 deletions(-) diff --git a/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs b/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs index b88c6219..8a449515 100644 --- a/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs +++ b/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs @@ -131,51 +131,87 @@ impl TxBuilderService for TxBuilder { .flatten() .collect::>(); - let _recv_msgs = future::try_join_all( - src_events - .into_iter() - .filter(|e| match e { - EurekaEvent::SendPacket(se) => { - se.packet.timeoutTimestamp > now - && se.packet.destChannel == target_channel_id - } - _ => false, - }) - .map(|e| async { - match e { - EurekaEvent::SendPacket(se) => { - let ibc_path = se.packet.commitment_path(); - self.source_tm_client - .prove_path(&[b"ibc".to_vec(), ibc_path], target_height) - .await - .map(|(v, p)| { - if v.is_empty() { - Some(MsgRecvPacket { - packet: Some(se.packet.into()), - proof_height: Some(Height { - revision_number: client_state - .latest_height - .unwrap_or_default() - .revision_number, - revision_height: target_height.into(), - }), - proof_commitment: p.encode_vec(), - signer: String::new(), - }) - } else { - None - } + let (src_send_events, src_ack_events): (Vec<_>, Vec<_>) = src_events + .into_iter() + .filter(|e| match e { + EurekaEvent::SendPacket(se) => { + se.packet.timeoutTimestamp > now && se.packet.destChannel == target_channel_id + } + EurekaEvent::WriteAcknowledgement(we) => { + we.packet.sourceChannel == target_channel_id + } + _ => false, + }) + .partition(|e| match e { + EurekaEvent::SendPacket(_) => true, + EurekaEvent::WriteAcknowledgement(_) => false, + _ => unreachable!(), + }); + + let _recv_msgs = future::try_join_all(src_send_events.into_iter().map(|e| async { + match e { + EurekaEvent::SendPacket(se) => { + let ibc_path = se.packet.commitment_path(); + self.source_tm_client + .prove_path(&[b"ibc".to_vec(), ibc_path], target_height) + .await + .map(|(v, p)| { + if v.is_empty() { + Some(MsgRecvPacket { + packet: Some(se.packet.into()), + proof_height: Some(Height { + revision_number: client_state + .latest_height + .unwrap_or_default() + .revision_number, + revision_height: target_height.into(), + }), + proof_commitment: p.encode_vec(), + signer: String::new(), }) - } - _ => unreachable!(), - } - }), - ) + } else { + None + } + }) + } + _ => unreachable!(), + } + })) .await? .into_iter() .flatten() .collect::>(); + let _ack_msgs = future::try_join_all(src_ack_events.into_iter().map(|e| async { + match e { + EurekaEvent::WriteAcknowledgement(we) => { + let ibc_path = we.packet.ack_commitment_path(); + self.source_tm_client + .prove_path(&[b"ibc".to_vec(), ibc_path], target_height) + .await + .map(|(v, p)| { + if v.is_empty() { + Some(MsgRecvPacket { + packet: Some(we.packet.into()), + proof_height: Some(Height { + revision_number: client_state + .latest_height + .unwrap_or_default() + .revision_number, + revision_height: target_height.into(), + }), + proof_commitment: p.encode_vec(), + signer: String::new(), + }) + } else { + None + } + }) + } + _ => unreachable!(), + } + })); + todo!() } } From b1dcc896bc70eda9ab1b981491c1debaf0d1c0d9 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Tue, 10 Dec 2024 16:22:40 +0800 Subject: [PATCH 10/26] imp: constructed update msg --- .../src/tx_builder/cosmos_to_cosmos.rs | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs b/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs index 8a449515..eefc770c 100644 --- a/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs +++ b/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs @@ -8,14 +8,14 @@ use ibc_proto_eureka::{ channel::v2::{ Channel, MsgRecvPacket, MsgTimeout, QueryChannelRequest, QueryChannelResponse, }, - client::v1::Height, + client::v1::{Height, MsgUpdateClient}, }, lightclients::tendermint::v1::ClientState, }, Protobuf, }; use prost::Message; -use sp1_ics07_tendermint_utils::rpc::TendermintRpcExt; +use sp1_ics07_tendermint_utils::{light_block::LightBlockExt, rpc::TendermintRpcExt}; use tendermint_rpc::{Client, HttpClient}; use crate::{chain::CosmosSdk, events::EurekaEvent}; @@ -77,14 +77,14 @@ impl TxBuilderService for TxBuilder { let channel = self.channel(target_channel_id.clone()).await?; let client_state = ClientState::decode( self.target_tm_client - .client_state(channel.client_id) + .client_state(channel.client_id.clone()) .await? .value .as_slice(), )?; - let light_block = self.source_tm_client.get_light_block(None).await?; - let target_height = light_block.height().value().try_into()?; + let target_light_block = self.source_tm_client.get_light_block(None).await?; + let target_height = target_light_block.height().value().try_into()?; let _timeout_msgs = future::try_join_all( target_events @@ -212,6 +212,25 @@ impl TxBuilderService for TxBuilder { } })); + let trusted_light_block = self + .source_tm_client + .get_light_block(Some( + client_state + .latest_height + .ok_or_else(|| anyhow::anyhow!("No latest height found"))? + .revision_height + .try_into()?, + )) + .await?; + + let proposed_header = target_light_block.into_header(&trusted_light_block); + + let _update_msg = MsgUpdateClient { + client_id: channel.client_id, + client_message: Some(proposed_header.into()), + signer: String::new(), + }; + todo!() } } From fd7ebebda62fe55bc8d4b19116aca5dfe25f90c4 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Tue, 10 Dec 2024 16:38:34 +0800 Subject: [PATCH 11/26] feat: added the basics of the module --- .../relayer/src/modules/cosmos_to_cosmos.rs | 32 +++++++++++++++++++ programs/relayer/src/modules/cosmos_to_eth.rs | 15 ++++----- programs/relayer/src/modules/mod.rs | 1 + 3 files changed, 40 insertions(+), 8 deletions(-) create mode 100644 programs/relayer/src/modules/cosmos_to_cosmos.rs diff --git a/programs/relayer/src/modules/cosmos_to_cosmos.rs b/programs/relayer/src/modules/cosmos_to_cosmos.rs new file mode 100644 index 000000000..34401294 --- /dev/null +++ b/programs/relayer/src/modules/cosmos_to_cosmos.rs @@ -0,0 +1,32 @@ +//! Defines Cosmos to Cosmos relayer module. + +use ibc_eureka_relayer_lib::{listener::cosmos_sdk, tx_builder::cosmos_to_cosmos}; + +/// The `CosmosToCosmosRelayerModule` struct defines the Cosmos to Cosmos relayer module. +#[derive(Clone, Copy, Debug)] +#[allow(clippy::module_name_repetitions)] +pub struct CosmosToCosmosRelayerModule; + +/// The `CosmosToCosmosRelayerModuleServer` defines the relayer server from Cosmos to Cosmos. +#[allow(dead_code)] +struct CosmosToCosmosRelayerModuleServer { + /// The souce chain listener for Cosmos SDK. + pub src_listener: cosmos_sdk::ChainListener, + /// The target chain listener for Cosmos SDK. + pub target_listener: cosmos_sdk::ChainListener, + /// The transaction builder from Cosmos to Cosmos. + pub tx_builder: cosmos_to_cosmos::TxBuilder, +} + +/// The configuration for the Cosmos to Cosmos relayer module. +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] +#[allow(clippy::module_name_repetitions)] +pub struct CosmosToCosmosConfig { + /// The source tendermint RPC URL. + pub src_rpc_url: String, + /// The target tendermint RPC URL. + pub target_rpc_url: String, + /// The address of the submitter. + /// Required since cosmos messages require a signer address. + pub signer_address: String, +} diff --git a/programs/relayer/src/modules/cosmos_to_eth.rs b/programs/relayer/src/modules/cosmos_to_eth.rs index 087e5bfc..96dadf40 100644 --- a/programs/relayer/src/modules/cosmos_to_eth.rs +++ b/programs/relayer/src/modules/cosmos_to_eth.rs @@ -28,15 +28,14 @@ use crate::{ #[allow(clippy::module_name_repetitions)] pub struct CosmosToEthRelayerModule; -/// The `RelayerModule` defines the relayer module for Cosmos to Ethereum. -#[allow(clippy::module_name_repetitions)] +/// The `CosmosToEthRelayerModuleServer` defines the relayer server from Cosmos to Ethereum. struct CosmosToEthRelayerModuleServer { /// The chain listener for Cosmos SDK. pub tm_listener: cosmos_sdk::ChainListener, /// The chain listener for `EthEureka`. pub eth_listener: eth_eureka::ChainListener>, - /// The chain submitter for `EthEureka`. - pub submitter: TxBuilder>, + /// The transaction builder for `EthEureka`. + pub tx_builder: TxBuilder>, } /// The configuration for the Cosmos to Ethereum relayer module. @@ -79,7 +78,7 @@ impl CosmosToEthRelayerModuleServer { Self { tm_listener, eth_listener, - submitter, + tx_builder: submitter, } } } @@ -100,7 +99,7 @@ impl RelayerService for CosmosToEthRelayerModuleServer { .await .map_err(|e| tonic::Status::from_error(e.to_string().into()))?, ibc_version: "2".to_string(), - ibc_contract: self.submitter.ics26_router.address().to_string(), + ibc_contract: self.tx_builder.ics26_router.address().to_string(), }), source_chain: Some(api::Chain { chain_id: self @@ -158,7 +157,7 @@ impl RelayerService for CosmosToEthRelayerModuleServer { tracing::info!("Fetched {} eureka events from EVM.", eth_events.len()); let multicall_tx = self - .submitter + .tx_builder .relay_events(cosmos_events, eth_events, inner_req.target_channel_id) .await .map_err(|e| tonic::Status::from_error(e.to_string().into()))?; @@ -167,7 +166,7 @@ impl RelayerService for CosmosToEthRelayerModuleServer { Ok(Response::new(api::RelayByTxResponse { tx: multicall_tx, - address: self.submitter.ics26_router.address().to_string(), + address: self.tx_builder.ics26_router.address().to_string(), })) } } diff --git a/programs/relayer/src/modules/mod.rs b/programs/relayer/src/modules/mod.rs index 2c632146..2c2f0d62 100644 --- a/programs/relayer/src/modules/mod.rs +++ b/programs/relayer/src/modules/mod.rs @@ -1,3 +1,4 @@ //! Includes one-sided relayer modules +pub mod cosmos_to_cosmos; pub mod cosmos_to_eth; From ad120119fed8cbaf63fd33b0bb8475782d49a02a Mon Sep 17 00:00:00 2001 From: srdtrk Date: Tue, 10 Dec 2024 16:48:28 +0800 Subject: [PATCH 12/26] feat: added constructor for server --- .../src/tx_builder/cosmos_to_cosmos.rs | 19 +++++++---- .../relayer/src/modules/cosmos_to_cosmos.rs | 33 +++++++++++++++++++ 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs b/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs index eefc770c..15af1f98 100644 --- a/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs +++ b/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs @@ -22,22 +22,29 @@ use crate::{chain::CosmosSdk, events::EurekaEvent}; use super::r#trait::TxBuilderService; -/// The `TxBuilder` produces txs to [`EthEureka`] based on events from [`CosmosSdk`]. +/// The `TxBuilder` produces txs to [`CosmosSdk`] based on events from [`CosmosSdk`]. #[allow(dead_code)] pub struct TxBuilder { /// The HTTP client for the source chain. pub source_tm_client: HttpClient, /// The HTTP client for the target chain. pub target_tm_client: HttpClient, + /// The signer address for the Cosmos messages. + pub signer_address: String, } impl TxBuilder { /// Creates a new `TxBuilder`. #[must_use] - pub const fn new(source_tm_client: HttpClient, target_tm_client: HttpClient) -> Self { + pub const fn new( + source_tm_client: HttpClient, + target_tm_client: HttpClient, + signer_address: String, + ) -> Self { Self { source_tm_client, target_tm_client, + signer_address, } } @@ -115,7 +122,7 @@ impl TxBuilderService for TxBuilder { .revision_number, revision_height: target_height.into(), }), - signer: String::new(), + signer: self.signer_address.clone(), }) } else { None @@ -167,7 +174,7 @@ impl TxBuilderService for TxBuilder { revision_height: target_height.into(), }), proof_commitment: p.encode_vec(), - signer: String::new(), + signer: self.signer_address.clone(), }) } else { None @@ -201,7 +208,7 @@ impl TxBuilderService for TxBuilder { revision_height: target_height.into(), }), proof_commitment: p.encode_vec(), - signer: String::new(), + signer: self.signer_address.clone(), }) } else { None @@ -228,7 +235,7 @@ impl TxBuilderService for TxBuilder { let _update_msg = MsgUpdateClient { client_id: channel.client_id, client_message: Some(proposed_header.into()), - signer: String::new(), + signer: self.signer_address.clone(), }; todo!() diff --git a/programs/relayer/src/modules/cosmos_to_cosmos.rs b/programs/relayer/src/modules/cosmos_to_cosmos.rs index 34401294..900f37ef 100644 --- a/programs/relayer/src/modules/cosmos_to_cosmos.rs +++ b/programs/relayer/src/modules/cosmos_to_cosmos.rs @@ -1,6 +1,9 @@ //! Defines Cosmos to Cosmos relayer module. +use std::str::FromStr; + use ibc_eureka_relayer_lib::{listener::cosmos_sdk, tx_builder::cosmos_to_cosmos}; +use tendermint_rpc::{HttpClient, Url}; /// The `CosmosToCosmosRelayerModule` struct defines the Cosmos to Cosmos relayer module. #[derive(Clone, Copy, Debug)] @@ -30,3 +33,33 @@ pub struct CosmosToCosmosConfig { /// Required since cosmos messages require a signer address. pub signer_address: String, } + +impl CosmosToCosmosRelayerModuleServer { + #[allow(dead_code)] + fn new(config: CosmosToCosmosConfig) -> Self { + let src_client = HttpClient::new( + Url::from_str(&config.src_rpc_url) + .unwrap_or_else(|_| panic!("invalid tendermint RPC URL: {}", config.src_rpc_url)), + ) + .expect("Failed to create tendermint HTTP client"); + + let src_listener = cosmos_sdk::ChainListener::new(src_client.clone()); + + let target_client = + HttpClient::new(Url::from_str(&config.target_rpc_url).unwrap_or_else(|_| { + panic!("invalid tendermint RPC URL: {}", config.target_rpc_url) + })) + .expect("Failed to create tendermint HTTP client"); + + let target_listener = cosmos_sdk::ChainListener::new(target_client.clone()); + + let tx_builder = + cosmos_to_cosmos::TxBuilder::new(src_client, target_client, config.signer_address); + + Self { + src_listener, + target_listener, + tx_builder, + } + } +} From 82581226d26e4bacd0f01341dd5089cb8e0e7481 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Tue, 10 Dec 2024 17:00:29 +0800 Subject: [PATCH 13/26] feat: implemented 'RelayerService' --- .../relayer/src/modules/cosmos_to_cosmos.rs | 99 ++++++++++++++++++- 1 file changed, 98 insertions(+), 1 deletion(-) diff --git a/programs/relayer/src/modules/cosmos_to_cosmos.rs b/programs/relayer/src/modules/cosmos_to_cosmos.rs index 900f37ef..29c978e8 100644 --- a/programs/relayer/src/modules/cosmos_to_cosmos.rs +++ b/programs/relayer/src/modules/cosmos_to_cosmos.rs @@ -2,8 +2,15 @@ use std::str::FromStr; -use ibc_eureka_relayer_lib::{listener::cosmos_sdk, tx_builder::cosmos_to_cosmos}; +use ibc_eureka_relayer_lib::{ + listener::{cosmos_sdk, ChainListenerService}, + tx_builder::{cosmos_to_cosmos, TxBuilderService}, +}; +use tendermint::Hash; use tendermint_rpc::{HttpClient, Url}; +use tonic::{Request, Response}; + +use crate::api::{self, relayer_service_server::RelayerService}; /// The `CosmosToCosmosRelayerModule` struct defines the Cosmos to Cosmos relayer module. #[derive(Clone, Copy, Debug)] @@ -63,3 +70,93 @@ impl CosmosToCosmosRelayerModuleServer { } } } + +#[tonic::async_trait] +impl RelayerService for CosmosToCosmosRelayerModuleServer { + #[tracing::instrument(skip_all)] + async fn info( + &self, + _request: Request, + ) -> Result, tonic::Status> { + tracing::info!("Received info request."); + Ok(Response::new(api::InfoResponse { + target_chain: Some(api::Chain { + chain_id: self + .target_listener + .chain_id() + .await + .map_err(|e| tonic::Status::from_error(e.to_string().into()))?, + ibc_version: "2".to_string(), + ibc_contract: String::new(), + }), + source_chain: Some(api::Chain { + chain_id: self + .src_listener + .chain_id() + .await + .map_err(|e| tonic::Status::from_error(e.to_string().into()))?, + ibc_version: "2".to_string(), + ibc_contract: String::new(), + }), + })) + } + + #[tracing::instrument(skip_all)] + async fn relay_by_tx( + &self, + request: Request, + ) -> Result, tonic::Status> { + tracing::info!("Handling relay by tx request..."); + let inner_req = request.into_inner(); + let src_txs = inner_req + .source_tx_ids + .into_iter() + .map(Hash::try_from) + .collect::, _>>() + .map_err(|e| tonic::Status::from_error(e.to_string().into()))?; + + let target_txs = inner_req + .timeout_tx_ids + .into_iter() + .map(Hash::try_from) + .collect::, _>>() + .map_err(|e| tonic::Status::from_error(e.to_string().into()))?; + + let src_events = self + .src_listener + .fetch_tx_events(src_txs) + .await + .map_err(|e| tonic::Status::from_error(e.to_string().into()))?; + + tracing::debug!(cosmos_src_events = ?src_events, "Fetched source cosmos events."); + tracing::info!( + "Fetched {} source eureka events from CosmosSDK.", + src_events.len() + ); + + let target_events = self + .target_listener + .fetch_tx_events(target_txs) + .await + .map_err(|e| tonic::Status::from_error(e.to_string().into()))?; + + tracing::debug!(cosmos_target_events = ?target_events, "Fetched target cosmos events."); + tracing::info!( + "Fetched {} target eureka events from CosmosSDK.", + target_events.len() + ); + + let tx = self + .tx_builder + .relay_events(src_events, target_events, inner_req.target_channel_id) + .await + .map_err(|e| tonic::Status::from_error(e.to_string().into()))?; + + tracing::info!("Relay by tx request completed."); + + Ok(Response::new(api::RelayByTxResponse { + tx, + address: String::new(), + })) + } +} From 77862df71e094c2982e07851a1190b60d69463b9 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Tue, 10 Dec 2024 17:09:22 +0800 Subject: [PATCH 14/26] feat: implemented ModuleServer --- .../relayer/src/modules/cosmos_to_cosmos.rs | 40 +++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/programs/relayer/src/modules/cosmos_to_cosmos.rs b/programs/relayer/src/modules/cosmos_to_cosmos.rs index 29c978e8..edcd9e90 100644 --- a/programs/relayer/src/modules/cosmos_to_cosmos.rs +++ b/programs/relayer/src/modules/cosmos_to_cosmos.rs @@ -1,6 +1,6 @@ //! Defines Cosmos to Cosmos relayer module. -use std::str::FromStr; +use std::{net::SocketAddr, str::FromStr}; use ibc_eureka_relayer_lib::{ listener::{cosmos_sdk, ChainListenerService}, @@ -8,9 +8,15 @@ use ibc_eureka_relayer_lib::{ }; use tendermint::Hash; use tendermint_rpc::{HttpClient, Url}; -use tonic::{Request, Response}; - -use crate::api::{self, relayer_service_server::RelayerService}; +use tonic::{transport::Server, Request, Response}; + +use crate::{ + api::{ + self, + relayer_service_server::{RelayerService, RelayerServiceServer}, + }, + core::modules::ModuleServer, +}; /// The `CosmosToCosmosRelayerModule` struct defines the Cosmos to Cosmos relayer module. #[derive(Clone, Copy, Debug)] @@ -160,3 +166,29 @@ impl RelayerService for CosmosToCosmosRelayerModuleServer { })) } } + +#[tonic::async_trait] +impl ModuleServer for CosmosToCosmosRelayerModule { + fn name(&self) -> &'static str { + "cosmos_to_cosmos" + } + + #[tracing::instrument(skip_all)] + async fn serve( + &self, + config: serde_json::Value, + addr: SocketAddr, + ) -> Result<(), tonic::transport::Error> { + let config = serde_json::from_value::(config) + .unwrap_or_else(|e| panic!("failed to parse config: {e}")); + + let server = CosmosToCosmosRelayerModuleServer::new(config); + + tracing::info!(%addr, "Started Cosmos to Cosmos relayer server."); + + Server::builder() + .add_service(RelayerServiceServer::new(server)) + .serve(addr) + .await + } +} From c4dba9f4e0ee643b883950e3f0be5f5061c82ff2 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Wed, 11 Dec 2024 11:57:21 +0800 Subject: [PATCH 15/26] feat: added relayer module --- programs/relayer/config.example.json | 9 +++++++++ programs/relayer/src/bin/relayer.rs | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/programs/relayer/config.example.json b/programs/relayer/config.example.json index 9efa88e6..7708ede2 100644 --- a/programs/relayer/config.example.json +++ b/programs/relayer/config.example.json @@ -13,6 +13,15 @@ "eth_rpc_url": "https://ethereum-holesky-rpc.publicnode.com", "sp1_private_key": "0x1234567890abcdef1234567890abcdef" } + }, + { + "name": "cosmos_to_cosmos", + "port": 3001, + "config": { + "src_rpc_url": "https://noble-testnet-rpc.polkachu.com:443", + "target_rpc_url": "http://public-celestia-mocha5-consensus.numia.xyz/", + "signer_address": "cosmos1abcdef1234567890abcdef1234567890" + } } ] } diff --git a/programs/relayer/src/bin/relayer.rs b/programs/relayer/src/bin/relayer.rs index 05b06005..3ea8b919 100644 --- a/programs/relayer/src/bin/relayer.rs +++ b/programs/relayer/src/bin/relayer.rs @@ -7,7 +7,9 @@ use solidity_ibc_eureka_relayer::{ config::RelayerConfig, }, core::builder::RelayerBuilder, - modules::cosmos_to_eth::CosmosToEthRelayerModule, + modules::{ + cosmos_to_cosmos::CosmosToCosmosRelayerModule, cosmos_to_eth::CosmosToEthRelayerModule, + }, }; #[tokio::main] @@ -27,6 +29,7 @@ async fn main() -> anyhow::Result<()> { // Build the relayer server. let mut relayer_builder = RelayerBuilder::default(); relayer_builder.add_module(CosmosToEthRelayerModule); + relayer_builder.add_module(CosmosToCosmosRelayerModule); // Start the relayer server. relayer_builder.start(config).await?; From 288f0109229b964cbb1e8b47f0fbc9cdc6161520 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Thu, 12 Dec 2024 15:11:26 +0800 Subject: [PATCH 16/26] e2e: rename chainA to EthChain --- e2e/interchaintestv8/e2esuite/light_clients.go | 6 +++--- e2e/interchaintestv8/e2esuite/suite.go | 11 +++++------ e2e/interchaintestv8/e2esuite/utils.go | 2 +- e2e/interchaintestv8/ibc_eureka_test.go | 10 +++++----- e2e/interchaintestv8/relayer_test.go | 10 +++++----- e2e/interchaintestv8/sp1_ics07_test.go | 16 ++++++++-------- 6 files changed, 27 insertions(+), 28 deletions(-) diff --git a/e2e/interchaintestv8/e2esuite/light_clients.go b/e2e/interchaintestv8/e2esuite/light_clients.go index 92208a68..e2ac5cb8 100644 --- a/e2e/interchaintestv8/e2esuite/light_clients.go +++ b/e2e/interchaintestv8/e2esuite/light_clients.go @@ -39,7 +39,7 @@ func (s *TestSuite) UpdateEthClient(ctx context.Context, ibcContractAddress stri return } - eth, simd := s.ChainA, s.ChainB + eth, simd := s.EthChain, s.ChainB // Wait until we have a block number greater than the minimum update to var updateTo int64 @@ -222,7 +222,7 @@ func (s *TestSuite) UpdateEthClient(ctx context.Context, ibcContractAddress stri } func (s *TestSuite) createUnionLightClient(ctx context.Context, simdRelayerUser ibc.Wallet, ibcContractAddress string, rustFixtureGenerator *types.RustFixtureGenerator) { - eth, simd := s.ChainA, s.ChainB + eth, simd := s.EthChain, s.ChainB file, err := os.Open("e2e/interchaintestv8/wasm/ethereum_light_client_minimal.wasm.gz") s.Require().NoError(err) @@ -329,7 +329,7 @@ func (s *TestSuite) createUnionLightClient(ctx context.Context, simdRelayerUser } func (s *TestSuite) createDummyLightClient(ctx context.Context, simdRelayerUser ibc.Wallet) { - eth, simd := s.ChainA, s.ChainB + eth, simd := s.EthChain, s.ChainB file, err := os.Open("e2e/interchaintestv8/wasm/wasm_dummy_light_client.wasm.gz") s.Require().NoError(err) diff --git a/e2e/interchaintestv8/e2esuite/suite.go b/e2e/interchaintestv8/e2esuite/suite.go index c94d2075..45a8b26c 100644 --- a/e2e/interchaintestv8/e2esuite/suite.go +++ b/e2e/interchaintestv8/e2esuite/suite.go @@ -31,14 +31,13 @@ const anvilFaucetPrivateKey = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5ef type TestSuite struct { suite.Suite - ChainA ethereum.Ethereum + EthChain ethereum.Ethereum ethTestnetType string ChainB *cosmos.CosmosChain UserB ibc.Wallet dockerClient *dockerclient.Client network string logger *zap.Logger - ExecRep *testreporter.RelayerExecReporter EthereumLightClientID string TendermintLightClientID string @@ -59,7 +58,7 @@ func (s *TestSuite) SetupSuite(ctx context.Context) { case testvalues.EthTestnetTypePoS: kurtosisChain, err := chainconfig.SpinUpKurtosisPoS(ctx) // TODO: Run this in a goroutine and wait for it to be ready s.Require().NoError(err) - s.ChainA, err = ethereum.NewEthereum(ctx, kurtosisChain.RPC, &kurtosisChain.BeaconApiClient, kurtosisChain.Faucet) + s.EthChain, err = ethereum.NewEthereum(ctx, kurtosisChain.RPC, &kurtosisChain.BeaconApiClient, kurtosisChain.Faucet) s.Require().NoError(err) s.T().Cleanup(func() { ctx := context.Background() @@ -87,10 +86,10 @@ func (s *TestSuite) SetupSuite(ctx context.Context) { ic = ic.AddChain(chain) } - s.ExecRep = testreporter.NewNopReporter().RelayerExecReporter(s.T()) + execRep := testreporter.NewNopReporter().RelayerExecReporter(s.T()) // TODO: Run this in a goroutine and wait for it to be ready - s.Require().NoError(ic.Build(ctx, s.ExecRep, interchaintest.InterchainBuildOptions{ + s.Require().NoError(ic.Build(ctx, execRep, interchaintest.InterchainBuildOptions{ TestName: s.T().Name(), Client: s.dockerClient, NetworkID: s.network, @@ -105,7 +104,7 @@ func (s *TestSuite) SetupSuite(ctx context.Context) { faucet, err := crypto.ToECDSA(ethcommon.FromHex(anvilFaucetPrivateKey)) s.Require().NoError(err) - s.ChainA, err = ethereum.NewEthereum(ctx, anvil.GetHostRPCAddress(), nil, faucet) + s.EthChain, err = ethereum.NewEthereum(ctx, anvil.GetHostRPCAddress(), nil, faucet) s.Require().NoError(err) } diff --git a/e2e/interchaintestv8/e2esuite/utils.go b/e2e/interchaintestv8/e2esuite/utils.go index 2e17809a..0da0b9e9 100644 --- a/e2e/interchaintestv8/e2esuite/utils.go +++ b/e2e/interchaintestv8/e2esuite/utils.go @@ -113,7 +113,7 @@ func (s *TestSuite) fundAddress(ctx context.Context, chain *cosmos.CosmosChain, // GetRelayerUsers returns two ibc.Wallet instances which can be used for the relayer users // on the two chains. func (s *TestSuite) GetRelayerUsers(ctx context.Context) (*ecdsa.PrivateKey, ibc.Wallet) { - eth, simd := s.ChainA, s.ChainB + eth, simd := s.EthChain, s.ChainB ethKey, err := eth.CreateAndFundUser() s.Require().NoError(err) diff --git a/e2e/interchaintestv8/ibc_eureka_test.go b/e2e/interchaintestv8/ibc_eureka_test.go index cca1898a..c615f2db 100644 --- a/e2e/interchaintestv8/ibc_eureka_test.go +++ b/e2e/interchaintestv8/ibc_eureka_test.go @@ -85,7 +85,7 @@ func TestWithIbcEurekaTestSuite(t *testing.T) { func (s *IbcEurekaTestSuite) SetupSuite(ctx context.Context, proofType operator.SupportedProofType) { s.TestSuite.SetupSuite(ctx) - eth, simd := s.ChainA, s.ChainB + eth, simd := s.EthChain, s.ChainB var prover string shouldGenerateRustFixtures := false @@ -333,7 +333,7 @@ func (s *IbcEurekaTestSuite) ICS20TransferERC20TokenfromEthereumToCosmosAndBackT ) { s.SetupSuite(ctx, proofType) - eth, simd := s.ChainA, s.ChainB + eth, simd := s.EthChain, s.ChainB ics20Address := ethcommon.HexToAddress(s.contractAddresses.Ics20Transfer) transferAmount := big.NewInt(testvalues.TransferAmount) @@ -723,7 +723,7 @@ func (s *IbcEurekaTestSuite) TestICS20TransferNativeCosmosCoinsToEthereumAndBack func (s *IbcEurekaTestSuite) ICS20TransferNativeCosmosCoinsToEthereumAndBackTest(ctx context.Context, pt operator.SupportedProofType) { s.SetupSuite(ctx, pt) - eth, simd := s.ChainA, s.ChainB + eth, simd := s.EthChain, s.ChainB ics20Address := ethcommon.HexToAddress(s.contractAddresses.Ics20Transfer) transferAmount := big.NewInt(testvalues.TransferAmount) @@ -1051,7 +1051,7 @@ func (s *IbcEurekaTestSuite) TestICS20TransferTimeoutFromEthereumToCosmosChain_P func (s *IbcEurekaTestSuite) ICS20TransferTimeoutFromEthereumToCosmosChainTest(ctx context.Context, pt operator.SupportedProofType) { s.SetupSuite(ctx, pt) - eth, simd := s.ChainA, s.ChainB + eth, simd := s.EthChain, s.ChainB transferAmount := big.NewInt(testvalues.TransferAmount) ethereumUserAddress := crypto.PubkeyToAddress(s.key.PublicKey) @@ -1191,7 +1191,7 @@ func (s *IbcEurekaTestSuite) createICS20MsgSendPacket( } func (s *IbcEurekaTestSuite) getCommitmentProof(ctx context.Context, path []byte) []byte { - eth, simd := s.ChainA, s.ChainB + eth, simd := s.EthChain, s.ChainB storageKey := ethereum.GetCommitmentsStorageKey(path) storageKeys := []string{storageKey.Hex()} diff --git a/e2e/interchaintestv8/relayer_test.go b/e2e/interchaintestv8/relayer_test.go index e25e465c..4004809f 100644 --- a/e2e/interchaintestv8/relayer_test.go +++ b/e2e/interchaintestv8/relayer_test.go @@ -55,7 +55,7 @@ func TestWithRelayerTestSuite(t *testing.T) { func (s *RelayerTestSuite) SetupSuite(ctx context.Context, proofType operator.SupportedProofType) { s.IbcEurekaTestSuite.SetupSuite(ctx, proofType) - eth, simd := s.ChainA, s.ChainB + eth, simd := s.EthChain, s.ChainB var relayerProcess *os.Process s.Require().True(s.Run("Start Relayer", func() { @@ -95,7 +95,7 @@ func (s *RelayerTestSuite) TestRelayerInfo() { ctx := context.Background() s.SetupSuite(ctx, operator.ProofTypeGroth16) - eth, simd := s.ChainA, s.ChainB + eth, simd := s.EthChain, s.ChainB s.Run("Relayer Info", func() { info, err := s.RelayerClient.Info(context.Background(), &relayertypes.InfoRequest{}) @@ -136,7 +136,7 @@ func (s *RelayerTestSuite) RecvPacketToEthTest( s.SetupSuite(ctx, proofType) - eth, simd := s.ChainA, s.ChainB + eth, simd := s.EthChain, s.ChainB ics26Address := ethcommon.HexToAddress(s.contractAddresses.Ics26Router) // ics20Address := ethcommon.HexToAddress(s.contractAddresses.Ics20Transfer) @@ -298,7 +298,7 @@ func (s *RelayerTestSuite) ICS20TransferERC20TokenBatchedAckTest( ) { s.SetupSuite(ctx, proofType) - eth, simd := s.ChainA, s.ChainB + eth, simd := s.EthChain, s.ChainB ics26Address := ethcommon.HexToAddress(s.contractAddresses.Ics26Router) ics20Address := ethcommon.HexToAddress(s.contractAddresses.Ics20Transfer) @@ -513,7 +513,7 @@ func (s *RelayerTestSuite) ICS20TimeoutFromEthereumToTimeoutTest( ) { s.SetupSuite(ctx, pt) - eth, _ := s.ChainA, s.ChainB + eth, _ := s.EthChain, s.ChainB ics26Address := ethcommon.HexToAddress(s.contractAddresses.Ics26Router) transferAmount := big.NewInt(testvalues.TransferAmount) diff --git a/e2e/interchaintestv8/sp1_ics07_test.go b/e2e/interchaintestv8/sp1_ics07_test.go index fec6e86d..b4dc2803 100644 --- a/e2e/interchaintestv8/sp1_ics07_test.go +++ b/e2e/interchaintestv8/sp1_ics07_test.go @@ -60,7 +60,7 @@ type SP1ICS07TendermintTestSuite struct { func (s *SP1ICS07TendermintTestSuite) SetupSuite(ctx context.Context, pt operator.SupportedProofType) { s.TestSuite.SetupSuite(ctx) - eth, simd := s.ChainA, s.ChainB + eth, simd := s.EthChain, s.ChainB s.Require().True(s.Run("Set up environment", func() { err := os.Chdir("../..") @@ -130,7 +130,7 @@ func (s *SP1ICS07TendermintTestSuite) TestDeploy_Plonk() { func (s *SP1ICS07TendermintTestSuite) DeployTest(ctx context.Context, pt operator.SupportedProofType) { s.SetupSuite(ctx, pt) - _, simd := s.ChainA, s.ChainB + _, simd := s.EthChain, s.ChainB s.Require().True(s.Run("Verify deployment", func() { clientState, err := s.contract.GetClientState(nil) @@ -164,7 +164,7 @@ func (s *SP1ICS07TendermintTestSuite) TestUpdateClient_Plonk() { func (s *SP1ICS07TendermintTestSuite) UpdateClientTest(ctx context.Context, pt operator.SupportedProofType) { s.SetupSuite(ctx, pt) - _, simd := s.ChainA, s.ChainB + _, simd := s.EthChain, s.ChainB if s.generateFixtures { s.T().Log("Generate fixtures is set to true, but TestUpdateClient does not support it (yet)") @@ -211,7 +211,7 @@ func (s *SP1ICS07TendermintTestSuite) MembershipTest(pt operator.SupportedProofT s.SetupSuite(ctx, pt) - eth, simd := s.ChainA, s.ChainB + eth, simd := s.EthChain, s.ChainB if s.generateFixtures { s.T().Log("Generate fixtures is set to true, but TestVerifyMembership does not support it (yet)") @@ -318,7 +318,7 @@ func (s *SP1ICS07TendermintTestSuite) TestUpdateClientAndMembership_Groth16() { func (s *SP1ICS07TendermintTestSuite) UpdateClientAndMembershipTest(ctx context.Context, pt operator.SupportedProofType) { s.SetupSuite(ctx, pt) - eth, simd := s.ChainA, s.ChainB + eth, simd := s.EthChain, s.ChainB if s.generateFixtures { s.T().Log("Generate fixtures is set to true, but TestUpdateClientAndMembership does not support it (yet)") @@ -413,7 +413,7 @@ func (s *SP1ICS07TendermintTestSuite) TestDoubleSignMisbehaviour_Groth16() { func (s *SP1ICS07TendermintTestSuite) DoubleSignMisbehaviourTest(ctx context.Context, fixName string, pt operator.SupportedProofType) { s.SetupSuite(ctx, pt) - eth, simd := s.ChainA, s.ChainB + eth, simd := s.EthChain, s.ChainB _ = eth var height clienttypes.Height @@ -518,7 +518,7 @@ func (s *SP1ICS07TendermintTestSuite) TestBreakingTimeMonotonicityMisbehaviour_G func (s *SP1ICS07TendermintTestSuite) BreakingTimeMonotonicityMisbehaviourTest(ctx context.Context, fixName string, pt operator.SupportedProofType) { s.SetupSuite(ctx, pt) - eth, simd := s.ChainA, s.ChainB + eth, simd := s.EthChain, s.ChainB var height clienttypes.Height var trustedHeader tmclient.Header @@ -607,7 +607,7 @@ func (s *SP1ICS07TendermintTestSuite) largeMembershipTest(n uint64, pt operator. s.SetupSuite(ctx, pt) - eth, simd := s.ChainA, s.ChainB + eth, simd := s.EthChain, s.ChainB s.Require().True(s.Run(fmt.Sprintf("Large membership test with %d key-value pairs", n), func() { membershipKeys := make([][][]byte, n) From 46b1f56564ee16b63799ecb94c9d5ade0de81a74 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Thu, 12 Dec 2024 15:54:40 +0800 Subject: [PATCH 17/26] e2e: allow multiple chains --- .../e2esuite/light_clients.go | 6 ++-- e2e/interchaintestv8/e2esuite/suite.go | 30 ++++++++++------ e2e/interchaintestv8/e2esuite/utils.go | 34 +++--------------- e2e/interchaintestv8/ibc_eureka_test.go | 36 +++++++++---------- e2e/interchaintestv8/relayer_test.go | 21 ++++++----- e2e/interchaintestv8/sp1_ics07_test.go | 29 ++++++++------- 6 files changed, 70 insertions(+), 86 deletions(-) diff --git a/e2e/interchaintestv8/e2esuite/light_clients.go b/e2e/interchaintestv8/e2esuite/light_clients.go index e2ac5cb8..644a3aad 100644 --- a/e2e/interchaintestv8/e2esuite/light_clients.go +++ b/e2e/interchaintestv8/e2esuite/light_clients.go @@ -39,7 +39,7 @@ func (s *TestSuite) UpdateEthClient(ctx context.Context, ibcContractAddress stri return } - eth, simd := s.EthChain, s.ChainB + eth, simd := s.EthChain, s.CosmosChains[0] // Wait until we have a block number greater than the minimum update to var updateTo int64 @@ -222,7 +222,7 @@ func (s *TestSuite) UpdateEthClient(ctx context.Context, ibcContractAddress stri } func (s *TestSuite) createUnionLightClient(ctx context.Context, simdRelayerUser ibc.Wallet, ibcContractAddress string, rustFixtureGenerator *types.RustFixtureGenerator) { - eth, simd := s.EthChain, s.ChainB + eth, simd := s.EthChain, s.CosmosChains[0] file, err := os.Open("e2e/interchaintestv8/wasm/ethereum_light_client_minimal.wasm.gz") s.Require().NoError(err) @@ -329,7 +329,7 @@ func (s *TestSuite) createUnionLightClient(ctx context.Context, simdRelayerUser } func (s *TestSuite) createDummyLightClient(ctx context.Context, simdRelayerUser ibc.Wallet) { - eth, simd := s.EthChain, s.ChainB + eth, simd := s.EthChain, s.CosmosChains[0] file, err := os.Open("e2e/interchaintestv8/wasm/wasm_dummy_light_client.wasm.gz") s.Require().NoError(err) diff --git a/e2e/interchaintestv8/e2esuite/suite.go b/e2e/interchaintestv8/e2esuite/suite.go index 45a8b26c..67d58b2b 100644 --- a/e2e/interchaintestv8/e2esuite/suite.go +++ b/e2e/interchaintestv8/e2esuite/suite.go @@ -33,8 +33,8 @@ type TestSuite struct { EthChain ethereum.Ethereum ethTestnetType string - ChainB *cosmos.CosmosChain - UserB ibc.Wallet + CosmosChains []*cosmos.CosmosChain + CosmosUsers []ibc.Wallet dockerClient *dockerclient.Client network string logger *zap.Logger @@ -79,8 +79,6 @@ func (s *TestSuite) SetupSuite(ctx context.Context) { chains, err := cf.Chains(s.T().Name()) s.Require().NoError(err) - s.ChainB = chains[0].(*cosmos.CosmosChain) - ic := interchaintest.NewInterchain() for _, chain := range chains { ic = ic.AddChain(chain) @@ -96,23 +94,33 @@ func (s *TestSuite) SetupSuite(ctx context.Context) { SkipPathCreation: true, })) - // map all query request types to their gRPC method paths for cosmos chains - s.Require().NoError(populateQueryReqToPath(ctx, s.ChainB)) - if s.ethTestnetType == testvalues.EthTestnetTypePoW { - anvil := chains[1].(*icethereum.EthereumChain) + anvil := chains[len(chains)-1].(*icethereum.EthereumChain) faucet, err := crypto.ToECDSA(ethcommon.FromHex(anvilFaucetPrivateKey)) s.Require().NoError(err) s.EthChain, err = ethereum.NewEthereum(ctx, anvil.GetHostRPCAddress(), nil, faucet) s.Require().NoError(err) + + // Remove the Ethereum chain from the cosmos chains + chains = chains[:len(chains)-1] + } + + for _, chain := range chains { + cosmosChain := chain.(*cosmos.CosmosChain) + s.CosmosChains = append(s.CosmosChains, cosmosChain) } + // map all query request types to their gRPC method paths for cosmos chains + s.Require().NoError(populateQueryReqToPath(ctx, s.CosmosChains[0])) + // Fund user accounts cosmosUserFunds := sdkmath.NewInt(testvalues.InitialBalance) - cosmosUsers := interchaintest.GetAndFundTestUsers(s.T(), ctx, s.T().Name(), cosmosUserFunds, s.ChainB) - s.UserB = cosmosUsers[0] + cosmosUsers := interchaintest.GetAndFundTestUsers(s.T(), ctx, s.T().Name(), cosmosUserFunds, chains...) + s.CosmosUsers = cosmosUsers s.proposalIDs = make(map[string]uint64) - s.proposalIDs[s.ChainB.Config().ChainID] = 1 + for _, chain := range s.CosmosChains { + s.proposalIDs[chain.Config().ChainID] = 1 + } } diff --git a/e2e/interchaintestv8/e2esuite/utils.go b/e2e/interchaintestv8/e2esuite/utils.go index 0da0b9e9..5a2cbab5 100644 --- a/e2e/interchaintestv8/e2esuite/utils.go +++ b/e2e/interchaintestv8/e2esuite/utils.go @@ -53,12 +53,6 @@ import ( ethereumligthclient "github.com/srdtrk/solidity-ibc-eureka/e2e/v8/types/ethereumlightclient" ) -// FundAddressChainB sends funds to the given address on Chain B. -// The amount sent is 1,000,000,000 of the chain's denom. -func (s *TestSuite) FundAddressChainB(ctx context.Context, address string) { - s.fundAddress(ctx, s.ChainB, s.UserB.KeyName(), address) -} - // BroadcastMessages broadcasts the provided messages to the given chain and signs them on behalf of the provided user. // Once the broadcast response is returned, we wait for two blocks to be created on chain. func (s *TestSuite) BroadcastMessages(ctx context.Context, chain *cosmos.CosmosChain, user ibc.Wallet, gas uint64, msgs ...sdk.Msg) (*sdk.TxResponse, error) { @@ -96,32 +90,12 @@ func (s *TestSuite) BroadcastMessages(ctx context.Context, chain *cosmos.CosmosC return &resp, nil } -// fundAddress sends funds to the given address on the given chain -func (s *TestSuite) fundAddress(ctx context.Context, chain *cosmos.CosmosChain, keyName, address string) { - err := chain.SendFunds(ctx, keyName, ibc.WalletAmount{ - Address: address, - Denom: chain.Config().Denom, - Amount: sdkmath.NewInt(1_000_000_000), - }) - s.Require().NoError(err) - - // wait for 2 blocks for the funds to be received - err = testutil.WaitForBlocks(ctx, 2, chain) - s.Require().NoError(err) -} - -// GetRelayerUsers returns two ibc.Wallet instances which can be used for the relayer users -// on the two chains. -func (s *TestSuite) GetRelayerUsers(ctx context.Context) (*ecdsa.PrivateKey, ibc.Wallet) { - eth, simd := s.EthChain, s.ChainB - - ethKey, err := eth.CreateAndFundUser() - s.Require().NoError(err) - +// CreateAndFundCosmosUser returns a new cosmos user with the given initial balance and funds it with the native chain denom. +func (s *TestSuite) CreateAndFundCosmosUser(ctx context.Context, chain *cosmos.CosmosChain) ibc.Wallet { cosmosUserFunds := sdkmath.NewInt(testvalues.InitialBalance) - cosmosUsers := interchaintest.GetAndFundTestUsers(s.T(), ctx, s.T().Name(), cosmosUserFunds, simd) + cosmosUsers := interchaintest.GetAndFundTestUsers(s.T(), ctx, s.T().Name(), cosmosUserFunds, chain) - return ethKey, cosmosUsers[0] + return cosmosUsers[0] } // GetEvmEvent parses the logs in the given receipt and returns the first event that can be parsed diff --git a/e2e/interchaintestv8/ibc_eureka_test.go b/e2e/interchaintestv8/ibc_eureka_test.go index c615f2db..cef6c3e6 100644 --- a/e2e/interchaintestv8/ibc_eureka_test.go +++ b/e2e/interchaintestv8/ibc_eureka_test.go @@ -85,7 +85,7 @@ func TestWithIbcEurekaTestSuite(t *testing.T) { func (s *IbcEurekaTestSuite) SetupSuite(ctx context.Context, proofType operator.SupportedProofType) { s.TestSuite.SetupSuite(ctx) - eth, simd := s.EthChain, s.ChainB + eth, simd := s.EthChain, s.CosmosChains[0] var prover string shouldGenerateRustFixtures := false @@ -182,10 +182,10 @@ func (s *IbcEurekaTestSuite) SetupSuite(ctx context.Context, proofType operator. _ = s.GetTxReciept(ctx, eth, tx.Hash()) // wait for the tx to be mined })) - _, simdRelayerUser := s.GetRelayerUsers(ctx) + simdUser := s.CreateAndFundCosmosUser(ctx, simd) s.Require().True(s.Run("Add ethereum light client on Cosmos chain", func() { - s.CreateEthereumLightClient(ctx, simdRelayerUser, s.contractAddresses.IbcStore, s.rustFixtureGenerator) + s.CreateEthereumLightClient(ctx, simdUser, s.contractAddresses.IbcStore, s.rustFixtureGenerator) })) s.Require().True(s.Run("Add client and counterparty on EVM", func() { @@ -208,17 +208,17 @@ func (s *IbcEurekaTestSuite) SetupSuite(ctx context.Context, proofType operator. s.Require().True(s.Run("Create channel and register counterparty on Cosmos chain", func() { merklePathPrefix := commitmenttypesv2.NewMerklePath([]byte("")) - _, err := s.BroadcastMessages(ctx, simd, simdRelayerUser, 200_000, &channeltypesv2.MsgCreateChannel{ + _, err := s.BroadcastMessages(ctx, simd, simdUser, 200_000, &channeltypesv2.MsgCreateChannel{ ClientId: s.EthereumLightClientID, MerklePathPrefix: merklePathPrefix, - Signer: simdRelayerUser.FormattedAddress(), + Signer: simdUser.FormattedAddress(), }) s.Require().NoError(err) - _, err = s.BroadcastMessages(ctx, simd, simdRelayerUser, 200_000, &channeltypesv2.MsgRegisterCounterparty{ + _, err = s.BroadcastMessages(ctx, simd, simdUser, 200_000, &channeltypesv2.MsgRegisterCounterparty{ ChannelId: ibctesting.FirstChannelID, CounterpartyChannelId: s.TendermintLightClientID, - Signer: simdRelayerUser.FormattedAddress(), + Signer: simdUser.FormattedAddress(), }) s.Require().NoError(err) })) @@ -238,7 +238,7 @@ func (s *IbcEurekaTestSuite) TestDeploy_Plonk() { func (s *IbcEurekaTestSuite) DeployTest(ctx context.Context, proofType operator.SupportedProofType) { s.SetupSuite(ctx, proofType) - simd := s.ChainB + simd := s.CosmosChains[0] s.Require().True(s.Run("Verify SP1 Client", func() { clientState, err := s.sp1Ics07Contract.GetClientState(nil) @@ -333,7 +333,7 @@ func (s *IbcEurekaTestSuite) ICS20TransferERC20TokenfromEthereumToCosmosAndBackT ) { s.SetupSuite(ctx, proofType) - eth, simd := s.EthChain, s.ChainB + eth, simd := s.EthChain, s.CosmosChains[0] ics20Address := ethcommon.HexToAddress(s.contractAddresses.Ics20Transfer) transferAmount := big.NewInt(testvalues.TransferAmount) @@ -342,9 +342,9 @@ func (s *IbcEurekaTestSuite) ICS20TransferERC20TokenfromEthereumToCosmosAndBackT s.FailNow("Total transfer amount exceeds the initial balance") } ethereumUserAddress := crypto.PubkeyToAddress(s.key.PublicKey) - cosmosUserWallet := s.UserB + cosmosUserWallet := s.CosmosUsers[0] cosmosUserAddress := cosmosUserWallet.FormattedAddress() - _, simdRelayerUser := s.GetRelayerUsers(ctx) + simdRelayerUser := s.CreateAndFundCosmosUser(ctx, simd) ics26routerAbi, err := abi.JSON(strings.NewReader(ics26router.ContractABI)) s.Require().NoError(err) @@ -723,21 +723,21 @@ func (s *IbcEurekaTestSuite) TestICS20TransferNativeCosmosCoinsToEthereumAndBack func (s *IbcEurekaTestSuite) ICS20TransferNativeCosmosCoinsToEthereumAndBackTest(ctx context.Context, pt operator.SupportedProofType) { s.SetupSuite(ctx, pt) - eth, simd := s.EthChain, s.ChainB + eth, simd := s.EthChain, s.CosmosChains[0] ics20Address := ethcommon.HexToAddress(s.contractAddresses.Ics20Transfer) transferAmount := big.NewInt(testvalues.TransferAmount) ethereumUserAddress := crypto.PubkeyToAddress(s.key.PublicKey) - cosmosUserWallet := s.UserB + cosmosUserWallet := s.CosmosUsers[0] cosmosUserAddress := cosmosUserWallet.FormattedAddress() - _, simdRelayerUser := s.GetRelayerUsers(ctx) + simdRelayerUser := s.CreateAndFundCosmosUser(ctx, simd) sendMemo := "nonnativesend" var sendPacket channeltypesv2.Packet var transferCoin sdk.Coin s.Require().True(s.Run("Send transfer on Cosmos chain", func() { timeout := uint64(time.Now().Add(30 * time.Minute).Unix()) - transferCoin = sdk.NewCoin(s.ChainB.Config().Denom, sdkmath.NewIntFromBigInt(transferAmount)) + transferCoin = sdk.NewCoin(simd.Config().Denom, sdkmath.NewIntFromBigInt(transferAmount)) transferPayload := ics20lib.ICS20LibFungibleTokenPacketData{ Denom: transferCoin.Denom, @@ -1051,11 +1051,11 @@ func (s *IbcEurekaTestSuite) TestICS20TransferTimeoutFromEthereumToCosmosChain_P func (s *IbcEurekaTestSuite) ICS20TransferTimeoutFromEthereumToCosmosChainTest(ctx context.Context, pt operator.SupportedProofType) { s.SetupSuite(ctx, pt) - eth, simd := s.EthChain, s.ChainB + eth, simd := s.EthChain, s.CosmosChains[0] transferAmount := big.NewInt(testvalues.TransferAmount) ethereumUserAddress := crypto.PubkeyToAddress(s.key.PublicKey) - cosmosUserWallet := s.UserB + cosmosUserWallet := s.CosmosUsers[0] cosmosUserAddress := cosmosUserWallet.FormattedAddress() var packet ics26router.IICS26RouterMsgsPacket @@ -1191,7 +1191,7 @@ func (s *IbcEurekaTestSuite) createICS20MsgSendPacket( } func (s *IbcEurekaTestSuite) getCommitmentProof(ctx context.Context, path []byte) []byte { - eth, simd := s.EthChain, s.ChainB + eth, simd := s.EthChain, s.CosmosChains[0] storageKey := ethereum.GetCommitmentsStorageKey(path) storageKeys := []string{storageKey.Hex()} diff --git a/e2e/interchaintestv8/relayer_test.go b/e2e/interchaintestv8/relayer_test.go index 4004809f..b3f9d198 100644 --- a/e2e/interchaintestv8/relayer_test.go +++ b/e2e/interchaintestv8/relayer_test.go @@ -55,7 +55,7 @@ func TestWithRelayerTestSuite(t *testing.T) { func (s *RelayerTestSuite) SetupSuite(ctx context.Context, proofType operator.SupportedProofType) { s.IbcEurekaTestSuite.SetupSuite(ctx, proofType) - eth, simd := s.EthChain, s.ChainB + eth, simd := s.EthChain, s.CosmosChains[0] var relayerProcess *os.Process s.Require().True(s.Run("Start Relayer", func() { @@ -95,7 +95,7 @@ func (s *RelayerTestSuite) TestRelayerInfo() { ctx := context.Background() s.SetupSuite(ctx, operator.ProofTypeGroth16) - eth, simd := s.EthChain, s.ChainB + eth, simd := s.EthChain, s.CosmosChains[0] s.Run("Relayer Info", func() { info, err := s.RelayerClient.Info(context.Background(), &relayertypes.InfoRequest{}) @@ -136,17 +136,16 @@ func (s *RelayerTestSuite) RecvPacketToEthTest( s.SetupSuite(ctx, proofType) - eth, simd := s.EthChain, s.ChainB + eth, simd := s.EthChain, s.CosmosChains[0] ics26Address := ethcommon.HexToAddress(s.contractAddresses.Ics26Router) - // ics20Address := ethcommon.HexToAddress(s.contractAddresses.Ics20Transfer) transferAmount := big.NewInt(testvalues.TransferAmount) totalTransferAmount := big.NewInt(testvalues.TransferAmount * int64(numOfTransfers)) if totalTransferAmount.Int64() > testvalues.InitialBalance { s.FailNow("Total transfer amount exceeds the initial balance") } ethereumUserAddress := crypto.PubkeyToAddress(s.key.PublicKey) - cosmosUserWallet := s.UserB + cosmosUserWallet := s.CosmosUsers[0] cosmosUserAddress := cosmosUserWallet.FormattedAddress() sendMemo := "nonnativesend" @@ -157,7 +156,7 @@ func (s *RelayerTestSuite) RecvPacketToEthTest( s.Require().True(s.Run("Send transfers on Cosmos chain", func() { for i := 0; i < numOfTransfers; i++ { timeout := uint64(time.Now().Add(30 * time.Minute).Unix()) - transferCoin = sdk.NewCoin(s.ChainB.Config().Denom, sdkmath.NewIntFromBigInt(transferAmount)) + transferCoin = sdk.NewCoin(simd.Config().Denom, sdkmath.NewIntFromBigInt(transferAmount)) transferPayload := ics20lib.ICS20LibFungibleTokenPacketData{ Denom: transferCoin.Denom, @@ -298,7 +297,7 @@ func (s *RelayerTestSuite) ICS20TransferERC20TokenBatchedAckTest( ) { s.SetupSuite(ctx, proofType) - eth, simd := s.EthChain, s.ChainB + eth, simd := s.EthChain, s.CosmosChains[0] ics26Address := ethcommon.HexToAddress(s.contractAddresses.Ics26Router) ics20Address := ethcommon.HexToAddress(s.contractAddresses.Ics20Transfer) @@ -308,9 +307,9 @@ func (s *RelayerTestSuite) ICS20TransferERC20TokenBatchedAckTest( s.FailNow("Total transfer amount exceeds the initial balance") } ethereumUserAddress := crypto.PubkeyToAddress(s.key.PublicKey) - cosmosUserWallet := s.UserB + cosmosUserWallet := s.CosmosUsers[0] cosmosUserAddress := cosmosUserWallet.FormattedAddress() - _, simdRelayerUser := s.GetRelayerUsers(ctx) + simdRelayerUser := s.CreateAndFundCosmosUser(ctx, simd) ics26routerAbi, err := abi.JSON(strings.NewReader(ics26router.ContractABI)) s.Require().NoError(err) @@ -513,7 +512,7 @@ func (s *RelayerTestSuite) ICS20TimeoutFromEthereumToTimeoutTest( ) { s.SetupSuite(ctx, pt) - eth, _ := s.EthChain, s.ChainB + eth, _ := s.EthChain, s.CosmosChains[0] ics26Address := ethcommon.HexToAddress(s.contractAddresses.Ics26Router) transferAmount := big.NewInt(testvalues.TransferAmount) @@ -522,7 +521,7 @@ func (s *RelayerTestSuite) ICS20TimeoutFromEthereumToTimeoutTest( s.FailNow("Total transfer amount exceeds the initial balance") } ethereumUserAddress := crypto.PubkeyToAddress(s.key.PublicKey) - cosmosUserWallet := s.UserB + cosmosUserWallet := s.CosmosUsers[0] cosmosUserAddress := cosmosUserWallet.FormattedAddress() s.Require().True(s.Run("Approve the ICS20Transfer.sol contract to spend the erc20 tokens", func() { diff --git a/e2e/interchaintestv8/sp1_ics07_test.go b/e2e/interchaintestv8/sp1_ics07_test.go index b4dc2803..ce831053 100644 --- a/e2e/interchaintestv8/sp1_ics07_test.go +++ b/e2e/interchaintestv8/sp1_ics07_test.go @@ -60,7 +60,7 @@ type SP1ICS07TendermintTestSuite struct { func (s *SP1ICS07TendermintTestSuite) SetupSuite(ctx context.Context, pt operator.SupportedProofType) { s.TestSuite.SetupSuite(ctx) - eth, simd := s.EthChain, s.ChainB + eth, simd := s.EthChain, s.CosmosChains[0] s.Require().True(s.Run("Set up environment", func() { err := os.Chdir("../..") @@ -130,7 +130,7 @@ func (s *SP1ICS07TendermintTestSuite) TestDeploy_Plonk() { func (s *SP1ICS07TendermintTestSuite) DeployTest(ctx context.Context, pt operator.SupportedProofType) { s.SetupSuite(ctx, pt) - _, simd := s.EthChain, s.ChainB + _, simd := s.EthChain, s.CosmosChains[0] s.Require().True(s.Run("Verify deployment", func() { clientState, err := s.contract.GetClientState(nil) @@ -164,7 +164,7 @@ func (s *SP1ICS07TendermintTestSuite) TestUpdateClient_Plonk() { func (s *SP1ICS07TendermintTestSuite) UpdateClientTest(ctx context.Context, pt operator.SupportedProofType) { s.SetupSuite(ctx, pt) - _, simd := s.EthChain, s.ChainB + _, simd := s.EthChain, s.CosmosChains[0] if s.generateFixtures { s.T().Log("Generate fixtures is set to true, but TestUpdateClient does not support it (yet)") @@ -211,7 +211,8 @@ func (s *SP1ICS07TendermintTestSuite) MembershipTest(pt operator.SupportedProofT s.SetupSuite(ctx, pt) - eth, simd := s.EthChain, s.ChainB + eth, simd := s.EthChain, s.CosmosChains[0] + simdUser := s.CosmosUsers[0] if s.generateFixtures { s.T().Log("Generate fixtures is set to true, but TestVerifyMembership does not support it (yet)") @@ -221,7 +222,7 @@ func (s *SP1ICS07TendermintTestSuite) MembershipTest(pt operator.SupportedProofT var membershipKey [][]byte s.Require().True(s.Run("Generate keys", func() { // Prove the bank balance of UserA - key, err := cosmos.BankBalanceKey(s.UserB.Address(), simd.Config().Denom) + key, err := cosmos.BankBalanceKey(simdUser.Address(), simd.Config().Denom) s.Require().NoError(err) membershipKey = [][]byte{[]byte(banktypes.StoreKey), key} @@ -318,7 +319,8 @@ func (s *SP1ICS07TendermintTestSuite) TestUpdateClientAndMembership_Groth16() { func (s *SP1ICS07TendermintTestSuite) UpdateClientAndMembershipTest(ctx context.Context, pt operator.SupportedProofType) { s.SetupSuite(ctx, pt) - eth, simd := s.EthChain, s.ChainB + eth, simd := s.EthChain, s.CosmosChains[0] + simdUser := s.CosmosUsers[0] if s.generateFixtures { s.T().Log("Generate fixtures is set to true, but TestUpdateClientAndMembership does not support it (yet)") @@ -331,7 +333,7 @@ func (s *SP1ICS07TendermintTestSuite) UpdateClientAndMembershipTest(ctx context. ) s.Require().True(s.Run("Generate keys", func() { // Prove the bank balance of UserA - key, err := cosmos.BankBalanceKey(s.UserB.Address(), simd.Config().Denom) + key, err := cosmos.BankBalanceKey(simdUser.Address(), simd.Config().Denom) s.Require().NoError(err) membershipKey = [][]byte{[]byte(banktypes.StoreKey), key} @@ -413,7 +415,7 @@ func (s *SP1ICS07TendermintTestSuite) TestDoubleSignMisbehaviour_Groth16() { func (s *SP1ICS07TendermintTestSuite) DoubleSignMisbehaviourTest(ctx context.Context, fixName string, pt operator.SupportedProofType) { s.SetupSuite(ctx, pt) - eth, simd := s.EthChain, s.ChainB + eth, simd := s.EthChain, s.CosmosChains[0] _ = eth var height clienttypes.Height @@ -518,7 +520,7 @@ func (s *SP1ICS07TendermintTestSuite) TestBreakingTimeMonotonicityMisbehaviour_G func (s *SP1ICS07TendermintTestSuite) BreakingTimeMonotonicityMisbehaviourTest(ctx context.Context, fixName string, pt operator.SupportedProofType) { s.SetupSuite(ctx, pt) - eth, simd := s.EthChain, s.ChainB + eth, simd := s.EthChain, s.CosmosChains[0] var height clienttypes.Height var trustedHeader tmclient.Header @@ -607,7 +609,8 @@ func (s *SP1ICS07TendermintTestSuite) largeMembershipTest(n uint64, pt operator. s.SetupSuite(ctx, pt) - eth, simd := s.EthChain, s.ChainB + eth, simd := s.EthChain, s.CosmosChains[0] + simdUser := s.CosmosUsers[0] s.Require().True(s.Run(fmt.Sprintf("Large membership test with %d key-value pairs", n), func() { membershipKeys := make([][][]byte, n) @@ -623,16 +626,16 @@ func (s *SP1ICS07TendermintTestSuite) largeMembershipTest(n uint64, pt operator. acc := sdk.AccAddress(pub.Address()) // Send some funds to the address - msgs = append(msgs, banktypes.NewMsgSend(s.UserB.Address(), acc, sdk.NewCoins(sdk.NewCoin(simd.Config().Denom, math.NewInt(1))))) + msgs = append(msgs, banktypes.NewMsgSend(simdUser.Address(), acc, sdk.NewCoins(sdk.NewCoin(simd.Config().Denom, math.NewInt(1))))) - key, err := cosmos.BankBalanceKey(s.UserB.Address(), simd.Config().Denom) + key, err := cosmos.BankBalanceKey(simdUser.Address(), simd.Config().Denom) s.Require().NoError(err) membershipKeys[i] = [][]byte{[]byte(banktypes.StoreKey), key} } // Send the messages - _, err := s.BroadcastMessages(ctx, simd, s.UserB, 20_000_000, msgs...) + _, err := s.BroadcastMessages(ctx, simd, simdUser, 20_000_000, msgs...) s.Require().NoError(err) })) From f13395e276a112cd41cba881c20880f987d090ea Mon Sep 17 00:00:00 2001 From: srdtrk Date: Fri, 13 Dec 2024 12:59:38 +0800 Subject: [PATCH 18/26] e2e: added eth testnet none --- e2e/interchaintestv8/e2esuite/suite.go | 2 ++ e2e/interchaintestv8/testvalues/values.go | 2 ++ 2 files changed, 4 insertions(+) diff --git a/e2e/interchaintestv8/e2esuite/suite.go b/e2e/interchaintestv8/e2esuite/suite.go index 67d58b2b..f4052a50 100644 --- a/e2e/interchaintestv8/e2esuite/suite.go +++ b/e2e/interchaintestv8/e2esuite/suite.go @@ -67,6 +67,8 @@ func (s *TestSuite) SetupSuite(ctx context.Context) { } kurtosisChain.Destroy(ctx) }) + case testvalues.EthTestnetTypeNone: + // Do nothing default: s.T().Fatalf("Unknown Ethereum testnet type: %s", s.ethTestnetType) } diff --git a/e2e/interchaintestv8/testvalues/values.go b/e2e/interchaintestv8/testvalues/values.go index 3bcdb81d..aa050c33 100644 --- a/e2e/interchaintestv8/testvalues/values.go +++ b/e2e/interchaintestv8/testvalues/values.go @@ -49,6 +49,8 @@ const ( EthTestnetTypePoW = "pow" // EthTestnetTypePoS is the Ethereum testnet type for using a proof of stake chain EthTestnetTypePoS = "pos" + // EthTestnetTypeNone is the Ethereum testnet type for using no chain. + EthTestnetTypeNone = "none" // EnvKeyEthTestnetType The Ethereum testnet type (pow|pos). EnvKeyEthTestnetType = "ETH_TESTNET_TYPE" // EnvE2EFacuetAddress The address of the faucet From 5d97c7d5361e188a045e863d9a69c1af19c96f3f Mon Sep 17 00:00:00 2001 From: srdtrk Date: Fri, 13 Dec 2024 13:22:21 +0800 Subject: [PATCH 19/26] e2e: refactor --- e2e/interchaintestv8/relayer/config.go | 47 +++++++++++++++++-- .../relayer/cosmos_to_cosmos_config.tmpl | 26 ++++++++++ e2e/interchaintestv8/relayer/relayer.go | 9 +--- e2e/interchaintestv8/relayer_test.go | 7 +-- 4 files changed, 76 insertions(+), 13 deletions(-) create mode 100644 e2e/interchaintestv8/relayer/cosmos_to_cosmos_config.tmpl diff --git a/e2e/interchaintestv8/relayer/config.go b/e2e/interchaintestv8/relayer/config.go index b15fd295..7020853c 100644 --- a/e2e/interchaintestv8/relayer/config.go +++ b/e2e/interchaintestv8/relayer/config.go @@ -5,8 +5,8 @@ import ( "text/template" ) -// ConfigInfo is a struct that holds the configuration information for the config template -type ConfigInfo struct { +// EthToCosmosConfigInfo is a struct that holds the configuration information for the Ethereum to Cosmos config template +type EthToCosmosConfigInfo struct { // Tendermint RPC URL TmRPC string // ICS26 Router address @@ -17,7 +17,7 @@ type ConfigInfo struct { SP1PrivateKey string } -func (c *ConfigInfo) GenerateConfigFile(path string) error { +func (c *EthToCosmosConfigInfo) GenerateEthToCosmosConfigFile(path string) error { tmpl, err := template.ParseFiles("e2e/interchaintestv8/relayer/config.tmpl") if err != nil { return err @@ -29,6 +29,47 @@ func (c *ConfigInfo) GenerateConfigFile(path string) error { } defer f.Close() + return tmpl.Execute(f, c) +} + +// EthToCosmosGRPCAddress returns the address for the eth to cosmos relayer gRPC server. +func (c *EthToCosmosConfigInfo) EthToCosmosGRPCAddress() string { + return "127.0.0.1:3000" +} + +// CosmosToCosmosConfigInfo is a struct that holds the configuration information for the Cosmos to Cosmos config template +type CosmosToCosmosConfigInfo struct { + // ChainA Tendermint RPC URL + ChainATmRPC string + // ChainB Tendermint RPC URL + ChainBTmRPC string + // ChainA Submitter address + ChainAUser string + // ChainB Submitter address + ChainBUser string +} + +func (c *CosmosToCosmosConfigInfo) GenerateCosmosToCosmosConfigFile(path string) error { + tmpl, err := template.ParseFiles("e2e/interchaintestv8/relayer/cosmos_to_cosmos_config.tmpl") + if err != nil { + return err + } + f, err := os.Create(path) + if err != nil { + return err + } + + defer f.Close() return tmpl.Execute(f, c) } + +// ChainAToChainBGRPCAddress returns the address for the cosmos to cosmos relayer gRPC server. +func (c *CosmosToCosmosConfigInfo) ChainAToChainBGRPCAddress() string { + return "127.0.0.1:3001" +} + +// ChainBToChainAGRPCAddress returns the address for the cosmos to cosmos relayer gRPC server. +func (c *CosmosToCosmosConfigInfo) ChainBToChainAGRPCAddress() string { + return "127.0.0.1:3002" +} diff --git a/e2e/interchaintestv8/relayer/cosmos_to_cosmos_config.tmpl b/e2e/interchaintestv8/relayer/cosmos_to_cosmos_config.tmpl new file mode 100644 index 000000000..c5f10a30 --- /dev/null +++ b/e2e/interchaintestv8/relayer/cosmos_to_cosmos_config.tmpl @@ -0,0 +1,26 @@ +{ + "server": { + "log_level": "info", + "address": "127.0.0.1" + }, + "modules": [ + { + "name": "cosmos_to_cosmos", + "port": 3001, + "config": { + "src_rpc_url": "{{ .ChainARPC }}", + "target_rpc_url": "{{ .ChainBRPC }}", + "signer_address": "{{ .ChainBUser }}" + } + }, + { + "name": "cosmos_to_cosmos", + "port": 3002, + "config": { + "src_rpc_url": "{{ .ChainBRPC }}", + "target_rpc_url": "{{ .ChainARPC }}", + "signer_address": "{{ .ChainAUser }}" + } + } + ] +} diff --git a/e2e/interchaintestv8/relayer/relayer.go b/e2e/interchaintestv8/relayer/relayer.go index 13c0ff18..e7de0dec 100644 --- a/e2e/interchaintestv8/relayer/relayer.go +++ b/e2e/interchaintestv8/relayer/relayer.go @@ -34,14 +34,9 @@ func StartRelayer(configPath string) (*os.Process, error) { return cmd.Process, nil } -// defaultGRPCAddress returns the default address for the gRPC server. -func defaultGRPCAddress() string { - return "127.0.0.1:3000" -} - // GetGRPCClient returns a gRPC client for the relayer. -func GetGRPCClient() (relayertypes.RelayerServiceClient, error) { - conn, err := grpc.NewClient(defaultGRPCAddress(), grpc.WithTransportCredentials(insecure.NewCredentials())) +func GetGRPCClient(addr string) (relayertypes.RelayerServiceClient, error) { + conn, err := grpc.NewClient(addr, grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { return nil, err } diff --git a/e2e/interchaintestv8/relayer_test.go b/e2e/interchaintestv8/relayer_test.go index b3f9d198..9f84f361 100644 --- a/e2e/interchaintestv8/relayer_test.go +++ b/e2e/interchaintestv8/relayer_test.go @@ -58,15 +58,16 @@ func (s *RelayerTestSuite) SetupSuite(ctx context.Context, proofType operator.Su eth, simd := s.EthChain, s.CosmosChains[0] var relayerProcess *os.Process + var configInfo relayer.EthToCosmosConfigInfo s.Require().True(s.Run("Start Relayer", func() { - configInfo := relayer.ConfigInfo{ + configInfo = relayer.EthToCosmosConfigInfo{ TmRPC: simd.GetHostRPCAddress(), ICS26Address: s.contractAddresses.Ics26Router, EthRPC: eth.RPC, SP1PrivateKey: os.Getenv(testvalues.EnvKeySp1PrivateKey), } - err := configInfo.GenerateConfigFile(testvalues.RelayerConfigFilePath) + err := configInfo.GenerateEthToCosmosConfigFile(testvalues.RelayerConfigFilePath) s.Require().NoError(err) relayerProcess, err = relayer.StartRelayer(testvalues.RelayerConfigFilePath) @@ -85,7 +86,7 @@ func (s *RelayerTestSuite) SetupSuite(ctx context.Context, proofType operator.Su s.Require().True(s.Run("Create Relayer Client", func() { var err error - s.RelayerClient, err = relayer.GetGRPCClient() + s.RelayerClient, err = relayer.GetGRPCClient(configInfo.EthToCosmosGRPCAddress()) s.Require().NoError(err) })) } From 0c58fae6ee51b03afde979b1ee9149ffde91806e Mon Sep 17 00:00:00 2001 From: srdtrk Date: Fri, 13 Dec 2024 16:13:12 +0800 Subject: [PATCH 20/26] imp: added chain info test --- e2e/interchaintestv8/cosmos_relayer_test.go | 117 ++++++++++++++++++ .../relayer/cosmos_to_cosmos_config.tmpl | 8 +- 2 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 e2e/interchaintestv8/cosmos_relayer_test.go diff --git a/e2e/interchaintestv8/cosmos_relayer_test.go b/e2e/interchaintestv8/cosmos_relayer_test.go new file mode 100644 index 000000000..26b49941 --- /dev/null +++ b/e2e/interchaintestv8/cosmos_relayer_test.go @@ -0,0 +1,117 @@ +package main + +import ( + "context" + "os" + "testing" + + "github.com/stretchr/testify/suite" + + "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v8/ibc" + + "github.com/srdtrk/solidity-ibc-eureka/e2e/v8/chainconfig" + "github.com/srdtrk/solidity-ibc-eureka/e2e/v8/e2esuite" + "github.com/srdtrk/solidity-ibc-eureka/e2e/v8/relayer" + "github.com/srdtrk/solidity-ibc-eureka/e2e/v8/testvalues" + relayertypes "github.com/srdtrk/solidity-ibc-eureka/e2e/v8/types/relayer" +) + +// CosmosRelayerTestSuite is a struct that holds the test suite for two Cosmos chains. +type CosmosRelayerTestSuite struct { + e2esuite.TestSuite + + SimdA *cosmos.CosmosChain + SimdB *cosmos.CosmosChain + + SimdASubmitter ibc.Wallet + SimdBSubmitter ibc.Wallet + + AtoBRelayerClient relayertypes.RelayerServiceClient + BtoARelayerClient relayertypes.RelayerServiceClient +} + +// TestWithIbcEurekaTestSuite is the boilerplate code that allows the test suite to be run +func TestWithCosmosRelayerTestSuite(t *testing.T) { + suite.Run(t, new(CosmosRelayerTestSuite)) +} + +// SetupSuite calls the underlying IbcEurekaTestSuite's SetupSuite method +// and deploys the IbcEureka contract +func (s *CosmosRelayerTestSuite) SetupSuite(ctx context.Context) { + ibcSpecs2 := chainconfig.DefaultChainSpecs[0] + ibcSpecs2.ChainID = "simd-2" + ibcSpecs2.Name = "ibc-go-simd-2" + + chainconfig.DefaultChainSpecs = append(chainconfig.DefaultChainSpecs, ibcSpecs2) + + s.TestSuite.SetupSuite(ctx) + + s.SimdA, s.SimdB = s.CosmosChains[0], s.CosmosChains[1] + s.SimdASubmitter = s.CreateAndFundCosmosUser(ctx, s.SimdA) + s.SimdBSubmitter = s.CreateAndFundCosmosUser(ctx, s.SimdB) + + var relayerProcess *os.Process + var configInfo relayer.CosmosToCosmosConfigInfo + s.Require().True(s.Run("Start Relayer", func() { + configInfo = relayer.CosmosToCosmosConfigInfo{ + ChainATmRPC: s.SimdA.GetHostRPCAddress(), + ChainBTmRPC: s.SimdB.GetHostRPCAddress(), + ChainAUser: s.SimdASubmitter.FormattedAddress(), + ChainBUser: s.SimdBSubmitter.FormattedAddress(), + } + + err := configInfo.GenerateCosmosToCosmosConfigFile(testvalues.RelayerConfigFilePath) + s.Require().NoError(err) + + relayerProcess, err = relayer.StartRelayer(testvalues.RelayerConfigFilePath) + s.Require().NoError(err) + + s.T().Cleanup(func() { + os.Remove(testvalues.RelayerConfigFilePath) + }) + })) + + s.T().Cleanup(func() { + if relayerProcess != nil { + _ = relayerProcess.Kill() + } + }) + + s.Require().True(s.Run("Create Relayer Client", func() { + var err error + s.AtoBRelayerClient, err = relayer.GetGRPCClient(configInfo.ChainAToChainBGRPCAddress()) + s.Require().NoError(err) + + s.BtoARelayerClient, err = relayer.GetGRPCClient(configInfo.ChainBToChainAGRPCAddress()) + s.Require().NoError(err) + })) +} + +// TestRelayer is a test that runs the relayer +func (s *CosmosRelayerTestSuite) TestRelayerInfo() { + ctx := context.Background() + s.SetupSuite(ctx) + + s.Run("Chain A to B Relayer Info", func() { + info, err := s.AtoBRelayerClient.Info(context.Background(), &relayertypes.InfoRequest{}) + s.Require().NoError(err) + s.Require().NotNil(info) + + s.T().Logf("Relayer Info: %+v", info) + + s.Require().Equal(s.SimdA.Config().ChainID, info.SourceChain.ChainId) + s.Require().Equal(s.SimdB.Config().ChainID, info.TargetChain.ChainId) + }) + + s.Run("Chain B to A Relayer Info", func() { + info, err := s.BtoARelayerClient.Info(context.Background(), &relayertypes.InfoRequest{}) + s.Require().NoError(err) + s.Require().NotNil(info) + + s.T().Logf("Relayer Info: %+v", info) + + s.Require().Equal(s.SimdB.Config().ChainID, info.SourceChain.ChainId) + s.Require().Equal(s.SimdA.Config().ChainID, info.TargetChain.ChainId) + }) +} diff --git a/e2e/interchaintestv8/relayer/cosmos_to_cosmos_config.tmpl b/e2e/interchaintestv8/relayer/cosmos_to_cosmos_config.tmpl index c5f10a30..9b6adaf1 100644 --- a/e2e/interchaintestv8/relayer/cosmos_to_cosmos_config.tmpl +++ b/e2e/interchaintestv8/relayer/cosmos_to_cosmos_config.tmpl @@ -8,8 +8,8 @@ "name": "cosmos_to_cosmos", "port": 3001, "config": { - "src_rpc_url": "{{ .ChainARPC }}", - "target_rpc_url": "{{ .ChainBRPC }}", + "src_rpc_url": "{{ .ChainATmRPC }}", + "target_rpc_url": "{{ .ChainBTmRPC }}", "signer_address": "{{ .ChainBUser }}" } }, @@ -17,8 +17,8 @@ "name": "cosmos_to_cosmos", "port": 3002, "config": { - "src_rpc_url": "{{ .ChainBRPC }}", - "target_rpc_url": "{{ .ChainARPC }}", + "src_rpc_url": "{{ .ChainBTmRPC }}", + "target_rpc_url": "{{ .ChainATmRPC }}", "signer_address": "{{ .ChainAUser }}" } } From b267c93e18a57bd94abee2117a12d2f3274e8e18 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Fri, 13 Dec 2024 16:20:18 +0800 Subject: [PATCH 21/26] ci: added test --- .github/workflows/e2e.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 51e7c695..217c390b 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -78,6 +78,7 @@ jobs: - TestWithRelayerTestSuite/TestTimeoutPacketFromEth_Plonk - TestWithRelayerTestSuite/Test_10_TimeoutPacketFromEth_Groth16 - TestWithRelayerTestSuite/Test_5_TimeoutPacketFromEth_Plonk + - TestWithCosmosRelayerTestSuite/TestRelayerInfo - TestWithSP1ICS07TendermintTestSuite/TestDeploy_Groth16 - TestWithSP1ICS07TendermintTestSuite/TestDeploy_Plonk - TestWithSP1ICS07TendermintTestSuite/TestUpdateClient_Groth16 From 0a2289735fc6bb27b0c601e617484c000b0d699a Mon Sep 17 00:00:00 2001 From: srdtrk Date: Fri, 13 Dec 2024 16:37:46 +0800 Subject: [PATCH 22/26] feat: test passing --- e2e/interchaintestv8/cosmos_relayer_test.go | 12 +++++++++--- e2e/interchaintestv8/sp1_ics07_test.go | 2 +- justfile | 5 +++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/e2e/interchaintestv8/cosmos_relayer_test.go b/e2e/interchaintestv8/cosmos_relayer_test.go index 26b49941..62a15b78 100644 --- a/e2e/interchaintestv8/cosmos_relayer_test.go +++ b/e2e/interchaintestv8/cosmos_relayer_test.go @@ -39,11 +39,14 @@ func TestWithCosmosRelayerTestSuite(t *testing.T) { // SetupSuite calls the underlying IbcEurekaTestSuite's SetupSuite method // and deploys the IbcEureka contract func (s *CosmosRelayerTestSuite) SetupSuite(ctx context.Context) { - ibcSpecs2 := chainconfig.DefaultChainSpecs[0] + //nolint:govet + ibcSpecs2 := *chainconfig.DefaultChainSpecs[0] ibcSpecs2.ChainID = "simd-2" ibcSpecs2.Name = "ibc-go-simd-2" - chainconfig.DefaultChainSpecs = append(chainconfig.DefaultChainSpecs, ibcSpecs2) + chainconfig.DefaultChainSpecs = append(chainconfig.DefaultChainSpecs, &ibcSpecs2) + + os.Setenv(testvalues.EnvKeyEthTestnetType, testvalues.EthTestnetTypeNone) s.TestSuite.SetupSuite(ctx) @@ -54,6 +57,9 @@ func (s *CosmosRelayerTestSuite) SetupSuite(ctx context.Context) { var relayerProcess *os.Process var configInfo relayer.CosmosToCosmosConfigInfo s.Require().True(s.Run("Start Relayer", func() { + err := os.Chdir("../..") + s.Require().NoError(err) + configInfo = relayer.CosmosToCosmosConfigInfo{ ChainATmRPC: s.SimdA.GetHostRPCAddress(), ChainBTmRPC: s.SimdB.GetHostRPCAddress(), @@ -61,7 +67,7 @@ func (s *CosmosRelayerTestSuite) SetupSuite(ctx context.Context) { ChainBUser: s.SimdBSubmitter.FormattedAddress(), } - err := configInfo.GenerateCosmosToCosmosConfigFile(testvalues.RelayerConfigFilePath) + err = configInfo.GenerateCosmosToCosmosConfigFile(testvalues.RelayerConfigFilePath) s.Require().NoError(err) relayerProcess, err = relayer.StartRelayer(testvalues.RelayerConfigFilePath) diff --git a/e2e/interchaintestv8/sp1_ics07_test.go b/e2e/interchaintestv8/sp1_ics07_test.go index ce831053..a730f9cc 100644 --- a/e2e/interchaintestv8/sp1_ics07_test.go +++ b/e2e/interchaintestv8/sp1_ics07_test.go @@ -72,7 +72,7 @@ func (s *SP1ICS07TendermintTestSuite) SetupSuite(ctx context.Context, pt operato os.Setenv(testvalues.EnvKeyRustLog, testvalues.EnvValueRustLog_Info) os.Setenv(testvalues.EnvKeyEthRPC, eth.RPC) os.Setenv(testvalues.EnvKeyTendermintRPC, simd.GetHostRPCAddress()) - os.Setenv(testvalues.EnvKeySp1Prover, "network") + os.Setenv(testvalues.EnvKeySp1Prover, testvalues.EnvValueSp1Prover_Network) os.Setenv(testvalues.EnvKeyOperatorPrivateKey, hex.EncodeToString(crypto.FromECDSA(s.key))) s.generateFixtures = os.Getenv(testvalues.EnvKeyGenerateSolidityFixtures) == testvalues.EnvValueGenerateFixtures_True diff --git a/justfile b/justfile index 9c805b53..e3479b23 100644 --- a/justfile +++ b/justfile @@ -90,6 +90,11 @@ test-e2e-relayer testname: clean @echo "Running {{testname}} test..." cd e2e/interchaintestv8 && go test -v -run '^TestWithRelayerTestSuite/{{testname}}$' -timeout 40m +# Run the e2e tests in the relayer test suite +test-e2e-cosmos-relayer testname: clean + @echo "Running {{testname}} test..." + cd e2e/interchaintestv8 && go test -v -run '^TestWithCosmosRelayerTestSuite/{{testname}}$' -timeout 40m + # Run the e2e tests in the relayer test suite test-e2e-sp1-ics07 testname: clean @echo "Running {{testname}} test..." From 542f77e55509cc3a7a3c4584c9e34ef199013757 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Fri, 13 Dec 2024 16:46:51 +0800 Subject: [PATCH 23/26] e2e: refactor --- e2e/interchaintestv8/chainconfig/chain_config.go | 12 ++++++++---- e2e/interchaintestv8/cosmos_relayer_test.go | 7 +------ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/e2e/interchaintestv8/chainconfig/chain_config.go b/e2e/interchaintestv8/chainconfig/chain_config.go index bd19638f..d423ae5f 100644 --- a/e2e/interchaintestv8/chainconfig/chain_config.go +++ b/e2e/interchaintestv8/chainconfig/chain_config.go @@ -7,11 +7,15 @@ import ( var DefaultChainSpecs = []*interchaintest.ChainSpec{ // -- IBC-Go -- - { + IbcGoChainSpec("ibc-go-simd-1", "simd-1"), +} + +func IbcGoChainSpec(name, chainId string) *interchaintest.ChainSpec { + return &interchaintest.ChainSpec{ ChainConfig: ibc.ChainConfig{ Type: "cosmos", - Name: "ibc-go-simd", - ChainID: "simd-1", + Name: name, + ChainID: chainId, Images: []ibc.DockerImage{ { Repository: "ghcr.io/cosmos/ibc-go-wasm-simd", // FOR LOCAL IMAGE USE: Docker Image Name @@ -29,5 +33,5 @@ var DefaultChainSpecs = []*interchaintest.ChainSpec{ TrustingPeriod: "508h", NoHostMount: false, }, - }, + } } diff --git a/e2e/interchaintestv8/cosmos_relayer_test.go b/e2e/interchaintestv8/cosmos_relayer_test.go index 62a15b78..425de213 100644 --- a/e2e/interchaintestv8/cosmos_relayer_test.go +++ b/e2e/interchaintestv8/cosmos_relayer_test.go @@ -39,12 +39,7 @@ func TestWithCosmosRelayerTestSuite(t *testing.T) { // SetupSuite calls the underlying IbcEurekaTestSuite's SetupSuite method // and deploys the IbcEureka contract func (s *CosmosRelayerTestSuite) SetupSuite(ctx context.Context) { - //nolint:govet - ibcSpecs2 := *chainconfig.DefaultChainSpecs[0] - ibcSpecs2.ChainID = "simd-2" - ibcSpecs2.Name = "ibc-go-simd-2" - - chainconfig.DefaultChainSpecs = append(chainconfig.DefaultChainSpecs, &ibcSpecs2) + chainconfig.DefaultChainSpecs = append(chainconfig.DefaultChainSpecs, chainconfig.IbcGoChainSpec("ibc-go-simd-2", "simd-2")) os.Setenv(testvalues.EnvKeyEthTestnetType, testvalues.EthTestnetTypeNone) From fb23893077802ad4d5c6b0a68dcbac472cb44472 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Fri, 13 Dec 2024 16:54:20 +0800 Subject: [PATCH 24/26] imp: refactored the justfile --- justfile | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/justfile b/justfile index e3479b23..7cbe576d 100644 --- a/justfile +++ b/justfile @@ -80,25 +80,35 @@ generate-abi: build-contracts abigen --abi abi/IBCERC20.json --pkg ibcerc20 --type Contract --out abigen/ibcerc20/contract.go abigen --abi abi/ICS20Lib.json --pkg ics20lib --type Lib --out abigen/ics20lib/lib.go -# Run the e2e tests +# Run any e2e test in the interchaintestv8 test suite using the test's full name +# For example, `just test-e2e TestWithIbcEurekaTestSuite/TestDeploy_Groth16` test-e2e testname: clean @echo "Running {{testname}} test..." - cd e2e/interchaintestv8 && go test -v -run '^TestWithIbcEurekaTestSuite/{{testname}}$' -timeout 40m + cd e2e/interchaintestv8 && go test -v -run '^{{testname}}$' -timeout 40m -# Run the e2e tests in the relayer test suite +# Run any e2e test in the IbcEurekaTestSuite using the test's name +# For example, `just test-e2e-eureka TestDeploy_Groth16` +test-e2e-eureka testname: clean + @echo "Running {{testname}} test..." + just test-e2e TestWithIbcEurekaTestSuite/{{testname}} + +# Run any e2e test in the RelayerTestSuite using the test's name +# For example, `just test-e2e-relayer TestRelayerInfo` test-e2e-relayer testname: clean @echo "Running {{testname}} test..." - cd e2e/interchaintestv8 && go test -v -run '^TestWithRelayerTestSuite/{{testname}}$' -timeout 40m + just test-e2e TestWithRelayerTestSuite/{{testname}} -# Run the e2e tests in the relayer test suite +# Run any e2e test in the CosmosRelayerTestSuite using the test's name +# For example, `just test-e2e-cosmos-relayer TestRelayerInfo` test-e2e-cosmos-relayer testname: clean @echo "Running {{testname}} test..." - cd e2e/interchaintestv8 && go test -v -run '^TestWithCosmosRelayerTestSuite/{{testname}}$' -timeout 40m + just test-e2e TestWithCosmosRelayerTestSuite/{{testname}} -# Run the e2e tests in the relayer test suite +# Run anu e2e test in the SP1ICS07TendermintTestSuite using the test's name +# For example, `just test-e2e-sp1-ics07 TestDeploy_Groth16` test-e2e-sp1-ics07 testname: clean @echo "Running {{testname}} test..." - cd e2e/interchaintestv8 && go test -v -run '^TestWithSP1ICS07TendermintTestSuite/{{testname}}$' -timeout 40m + just test-e2e TestWithSP1ICS07TendermintTestSuite/{{testname}} # Install the sp1-ics07-tendermint operator for use in the e2e tests install-operator: From 667393d1b14db4b2c808ca8502b736dd437aac3d Mon Sep 17 00:00:00 2001 From: srdtrk Date: Fri, 13 Dec 2024 17:10:12 +0800 Subject: [PATCH 25/26] imp: updated cosmos event key --- packages/relayer-lib/src/events/cosmos_sdk.rs | 8 ++++---- packages/relayer-lib/src/events/eureka.rs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/relayer-lib/src/events/cosmos_sdk.rs b/packages/relayer-lib/src/events/cosmos_sdk.rs index cb4a61ce..3983e278 100644 --- a/packages/relayer-lib/src/events/cosmos_sdk.rs +++ b/packages/relayer-lib/src/events/cosmos_sdk.rs @@ -28,7 +28,7 @@ pub const ATTRIBUTE_KEY_DST_CHANNEL: &str = "packet_dest_channel"; pub const ATTRIBUTE_KEY_SEQUENCE: &str = "packet_sequence"; /// The attribute key for the timeout timestamp. pub const ATTRIBUTE_KEY_TIMEOUT_TIMESTAMP: &str = "packet_timeout_timestamp"; -/// The attribute key for the packet data hex. -pub const ATTRIBUTE_KEY_PACKET_DATA_HEX: &str = "packet_data_hex"; -/// The attribute key for the acknowledgement data hex. -pub const ATTRIBUTE_KEY_ACK_DATA_HEX: &str = "acknowledgement_data_hex"; +/// The attribute key for the encoded packet hex. +pub const ATTRIBUTE_KEY_ENCODED_PACKET_HEX: &str = "encoded_packet_hex"; +/// The attribute key for the encoded acknowledgement hex. +pub const ATTRIBUTE_KEY_ENCODED_ACK_HEX: &str = "encoded_acknowledgement_hex"; diff --git a/packages/relayer-lib/src/events/eureka.rs b/packages/relayer-lib/src/events/eureka.rs index c6574a22..55e97360 100644 --- a/packages/relayer-lib/src/events/eureka.rs +++ b/packages/relayer-lib/src/events/eureka.rs @@ -69,7 +69,7 @@ impl TryFrom for EurekaEvent { .attributes .into_iter() .find_map(|attr| { - if attr.key_str().ok()? == cosmos_sdk::ATTRIBUTE_KEY_PACKET_DATA_HEX { + if attr.key_str().ok()? == cosmos_sdk::ATTRIBUTE_KEY_ENCODED_PACKET_HEX { let packet: Vec = hex::decode(attr.value_str().ok()?).ok()?; let packet = Packet::decode(packet.as_slice()).ok()?; Some(Self::SendPacket(SendPacket { @@ -84,7 +84,7 @@ impl TryFrom for EurekaEvent { .attributes .into_iter() .find_map(|attr| { - if attr.key_str().ok()? == cosmos_sdk::ATTRIBUTE_KEY_PACKET_DATA_HEX { + if attr.key_str().ok()? == cosmos_sdk::ATTRIBUTE_KEY_ENCODED_PACKET_HEX { let packet: Vec = hex::decode(attr.value_str().ok()?).ok()?; let packet = Packet::decode(packet.as_slice()).ok()?; Some(Self::RecvPacket(RecvPacket { @@ -100,12 +100,12 @@ impl TryFrom for EurekaEvent { .attributes .into_iter() .filter_map(|attr| match attr.key_str().ok()? { - cosmos_sdk::ATTRIBUTE_KEY_ACK_DATA_HEX => { + cosmos_sdk::ATTRIBUTE_KEY_ENCODED_ACK_HEX => { let ack_data = hex::decode(attr.value_str().ok()?).ok()?; let ack = Acknowledgement::decode(ack_data.as_slice()).ok()?; Some((Some(ack), None)) } - cosmos_sdk::ATTRIBUTE_KEY_PACKET_DATA_HEX => { + cosmos_sdk::ATTRIBUTE_KEY_ENCODED_PACKET_HEX => { let packet_data = hex::decode(attr.value_str().ok()?).ok()?; let packet = Packet::decode(packet_data.as_slice()).ok()?; Some((None, Some(packet))) From 519a72c6b8b4acacc053fc260bba4c668cad66d7 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Fri, 13 Dec 2024 21:47:29 +0800 Subject: [PATCH 26/26] imp: review items --- e2e/interchaintestv8/cosmos_relayer_test.go | 5 ++++- e2e/interchaintestv8/relayer_test.go | 5 ++++- packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs | 3 ++- packages/relayer-lib/src/tx_builder/eth_eureka.rs | 3 ++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/e2e/interchaintestv8/cosmos_relayer_test.go b/e2e/interchaintestv8/cosmos_relayer_test.go index 425de213..4116b7dd 100644 --- a/e2e/interchaintestv8/cosmos_relayer_test.go +++ b/e2e/interchaintestv8/cosmos_relayer_test.go @@ -75,7 +75,10 @@ func (s *CosmosRelayerTestSuite) SetupSuite(ctx context.Context) { s.T().Cleanup(func() { if relayerProcess != nil { - _ = relayerProcess.Kill() + err := relayerProcess.Kill() + if err != nil { + s.T().Logf("Failed to kill the relayer process: %v", err) + } } }) diff --git a/e2e/interchaintestv8/relayer_test.go b/e2e/interchaintestv8/relayer_test.go index 9f84f361..5af7142a 100644 --- a/e2e/interchaintestv8/relayer_test.go +++ b/e2e/interchaintestv8/relayer_test.go @@ -80,7 +80,10 @@ func (s *RelayerTestSuite) SetupSuite(ctx context.Context, proofType operator.Su s.T().Cleanup(func() { if relayerProcess != nil { - _ = relayerProcess.Kill() + err := relayerProcess.Kill() + if err != nil { + s.T().Logf("Failed to kill the relayer process: %v", err) + } } }) diff --git a/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs b/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs index 15af1f98..c2ac5336 100644 --- a/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs +++ b/packages/relayer-lib/src/tx_builder/cosmos_to_cosmos.rs @@ -1,4 +1,5 @@ -//! The `ChainSubmitter` submits txs to [`CosmosSdk`] based on events from [`CosmosSdk`]. +//! This module defines [`TxBuilder`] which is responsible for building transactions to be sent to +//! the Cosmos SDK chain from events received from another Cosmos SDK chain. use anyhow::Result; use futures::future; diff --git a/packages/relayer-lib/src/tx_builder/eth_eureka.rs b/packages/relayer-lib/src/tx_builder/eth_eureka.rs index 867a89c9..b131df83 100644 --- a/packages/relayer-lib/src/tx_builder/eth_eureka.rs +++ b/packages/relayer-lib/src/tx_builder/eth_eureka.rs @@ -1,4 +1,5 @@ -//! The `ChainSubmitter` submits txs to [`EthEureka`] based on events from [`CosmosSdk`]. +//! This module defines [`TxBuilder`] which is responsible for building transactions to be sent to +//! the Ethereum chain from events received from the Cosmos SDK chain. use std::{env, str::FromStr};