From 5a9cd844dde0b54b35cb3ddd70a0c52a1818c6d7 Mon Sep 17 00:00:00 2001 From: Daniel Savu <23065004+daniel-savu@users.noreply.github.com> Date: Tue, 21 Nov 2023 12:10:54 +0000 Subject: [PATCH] Dan/more cw agent remediations (#2912) ### Description ### Drive-by changes ### Related issues ### Backward compatibility ### Testing --- .gitignore | 3 - rust/Cargo.lock | 27 +-- rust/Cargo.toml | 207 +++++++++--------- rust/chains/hyperlane-cosmos/Cargo.toml | 28 +-- rust/chains/hyperlane-cosmos/src/mailbox.rs | 8 +- .../src/payloads/ism_routes.rs | 2 +- rust/chains/hyperlane-cosmos/src/types.rs | 22 +- .../src/validator_announce.rs | 7 +- rust/chains/hyperlane-ethereum/Cargo.toml | 6 - rust/chains/hyperlane-fuel/Cargo.toml | 6 - rust/hyperlane-base/Cargo.toml | 1 + .../src/settings/parser/connection_parser.rs | 127 +++++++++++ .../hyperlane-base/src/settings/parser/mod.rs | 113 +--------- rust/hyperlane-base/src/settings/signers.rs | 54 +++-- rust/hyperlane-core/src/traits/mod.rs | 17 ++ 15 files changed, 315 insertions(+), 313 deletions(-) create mode 100644 rust/hyperlane-base/src/settings/parser/connection_parser.rs diff --git a/.gitignore b/.gitignore index 175e312900..f9892417af 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,3 @@ yarn-error.log .vscode tsconfig.editor.json - -rust/neutron_validator_sigs -rust/relayer_db \ No newline at end of file diff --git a/rust/Cargo.lock b/rust/Cargo.lock index f4a829246c..b8eb2e6580 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -3872,28 +3872,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "hpl-interface" -version = "0.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ce374f1f3bf048eacfff71e74ecf4700ef4e6d26085c9b3d89f5bb19bdf1ff5" -dependencies = [ - "bech32 0.9.1", - "cosmwasm-schema", - "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus", - "cw2", - "cw20", - "cw20-base", - "ripemd", - "schemars", - "serde", - "sha2 0.10.8", - "sha3 0.10.8", - "thiserror", -] - [[package]] name = "hpl-interface" version = "0.0.6-rc3" @@ -4099,6 +4077,7 @@ dependencies = [ "tracing-error", "tracing-futures", "tracing-subscriber", + "url", "walkdir", "warp", ] @@ -4157,7 +4136,7 @@ dependencies = [ "cosmrs", "derive-new", "hex 0.4.3", - "hpl-interface 0.0.2", + "hpl-interface", "hyper", "hyper-tls", "hyperlane-core", @@ -6922,7 +6901,7 @@ dependencies = [ "ctrlc", "eyre", "hex 0.4.3", - "hpl-interface 0.0.6-rc3", + "hpl-interface", "hyperlane-core", "k256 0.13.1", "macro_rules_attribute", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index d9d2534752..c1ee840430 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,43 +1,43 @@ [workspace] members = [ - "agents/relayer", - "agents/scraper", - "agents/validator", - "chains/hyperlane-cosmos", - "chains/hyperlane-ethereum", - "chains/hyperlane-fuel", - "chains/hyperlane-sealevel", - "ethers-prometheus", - "hyperlane-base", - "hyperlane-core", - "hyperlane-test", - "sealevel/client", - "sealevel/libraries/access-control", - "sealevel/libraries/account-utils", - "sealevel/libraries/ecdsa-signature", - "sealevel/libraries/hyperlane-sealevel-connection-client", - "sealevel/libraries/hyperlane-sealevel-token", - "sealevel/libraries/interchain-security-module-interface", - "sealevel/libraries/message-recipient-interface", - "sealevel/libraries/multisig-ism", - "sealevel/libraries/serializable-account-meta", - "sealevel/libraries/test-transaction-utils", - "sealevel/libraries/test-utils", - "sealevel/programs/hyperlane-sealevel-token", - "sealevel/programs/hyperlane-sealevel-token-collateral", - "sealevel/programs/hyperlane-sealevel-token-native", - "sealevel/programs/hyperlane-sealevel-igp", - "sealevel/programs/hyperlane-sealevel-igp-test", - "sealevel/programs/ism/multisig-ism-message-id", - "sealevel/programs/ism/test-ism", - "sealevel/programs/mailbox", - "sealevel/programs/mailbox-test", - "sealevel/programs/test-send-receiver", - "sealevel/programs/validator-announce", - "utils/abigen", - "utils/backtrace-oneline", - "utils/hex", - "utils/run-locally", + "agents/relayer", + "agents/scraper", + "agents/validator", + "chains/hyperlane-cosmos", + "chains/hyperlane-ethereum", + "chains/hyperlane-fuel", + "chains/hyperlane-sealevel", + "ethers-prometheus", + "hyperlane-base", + "hyperlane-core", + "hyperlane-test", + "sealevel/client", + "sealevel/libraries/access-control", + "sealevel/libraries/account-utils", + "sealevel/libraries/ecdsa-signature", + "sealevel/libraries/hyperlane-sealevel-connection-client", + "sealevel/libraries/hyperlane-sealevel-token", + "sealevel/libraries/interchain-security-module-interface", + "sealevel/libraries/message-recipient-interface", + "sealevel/libraries/multisig-ism", + "sealevel/libraries/serializable-account-meta", + "sealevel/libraries/test-transaction-utils", + "sealevel/libraries/test-utils", + "sealevel/programs/hyperlane-sealevel-igp", + "sealevel/programs/hyperlane-sealevel-igp-test", + "sealevel/programs/hyperlane-sealevel-token", + "sealevel/programs/hyperlane-sealevel-token-collateral", + "sealevel/programs/hyperlane-sealevel-token-native", + "sealevel/programs/ism/multisig-ism-message-id", + "sealevel/programs/ism/test-ism", + "sealevel/programs/mailbox", + "sealevel/programs/mailbox-test", + "sealevel/programs/test-send-receiver", + "sealevel/programs/validator-announce", + "utils/abigen", + "utils/backtrace-oneline", + "utils/hex", + "utils/run-locally", ] [workspace.package] @@ -62,13 +62,13 @@ bytes = "1" clap = "4" color-eyre = "0.6" config = "0.13.3" +convert_case = "0.6" cosmrs = { version = "0.14", default-features = false, features = [ - "cosmwasm", - "rpc", - "tokio", - "grpc", + "cosmwasm", + "rpc", + "tokio", + "grpc", ] } -convert_case = "0.6" crunchy = "0.2" ctrlc = "3.2" curve25519-dalek = { version = "~3.2", features = ["serde"] } @@ -84,9 +84,14 @@ fuels-code-gen = "0.38" futures = "0.3" futures-util = "0.3" generic-array = { version = "0.14", features = ["serde", "more_lengths"] } -getrandom = { version = "0.2", features = [ - "js", -] } # Required for WASM support https://docs.rs/getrandom/latest/getrandom/#webassembly-support +# Required for WASM support https://docs.rs/getrandom/latest/getrandom/#webassembly-support +bech32 = "0.9.1" +elliptic-curve = "0.12.3" +getrandom = { version = "0.2", features = ["js"] } +hex = "0.4.3" +hpl-interface = "=0.0.6-rc3" +hyper = "0.14" +hyper-tls = "0.5.0" itertools = "0.11.0" jsonrpc-core = "18.0" k256 = { version = "0.13.1", features = ["std", "ecdsa"] } @@ -107,24 +112,27 @@ primitive-types = "=0.12.1" prometheus = "0.13" regex = "1.5" reqwest = "0.11" +ripemd = "0.1.3" rlp = "=0.5.2" rocksdb = "0.21.0" sea-orm = { version = "0.11.1", features = [ - "sqlx-postgres", - "runtime-tokio-native-tls", - "with-bigdecimal", - "with-time", - "macros", + "sqlx-postgres", + "runtime-tokio-native-tls", + "with-bigdecimal", + "with-time", + "macros", ] } sea-orm-migration = { version = "0.11.1", features = [ - "sqlx-postgres", - "runtime-tokio-native-tls", + "sqlx-postgres", + "runtime-tokio-native-tls", ] } semver = "1.0" serde = { version = "1.0", features = ["derive"] } serde_bytes = "0.11" serde_derive = "1.0" serde_json = "1.0" +sha2 = { version = "0.10.6", default-features = false } +sha256 = "1.1.4" sha3 = "0.10" solana-account-decoder = "=1.14.13" solana-banks-client = "=1.14.13" @@ -139,7 +147,7 @@ solana-sdk = "=1.14.13" solana-transaction-status = "=1.14.13" solana-zk-token-sdk = "=1.14.13" spl-associated-token-account = { version = "=1.1.2", features = [ - "no-entrypoint", + "no-entrypoint", ] } spl-noop = { version = "=0.1.3", features = ["no-entrypoint"] } spl-token = { version = "=3.5.0", features = ["no-entrypoint"] } @@ -150,12 +158,14 @@ strum = "0.25.0" strum_macros = "0.25.2" tempfile = "3.3" tendermint = "0.32.2" +tendermint-rpc = { version = "0.32.0", features = ["http-client", "tokio"] } thiserror = "1.0" time = "0.3" tiny-keccak = "2.0.2" -toml_edit = "0.19.14" tokio = { version = "1", features = ["parking_lot"] } tokio-test = "0.4" +toml_edit = "0.19.14" +tonic = "0.9.2" tracing = { version = "0.1", features = ["release_max_level_debug"] } tracing-error = "0.2" tracing-futures = "0.2" @@ -166,159 +176,146 @@ url = "2.3" walkdir = "2" warp = "0.3" which = "4.3" -sha256 = "1.1.4" -bech32 = "0.9.1" -tonic = "0.9.2" -sha2 = { version = "0.10.6", default-features = false } -ripemd = "0.1.3" -hyper = "0.14" -hyper-tls = "0.5.0" -hex = "0.4.3" -tendermint-rpc = { version = "0.32.0", features = ["http-client", "tokio"] } -hpl-interface = "=0.0.6-rc3" -elliptic-curve = "0.12.3" ## TODO: remove this cosmwasm-schema = "1.2.7" - [workspace.dependencies.ethers] +features = [] git = "https://github.com/hyperlane-xyz/ethers-rs" tag = "2023-06-01" -features = [] [workspace.dependencies.ethers-contract] +features = ["legacy"] git = "https://github.com/hyperlane-xyz/ethers-rs" tag = "2023-06-01" -features = ["legacy"] [workspace.dependencies.ethers-core] +features = [] git = "https://github.com/hyperlane-xyz/ethers-rs" tag = "2023-06-01" -features = [] [workspace.dependencies.ethers-providers] +features = [] git = "https://github.com/hyperlane-xyz/ethers-rs" tag = "2023-06-01" -features = [] [workspace.dependencies.ethers-signers] +features = ["aws"] git = "https://github.com/hyperlane-xyz/ethers-rs" tag = "2023-06-01" -features = ["aws"] [patch.crates-io.curve25519-dalek] -version = "3.2.2" -git = "https://github.com/Eclipse-Laboratories-Inc/curve25519-dalek" branch = "v3.2.2-relax-zeroize" +git = "https://github.com/Eclipse-Laboratories-Inc/curve25519-dalek" +version = "3.2.2" [patch.crates-io.ed25519-dalek] -version = "1.0.1" -git = "https://github.com/Eclipse-Laboratories-Inc/ed25519-dalek" branch = "main" +git = "https://github.com/Eclipse-Laboratories-Inc/ed25519-dalek" +version = "1.0.1" [patch.crates-io.primitive-types] -version = "=0.12.1" -git = "https://github.com/hyperlane-xyz/parity-common.git" branch = "hyperlane" +git = "https://github.com/hyperlane-xyz/parity-common.git" +version = "=0.12.1" [patch.crates-io.rlp] -version = "=0.5.2" -git = "https://github.com/hyperlane-xyz/parity-common.git" branch = "hyperlane" +git = "https://github.com/hyperlane-xyz/parity-common.git" +version = "=0.5.2" [patch.crates-io.solana-account-decoder] -version = "=1.14.13" git = "https://github.com/hyperlane-xyz/solana.git" tag = "hyperlane-1.14.13-2023-07-04" +version = "=1.14.13" [patch.crates-io.solana-banks-client] -version = "=1.14.13" git = "https://github.com/hyperlane-xyz/solana.git" tag = "hyperlane-1.14.13-2023-07-04" +version = "=1.14.13" [patch.crates-io.solana-banks-interface] -version = "=1.14.13" git = "https://github.com/hyperlane-xyz/solana.git" tag = "hyperlane-1.14.13-2023-07-04" +version = "=1.14.13" [patch.crates-io.solana-banks-server] -version = "=1.14.13" git = "https://github.com/hyperlane-xyz/solana.git" tag = "hyperlane-1.14.13-2023-07-04" +version = "=1.14.13" [patch.crates-io.solana-clap-utils] -version = "=1.14.13" git = "https://github.com/hyperlane-xyz/solana.git" tag = "hyperlane-1.14.13-2023-07-04" +version = "=1.14.13" [patch.crates-io.solana-cli-config] -version = "=1.14.13" git = "https://github.com/hyperlane-xyz/solana.git" tag = "hyperlane-1.14.13-2023-07-04" +version = "=1.14.13" [patch.crates-io.solana-client] -version = "=1.14.13" git = "https://github.com/hyperlane-xyz/solana.git" tag = "hyperlane-1.14.13-2023-07-04" +version = "=1.14.13" [patch.crates-io.solana-program] -version = "=1.14.13" git = "https://github.com/hyperlane-xyz/solana.git" tag = "hyperlane-1.14.13-2023-07-04" +version = "=1.14.13" [patch.crates-io.solana-program-test] -version = "=1.14.13" git = "https://github.com/hyperlane-xyz/solana.git" tag = "hyperlane-1.14.13-2023-07-04" +version = "=1.14.13" [patch.crates-io.solana-sdk] -version = "=1.14.13" git = "https://github.com/hyperlane-xyz/solana.git" tag = "hyperlane-1.14.13-2023-07-04" +version = "=1.14.13" [patch.crates-io.solana-transaction-status] -version = "=1.14.13" git = "https://github.com/hyperlane-xyz/solana.git" tag = "hyperlane-1.14.13-2023-07-04" +version = "=1.14.13" [patch.crates-io.solana-zk-token-sdk] -version = "=1.14.13" git = "https://github.com/hyperlane-xyz/solana.git" tag = "hyperlane-1.14.13-2023-07-04" +version = "=1.14.13" [patch.crates-io.spl-associated-token-account] -version = "=1.1.2" -git = "https://github.com/hyperlane-xyz/solana-program-library.git" branch = "hyperlane" +git = "https://github.com/hyperlane-xyz/solana-program-library.git" +version = "=1.1.2" [patch.crates-io.spl-noop] -version = "=0.1.3" -git = "https://github.com/hyperlane-xyz/solana-program-library.git" branch = "hyperlane" +git = "https://github.com/hyperlane-xyz/solana-program-library.git" +version = "=0.1.3" [patch.crates-io.spl-token] -version = "=3.5.0" -git = "https://github.com/hyperlane-xyz/solana-program-library.git" branch = "hyperlane" +git = "https://github.com/hyperlane-xyz/solana-program-library.git" +version = "=3.5.0" [patch.crates-io.spl-token-2022] -version = "=0.5.0" -git = "https://github.com/hyperlane-xyz/solana-program-library.git" branch = "hyperlane" +git = "https://github.com/hyperlane-xyz/solana-program-library.git" +version = "=0.5.0" [patch.crates-io.spl-type-length-value] version = "=0.1.0" - git = "https://github.com/hyperlane-xyz/solana-program-library.git" branch = "hyperlane" [patch.crates-io.tendermint] -version = "=0.32.2" -git = "https://github.com/hyperlane-xyz/tendermint-rs.git" branch = "trevor/0.32.2-fork" +git = "https://github.com/hyperlane-xyz/tendermint-rs.git" +version = "=0.32.2" [patch.crates-io.tendermint-rpc] -version = "=0.32.2" -git = "https://github.com/hyperlane-xyz/tendermint-rs.git" branch = "trevor/0.32.2-fork" +git = "https://github.com/hyperlane-xyz/tendermint-rs.git" +version = "=0.32.2" diff --git a/rust/chains/hyperlane-cosmos/Cargo.toml b/rust/chains/hyperlane-cosmos/Cargo.toml index e3ff363ae9..59bf545d54 100644 --- a/rust/chains/hyperlane-cosmos/Cargo.toml +++ b/rust/chains/hyperlane-cosmos/Cargo.toml @@ -9,26 +9,26 @@ version = { workspace = true } [dependencies] async-trait = { workspace = true } +base64 = { workspace = true } +bech32 = { workspace = true } cosmrs = { workspace = true, features = ["cosmwasm", "tokio", "grpc", "rpc"] } derive-new = { workspace = true } +hex = { workspace = true } +hpl-interface.workspace = true +hyper = { workspace = true } +hyper-tls = { workspace = true } +once_cell = { workspace = true } +ripemd = { workspace = true } serde = { workspace = true } +serde_json = { workspace = true } +sha2 = { workspace = true } +sha256 = { workspace = true } +tendermint = { workspace = true, features = ["rust-crypto", "secp256k1"] } thiserror = { workspace = true } tokio = { workspace = true } -tracing-futures = { workspace = true } +tonic = { workspace = true } tracing = { workspace = true } +tracing-futures = { workspace = true } url = { workspace = true } -bech32 = { workspace = true } -base64 = { workspace = true } -serde_json = { workspace = true } -once_cell = { workspace = true } -tonic = { workspace = true } -sha2 = { workspace = true } -ripemd = { workspace = true } -hyper = { workspace = true } -hyper-tls = { workspace = true } -sha256 = { workspace = true } -hex = { workspace = true } -tendermint = { workspace = true, features = ["rust-crypto", "secp256k1"]} -hpl-interface = { version = "0.0.2" } hyperlane-core = { path = "../../hyperlane-core" } diff --git a/rust/chains/hyperlane-cosmos/src/mailbox.rs b/rust/chains/hyperlane-cosmos/src/mailbox.rs index 6fd36cc655..657cf0a980 100644 --- a/rust/chains/hyperlane-cosmos/src/mailbox.rs +++ b/rust/chains/hyperlane-cosmos/src/mailbox.rs @@ -181,12 +181,8 @@ impl Mailbox for CosmosMailbox { .provider .wasm_send(process_message, tx_gas_limit) .await?; - Ok(TxOutcome { - transaction_id: H256::from_slice(hex::decode(response.txhash)?.as_slice()).into(), - executed: response.code == 0, - gas_used: U256::from(response.gas_used), - gas_price: U256::from(response.gas_wanted), - }) + + Ok(response.try_into()?) } #[instrument(err, ret, skip(self), fields(msg=%message, metadata=%fmt_bytes(metadata)))] diff --git a/rust/chains/hyperlane-cosmos/src/payloads/ism_routes.rs b/rust/chains/hyperlane-cosmos/src/payloads/ism_routes.rs index 1f2321a917..052a1cc48b 100644 --- a/rust/chains/hyperlane-cosmos/src/payloads/ism_routes.rs +++ b/rust/chains/hyperlane-cosmos/src/payloads/ism_routes.rs @@ -39,5 +39,5 @@ pub struct QueryIsmModuleTypeRequest { #[derive(Serialize, Deserialize, Debug)] pub struct QueryIsmModuleTypeResponse { #[serde(rename = "type")] - pub typ: hpl_interface::ism::ISMType, + pub typ: hpl_interface::ism::IsmType, } diff --git a/rust/chains/hyperlane-cosmos/src/types.rs b/rust/chains/hyperlane-cosmos/src/types.rs index d2e7c965ad..1a3f44ad3e 100644 --- a/rust/chains/hyperlane-cosmos/src/types.rs +++ b/rust/chains/hyperlane-cosmos/src/types.rs @@ -1,9 +1,9 @@ use hyperlane_core::ModuleType; -pub struct IsmType(pub hpl_interface::ism::ISMType); +pub struct IsmType(pub hpl_interface::ism::IsmType); -impl From for IsmType { - fn from(value: hpl_interface::ism::ISMType) -> Self { +impl From for IsmType { + fn from(value: hpl_interface::ism::IsmType) -> Self { IsmType(value) } } @@ -11,14 +11,14 @@ impl From for IsmType { impl From for ModuleType { fn from(value: IsmType) -> Self { match value.0 { - hpl_interface::ism::ISMType::Unused => ModuleType::Unused, - hpl_interface::ism::ISMType::Routing => ModuleType::Routing, - hpl_interface::ism::ISMType::Aggregation => ModuleType::Aggregation, - hpl_interface::ism::ISMType::LegacyMultisig => ModuleType::MessageIdMultisig, - hpl_interface::ism::ISMType::MerkleRootMultisig => ModuleType::MerkleRootMultisig, - hpl_interface::ism::ISMType::MessageIdMultisig => ModuleType::MessageIdMultisig, - hpl_interface::ism::ISMType::Null => ModuleType::Null, - hpl_interface::ism::ISMType::CcipRead => ModuleType::CcipRead, + hpl_interface::ism::IsmType::Unused => ModuleType::Unused, + hpl_interface::ism::IsmType::Routing => ModuleType::Routing, + hpl_interface::ism::IsmType::Aggregation => ModuleType::Aggregation, + hpl_interface::ism::IsmType::LegacyMultisig => ModuleType::MessageIdMultisig, + hpl_interface::ism::IsmType::MerkleRootMultisig => ModuleType::MerkleRootMultisig, + hpl_interface::ism::IsmType::MessageIdMultisig => ModuleType::MessageIdMultisig, + hpl_interface::ism::IsmType::Null => ModuleType::Null, + hpl_interface::ism::IsmType::CcipRead => ModuleType::CcipRead, } } } diff --git a/rust/chains/hyperlane-cosmos/src/validator_announce.rs b/rust/chains/hyperlane-cosmos/src/validator_announce.rs index a5d9d2838b..f7024439dc 100644 --- a/rust/chains/hyperlane-cosmos/src/validator_announce.rs +++ b/rust/chains/hyperlane-cosmos/src/validator_announce.rs @@ -104,12 +104,7 @@ impl ValidatorAnnounce for CosmosValidatorAnnounce { .wasm_send(announce_request, tx_gas_limit) .await?; - Ok(TxOutcome { - transaction_id: H256::from_slice(hex::decode(response.txhash)?.as_slice()).into(), - executed: response.code == 0, - gas_used: U256::from(response.gas_used), - gas_price: U256::from(response.gas_wanted), - }) + Ok(response.try_into()?) } async fn announce_tokens_needed(&self, announcement: SignedType) -> Option { diff --git a/rust/chains/hyperlane-ethereum/Cargo.toml b/rust/chains/hyperlane-ethereum/Cargo.toml index a7de33d53a..8d6db17f45 100644 --- a/rust/chains/hyperlane-ethereum/Cargo.toml +++ b/rust/chains/hyperlane-ethereum/Cargo.toml @@ -33,12 +33,6 @@ url.workspace = true hyperlane-core = { path = "../../hyperlane-core" } ethers-prometheus = { path = "../../ethers-prometheus", features = ["serde"] } -# These should only be used if it _must_ be used to interop with the inner library, -# all errors exported from a chain crate should be using thiserror or handrolled to -# make error handling easier. -# eyre = "never" -# anyhow = never - [build-dependencies] abigen = { path = "../../utils/abigen", features = ["ethers"] } hyperlane-core = { path = "../../hyperlane-core", features = ["test-utils"] } diff --git a/rust/chains/hyperlane-fuel/Cargo.toml b/rust/chains/hyperlane-fuel/Cargo.toml index d9b85aab2d..7dabcdd514 100644 --- a/rust/chains/hyperlane-fuel/Cargo.toml +++ b/rust/chains/hyperlane-fuel/Cargo.toml @@ -21,11 +21,5 @@ url.workspace = true hyperlane-core = { path = "../../hyperlane-core" } -# These should only be used if it _must_ be used to interop with the inner library, -# all errors exported from a chain crate should be using thiserror or handrolled to -# make error handling easier. -# eyre = "never" -# anyhow = never - [build-dependencies] abigen = { path = "../../utils/abigen", features = ["fuels"] } diff --git a/rust/hyperlane-base/Cargo.toml b/rust/hyperlane-base/Cargo.toml index b3e5fbc74f..02d870e644 100644 --- a/rust/hyperlane-base/Cargo.toml +++ b/rust/hyperlane-base/Cargo.toml @@ -36,6 +36,7 @@ tracing-error.workspace = true tracing-futures.workspace = true tracing-subscriber = { workspace = true, features = ["json", "ansi"] } tracing.workspace = true +url.workspace = true warp.workspace = true backtrace = { workspace = true, optional = true } diff --git a/rust/hyperlane-base/src/settings/parser/connection_parser.rs b/rust/hyperlane-base/src/settings/parser/connection_parser.rs new file mode 100644 index 0000000000..5a56cb253b --- /dev/null +++ b/rust/hyperlane-base/src/settings/parser/connection_parser.rs @@ -0,0 +1,127 @@ +use eyre::eyre; +use hyperlane_core::config::ConfigErrResultExt; +use hyperlane_core::{config::ConfigParsingError, HyperlaneDomainProtocol}; +use url::Url; + +use crate::settings::envs::*; +use crate::settings::ChainConnectionConf; + +use super::ValueParser; + +pub fn build_ethereum_connection_conf( + rpcs: &Vec, + chain: &ValueParser, + err: &mut ConfigParsingError, + default_rpc_consensus_type: &str, +) -> Option { + let Some(first_url) = rpcs.clone().into_iter().next() else { + return None; + }; + let rpc_consensus_type = chain + .chain(err) + .get_opt_key("rpcConsensusType") + .parse_string() + .unwrap_or(default_rpc_consensus_type); + + match rpc_consensus_type { + "single" => Some(h_eth::ConnectionConf::Http { url: first_url }), + "fallback" => Some(h_eth::ConnectionConf::HttpFallback { urls: rpcs.clone() }), + "quorum" => Some(h_eth::ConnectionConf::HttpQuorum { urls: rpcs.clone() }), + ty => Err(eyre!("unknown rpc consensus type `{ty}`")) + .take_err(err, || &chain.cwp + "rpc_consensus_type"), + } + .map(ChainConnectionConf::Ethereum) +} + +pub fn build_cosmos_connection_conf( + rpcs: &Vec, + chain: &ValueParser, + err: &mut ConfigParsingError, +) -> Option { + let mut local_err = ConfigParsingError::default(); + + let grpc_url = chain + .chain(&mut local_err) + .get_key("grpcUrl") + .parse_string() + .end() + .or_else(|| { + local_err.push( + &chain.cwp + "grpc_url", + eyre!("Missing grpc definitions for chain"), + ); + None + }); + + let chain_id = chain + .chain(&mut local_err) + .get_key("chainId") + .parse_string() + .end() + .or_else(|| { + local_err.push(&chain.cwp + "chain_id", eyre!("Missing chain id for chain")); + None + }); + + let prefix = chain + .chain(err) + .get_key("prefix") + .parse_string() + .end() + .or_else(|| { + local_err.push(&chain.cwp + "prefix", eyre!("Missing prefix for chain")); + None + }); + + let canonical_asset = if let Some(asset) = chain + .chain(err) + .get_opt_key("canonicalAsset") + .parse_string() + .end() + { + Some(asset.to_string()) + } else if let Some(hrp) = prefix { + Some(format!("u{}", hrp)) + } else { + local_err.push( + &chain.cwp + "canonical_asset", + eyre!("Missing canonical asset for chain"), + ); + None + }; + + if !local_err.is_ok() { + err.merge(local_err); + None + } else { + Some(ChainConnectionConf::Cosmos(h_cosmos::ConnectionConf::new( + grpc_url.unwrap().to_string(), + rpcs.first().unwrap().to_string(), + chain_id.unwrap().to_string(), + prefix.unwrap().to_string(), + canonical_asset.unwrap(), + ))) + } +} + +pub fn build_connection_conf( + domain_protocol: HyperlaneDomainProtocol, + rpcs: &Vec, + chain: &ValueParser, + err: &mut ConfigParsingError, + default_rpc_consensus_type: &str, +) -> Option { + match domain_protocol { + HyperlaneDomainProtocol::Ethereum => { + build_ethereum_connection_conf(rpcs, chain, err, default_rpc_consensus_type) + } + HyperlaneDomainProtocol::Fuel => rpcs + .into_iter() + .next() + .map(|url| ChainConnectionConf::Fuel(h_fuel::ConnectionConf { url: url.clone() })), + HyperlaneDomainProtocol::Sealevel => rpcs.iter().next().map(|url| { + ChainConnectionConf::Sealevel(h_sealevel::ConnectionConf { url: url.clone() }) + }), + HyperlaneDomainProtocol::Cosmos => build_cosmos_connection_conf(rpcs, chain, err), + } +} diff --git a/rust/hyperlane-base/src/settings/parser/mod.rs b/rust/hyperlane-base/src/settings/parser/mod.rs index 7edaae6d6a..781a7c7f2d 100644 --- a/rust/hyperlane-base/src/settings/parser/mod.rs +++ b/rust/hyperlane-base/src/settings/parser/mod.rs @@ -21,10 +21,11 @@ use serde_json::Value; pub use self::json_value_parser::ValueParser; pub use super::envs::*; use crate::settings::{ - chains::IndexSettings, trace::TracingConfig, ChainConf, ChainConnectionConf, - CoreContractAddresses, Settings, SignerConf, + chains::IndexSettings, parser::connection_parser::build_connection_conf, trace::TracingConfig, + ChainConf, ChainConnectionConf, CoreContractAddresses, Settings, SignerConf, }; +mod connection_parser; mod json_value_parser; /// The base agent config @@ -224,107 +225,13 @@ fn parse_chain( .end(); cfg_unwrap_all!(&chain.cwp, err: [domain]); - - let connection: Option = match domain.domain_protocol() { - HyperlaneDomainProtocol::Ethereum => { - if rpcs.len() <= 1 { - rpcs.into_iter() - .next() - .map(|url| ChainConnectionConf::Ethereum(h_eth::ConnectionConf::Http { url })) - } else { - let rpc_consensus_type = chain - .chain(&mut err) - .get_opt_key("rpcConsensusType") - .parse_string() - .unwrap_or(default_rpc_consensus_type); - match rpc_consensus_type { - "single" => Some(h_eth::ConnectionConf::Http { - url: rpcs.into_iter().next().unwrap(), - }), - "fallback" => Some(h_eth::ConnectionConf::HttpFallback { urls: rpcs }), - "quorum" => Some(h_eth::ConnectionConf::HttpQuorum { urls: rpcs }), - ty => Err(eyre!("unknown rpc consensus type `{ty}`")) - .take_err(&mut err, || &chain.cwp + "rpc_consensus_type"), - } - .map(ChainConnectionConf::Ethereum) - } - } - HyperlaneDomainProtocol::Fuel => rpcs - .into_iter() - .next() - .map(|url| ChainConnectionConf::Fuel(h_fuel::ConnectionConf { url })), - HyperlaneDomainProtocol::Sealevel => rpcs - .into_iter() - .next() - .map(|url| ChainConnectionConf::Sealevel(h_sealevel::ConnectionConf { url })), - HyperlaneDomainProtocol::Cosmos => { - // ----- only for cosmos ----- - let mut local_err = ConfigParsingError::default(); - - let grpc_url = chain - .chain(&mut local_err) - .get_key("grpcUrl") - .parse_string() - .end() - .or_else(|| { - local_err.push( - &chain.cwp + "grpc_url", - eyre!("Missing grpc definitions for chain"), - ); - None - }); - - let chain_id = chain - .chain(&mut local_err) - .get_key("chainId") - .parse_string() - .end() - .or_else(|| { - local_err.push(&chain.cwp + "chain_id", eyre!("Missing chain id for chain")); - None - }); - - let prefix = chain - .chain(&mut err) - .get_key("prefix") - .parse_string() - .end() - .or_else(|| { - local_err.push(&chain.cwp + "prefix", eyre!("Missing prefix for chain")); - None - }); - - let canonical_asset = if let Some(asset) = chain - .chain(&mut err) - .get_opt_key("canonicalAsset") - .parse_string() - .end() - { - Some(asset.to_string()) - } else if let Some(hrp) = prefix { - Some(format!("u{}", hrp)) - } else { - local_err.push( - &chain.cwp + "canonical_asset", - eyre!("Missing canonical asset for chain"), - ); - None - }; - - if !local_err.is_ok() { - err.merge(local_err); - None - } else { - Some(ChainConnectionConf::Cosmos(h_cosmos::ConnectionConf::new( - grpc_url.unwrap().to_string(), - rpcs.first().unwrap().to_string(), - chain_id.unwrap().to_string(), - prefix.unwrap().to_string(), - canonical_asset.unwrap(), - ))) - } - } - }; + let connection = build_connection_conf( + domain.domain_protocol(), + &rpcs, + &chain, + &mut err, + default_rpc_consensus_type, + ); cfg_unwrap_all!(&chain.cwp, err: [connection, mailbox, interchain_gas_paymaster, validator_announce]); err.into_result(ChainConf { diff --git a/rust/hyperlane-base/src/settings/signers.rs b/rust/hyperlane-base/src/settings/signers.rs index d072d428b6..2979488544 100644 --- a/rust/hyperlane-base/src/settings/signers.rs +++ b/rust/hyperlane-base/src/settings/signers.rs @@ -103,16 +103,15 @@ impl ChainSigner for hyperlane_ethereum::Signers { #[async_trait] impl BuildableWithSignerConf for fuels::prelude::WalletUnlocked { async fn build(conf: &SignerConf) -> Result { - Ok(match conf { - SignerConf::HexKey { key } => { - let key = fuels::signers::fuel_crypto::SecretKey::try_from(key.as_bytes()) - .context("Invalid fuel signer key")?; - fuels::prelude::WalletUnlocked::new_from_private_key(key, None) - } - SignerConf::Aws { .. } => bail!("Aws signer is not supported by fuel"), - SignerConf::CosmosKey { .. } => bail!("Cosmos signer is not supported by fuel"), - SignerConf::Node => bail!("Node signer is not supported by fuel"), - }) + if let SignerConf::HexKey { key } = conf { + let key = fuels::signers::fuel_crypto::SecretKey::try_from(key.as_bytes()) + .context("Invalid fuel signer key")?; + Ok(fuels::prelude::WalletUnlocked::new_from_private_key( + key, None, + )) + } else { + bail!(format!("{conf:?} key is not supported by fuel")); + } } } @@ -125,17 +124,16 @@ impl ChainSigner for fuels::prelude::WalletUnlocked { #[async_trait] impl BuildableWithSignerConf for Keypair { async fn build(conf: &SignerConf) -> Result { - Ok(match conf { - SignerConf::HexKey { key } => { - let secret = SecretKey::from_bytes(key.as_bytes()) - .context("Invalid sealevel ed25519 secret key")?; + if let SignerConf::HexKey { key } = conf { + let secret = SecretKey::from_bytes(key.as_bytes()) + .context("Invalid sealevel ed25519 secret key")?; + Ok( Keypair::from_bytes(&ed25519_dalek::Keypair::from(secret).to_bytes()) - .context("Unable to create Keypair")? - } - SignerConf::Aws { .. } => bail!("Aws signer is not supported by fuel"), - SignerConf::CosmosKey { .. } => bail!("Cosmos signer is not supported by fuel"), - SignerConf::Node => bail!("Node signer is not supported by fuel"), - }) + .context("Unable to create Keypair")?, + ) + } else { + bail!(format!("{conf:?} key is not supported by sealevel")); + } } } @@ -148,14 +146,14 @@ impl ChainSigner for Keypair { #[async_trait] impl BuildableWithSignerConf for hyperlane_cosmos::Signer { async fn build(conf: &SignerConf) -> Result { - Ok(match conf { - SignerConf::HexKey { .. } => bail!("HexKey signer is not supported by cosmos"), - SignerConf::Aws { .. } => bail!("Aws signer is not supported by cosmos"), - SignerConf::CosmosKey { key, prefix } => { - hyperlane_cosmos::Signer::new(key.as_bytes().to_vec(), prefix.clone())? - } - SignerConf::Node => bail!("Node signer is not supported by cosmos"), - }) + if let SignerConf::CosmosKey { key, prefix } = conf { + Ok(hyperlane_cosmos::Signer::new( + key.as_bytes().to_vec(), + prefix.clone(), + )?) + } else { + bail!(format!("{conf:?} key is not supported by cosmos")); + } } } diff --git a/rust/hyperlane-core/src/traits/mod.rs b/rust/hyperlane-core/src/traits/mod.rs index ec2c9e04f4..555082dbc5 100644 --- a/rust/hyperlane-core/src/traits/mod.rs +++ b/rust/hyperlane-core/src/traits/mod.rs @@ -15,6 +15,8 @@ pub use routing_ism::*; pub use signing::*; pub use validator_announce::*; +use crate::{ChainCommunicationError, ChainResult, H256, U256}; + mod aggregation_ism; mod ccip_read_ism; mod cursor; @@ -60,3 +62,18 @@ impl From for TxOutcome { } } } + +impl TryFrom for TxOutcome { + type Error = ChainCommunicationError; + + fn try_from( + response: cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse, + ) -> ChainResult { + Ok(Self { + transaction_id: H256::from_slice(hex::decode(response.txhash)?.as_slice()).into(), + executed: response.code == 0, + gas_used: U256::from(response.gas_used), + gas_price: U256::one(), + }) + } +}