From 19d6ed33e5f73aef12bb48e1a876e1f7e9813e1a Mon Sep 17 00:00:00 2001 From: Daniel Savu <23065004+daniel-savu@users.noreply.github.com> Date: Thu, 2 Nov 2023 19:16:33 +0000 Subject: [PATCH] refactor: delegate keypair encoding to cosmrs --- rust/Cargo.lock | 2 + rust/chains/hyperlane-cosmos/Cargo.toml | 1 + .../hyperlane-cosmos/src/aggregation_ism.rs | 2 +- rust/chains/hyperlane-cosmos/src/error.rs | 6 + .../src/interchain_security_module.rs | 31 +--- rust/chains/hyperlane-cosmos/src/lib.rs | 1 + .../hyperlane-cosmos/src/libs/address.rs | 53 +++++++ .../hyperlane-cosmos/src/libs/binary.rs | 28 ---- rust/chains/hyperlane-cosmos/src/libs/mod.rs | 5 +- .../hyperlane-cosmos/src/libs/verify.rs | 132 ------------------ rust/chains/hyperlane-cosmos/src/mailbox.rs | 12 +- .../hyperlane-cosmos/src/multisig_ism.rs | 5 +- .../hyperlane-cosmos/src/providers/grpc.rs | 6 +- .../hyperlane-cosmos/src/providers/rpc.rs | 8 +- .../hyperlane-cosmos/src/routing_ism.rs | 2 +- rust/chains/hyperlane-cosmos/src/signers.rs | 17 +-- rust/chains/hyperlane-cosmos/src/types.rs | 24 ++++ .../src/validator_announce.rs | 5 +- rust/utils/run-locally/Cargo.toml | 3 +- rust/utils/run-locally/src/cosmos/crypto.rs | 4 + 20 files changed, 120 insertions(+), 227 deletions(-) create mode 100644 rust/chains/hyperlane-cosmos/src/libs/address.rs delete mode 100644 rust/chains/hyperlane-cosmos/src/libs/binary.rs delete mode 100644 rust/chains/hyperlane-cosmos/src/libs/verify.rs create mode 100644 rust/chains/hyperlane-cosmos/src/types.rs diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 7bd66adcd7..83f826cbed 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -4155,6 +4155,7 @@ dependencies = [ "base64 0.21.4", "bech32 0.9.1", "cosmrs", + "derive-new", "hex 0.4.3", "hpl-interface 0.0.2", "hyper", @@ -6921,6 +6922,7 @@ dependencies = [ "hex 0.4.3", "hpl-interface 0.0.6-rc5", "hyperlane-core", + "hyperlane-cosmos", "k256 0.13.1", "macro_rules_attribute", "maplit", diff --git a/rust/chains/hyperlane-cosmos/Cargo.toml b/rust/chains/hyperlane-cosmos/Cargo.toml index 0da9b9bc93..1d9058ce50 100644 --- a/rust/chains/hyperlane-cosmos/Cargo.toml +++ b/rust/chains/hyperlane-cosmos/Cargo.toml @@ -10,6 +10,7 @@ version = { workspace = true } [dependencies] async-trait = { workspace = true } cosmrs = { workspace = true, features = ["cosmwasm", "tokio", "grpc", "rpc"] } +derive-new = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } tokio = { workspace = true } diff --git a/rust/chains/hyperlane-cosmos/src/aggregation_ism.rs b/rust/chains/hyperlane-cosmos/src/aggregation_ism.rs index 6b60be5bcc..6ac1dd5240 100644 --- a/rust/chains/hyperlane-cosmos/src/aggregation_ism.rs +++ b/rust/chains/hyperlane-cosmos/src/aggregation_ism.rs @@ -1,7 +1,7 @@ use crate::{ + address::bech32_decode, grpc::{WasmGrpcProvider, WasmProvider}, payloads::aggregate_ism::{ModulesAndThresholdRequest, ModulesAndThresholdResponse}, - verify::bech32_decode, ConnectionConf, CosmosProvider, Signer, }; use async_trait::async_trait; diff --git a/rust/chains/hyperlane-cosmos/src/error.rs b/rust/chains/hyperlane-cosmos/src/error.rs index cb101f009e..7ed0d141ce 100644 --- a/rust/chains/hyperlane-cosmos/src/error.rs +++ b/rust/chains/hyperlane-cosmos/src/error.rs @@ -12,6 +12,12 @@ pub enum HyperlaneCosmosError { /// gRPC error #[error("{0}")] GrpcError(#[from] tonic::Status), + /// Cosmos error + #[error("{0}")] + CosmosError(#[from] cosmrs::Error), + /// Cosmos error report + #[error("{0}")] + CosmosErrorReport(#[from] cosmrs::ErrorReport), } impl From for ChainCommunicationError { diff --git a/rust/chains/hyperlane-cosmos/src/interchain_security_module.rs b/rust/chains/hyperlane-cosmos/src/interchain_security_module.rs index 1e27fca038..5b122e2c02 100644 --- a/rust/chains/hyperlane-cosmos/src/interchain_security_module.rs +++ b/rust/chains/hyperlane-cosmos/src/interchain_security_module.rs @@ -8,10 +8,9 @@ use crate::{ grpc::{WasmGrpcProvider, WasmProvider}, payloads::{ general::EmptyStruct, - ism_routes::{ - QueryIsmGeneralRequest, QueryIsmModuleTypeRequest, QueryIsmModuleTypeResponse, - }, + ism_routes::{QueryIsmGeneralRequest, QueryIsmModuleTypeRequest}, }, + types::IsmType, ConnectionConf, CosmosProvider, Signer, }; @@ -57,19 +56,6 @@ impl HyperlaneChain for CosmosInterchainSecurityModule { } } -fn ism_type_to_module_type(ism_type: hpl_interface::ism::ISMType) -> ModuleType { - match ism_type { - 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, - } -} - #[async_trait] impl InterchainSecurityModule for CosmosInterchainSecurityModule { /// Returns the module type of the ISM compliant with the corresponding @@ -84,16 +70,9 @@ impl InterchainSecurityModule for CosmosInterchainSecurityModule { .wasm_query(QueryIsmGeneralRequest { ism: query }, None) .await?; - // Handle both the ISMType response and the ModuleTypeResponse response. - let ismtype_response = serde_json::from_slice::(&data); - let moduletye_response = - serde_json::from_slice::(&data); - - Ok(match (ismtype_response, moduletye_response) { - (Ok(v), _) => ism_type_to_module_type(v.typ), - (_, Ok(v)) => ism_type_to_module_type(v.typ), - _ => ModuleType::Null, - }) + let module_type_response = + serde_json::from_slice::(&data)?; + Ok(IsmType(module_type_response.typ).into()) } /// Dry runs the `verify()` ISM call and returns `Some(gas_estimate)` if the call diff --git a/rust/chains/hyperlane-cosmos/src/lib.rs b/rust/chains/hyperlane-cosmos/src/lib.rs index a68c97aee8..82a4a0ece1 100644 --- a/rust/chains/hyperlane-cosmos/src/lib.rs +++ b/rust/chains/hyperlane-cosmos/src/lib.rs @@ -18,6 +18,7 @@ mod providers; mod routing_ism; mod signers; mod trait_builder; +mod types; mod utils; mod validator_announce; diff --git a/rust/chains/hyperlane-cosmos/src/libs/address.rs b/rust/chains/hyperlane-cosmos/src/libs/address.rs new file mode 100644 index 0000000000..eb39a9d550 --- /dev/null +++ b/rust/chains/hyperlane-cosmos/src/libs/address.rs @@ -0,0 +1,53 @@ +use std::str::FromStr; + +use cosmrs::{crypto::secp256k1::SigningKey, AccountId}; +use derive_new::new; +use hyperlane_core::{ChainResult, H256}; + +/// decode bech32 address to H256 +pub fn bech32_decode(addr: String) -> ChainResult { + let account_id = AccountId::from_str(&addr)?; + + // although `from_slice` can panic if the slice is not 32 bytes long, + // we know that we're passing in a value that is 32 bytes long because it was decoded from + // bech32 + Ok(H256::from_slice(&account_id.to_bytes())) +} + +/// Wrapper around the cosmrs AccountId type that abstracts keypair conversions and +/// bech32 encoding +#[derive(new)] +pub struct CosmosAddress { + account_id: AccountId, +} + +impl CosmosAddress { + /// Returns a Bitcoin style address: RIPEMD160(SHA256(pubkey)) + /// Source: https://github.com/cosmos/cosmos-sdk/blob/177e7f45959215b0b4e85babb7c8264eaceae052/crypto/keys/secp256k1/secp256k1.go#L154 + pub fn from_pubkey(pub_key: &[u8], prefix: &str) -> ChainResult { + let account_id = AccountId::new(prefix, pub_key)?; + Ok(Self { account_id }) + } + + /// Creates a wrapper arround a cosmrs AccountId from a private key byte array + pub fn from_privkey(priv_key: &[u8], prefix: &str) -> ChainResult { + let pubkey = SigningKey::from_slice(priv_key)?.public_key().to_bytes(); + Self::from_pubkey(&pubkey, prefix) + } + + /// Creates a wrapper arround a cosmrs AccountId from a H256 digest + pub fn from_h256(digest: H256, prefix: &str) -> ChainResult { + let bytes = digest.as_bytes(); + CosmosAddress::from_pubkey(bytes, prefix) + } + + /// String representation of a cosmos AccountId + pub fn address(&self) -> String { + self.account_id.to_string() + } +} + +/// encode H256 to bech32 address +pub fn pub_to_addr(pub_key: Vec, prefix: &str) -> ChainResult { + Ok(CosmosAddress::from_pubkey(&pub_key, prefix)?.address()) +} diff --git a/rust/chains/hyperlane-cosmos/src/libs/binary.rs b/rust/chains/hyperlane-cosmos/src/libs/binary.rs deleted file mode 100644 index a75ffaa342..0000000000 --- a/rust/chains/hyperlane-cosmos/src/libs/binary.rs +++ /dev/null @@ -1,28 +0,0 @@ -use hyperlane_core::{H160, H256, H512}; -use std::cmp; - -/// Convert H256 to H512 -pub fn h256_to_h512(v: H256) -> H512 { - let mut result: [u8; 64] = [0; 64]; - let vec = v.0.as_slice(); - let start_point = cmp::max(0, 32 - vec.len()); - result[start_point..32].copy_from_slice(vec); - - H512::from_slice(&result) -} - -/// Convert H256 to H160 -pub fn h256_to_h160(v: H256) -> H160 { - let mut result = [0u8; 20]; - - result.copy_from_slice(&v.0[12..]); - H160::from_slice(&result) -} - -/// Convert H160 to H256 -pub fn h160_to_h256(v: H160) -> H256 { - let mut result = [0u8; 32]; - result[12..].copy_from_slice(v.as_bytes()); - - H256::from_slice(&result) -} diff --git a/rust/chains/hyperlane-cosmos/src/libs/mod.rs b/rust/chains/hyperlane-cosmos/src/libs/mod.rs index 6c33ef5122..d89e6cd7db 100644 --- a/rust/chains/hyperlane-cosmos/src/libs/mod.rs +++ b/rust/chains/hyperlane-cosmos/src/libs/mod.rs @@ -1,5 +1,2 @@ /// This module contains all the verification variables the libraries used by the Hyperlane Cosmos chain. -pub mod verify; - -/// This module contains all the Binary variables used by the Hyperlane Cosmos chain. -pub mod binary; +pub mod address; diff --git a/rust/chains/hyperlane-cosmos/src/libs/verify.rs b/rust/chains/hyperlane-cosmos/src/libs/verify.rs deleted file mode 100644 index 8fe0fba28a..0000000000 --- a/rust/chains/hyperlane-cosmos/src/libs/verify.rs +++ /dev/null @@ -1,132 +0,0 @@ -use std::cmp; - -use bech32::{FromBase32, ToBase32}; -use cosmrs::crypto::secp256k1::SigningKey; -use hyperlane_core::{ChainCommunicationError, ChainResult, H160, H256}; -use ripemd::Ripemd160; -use sha2::{Digest, Sha256}; - -use crate::HyperlaneCosmosError; - -/// decode bech32 address to H256 -pub fn bech32_decode(addr: String) -> ChainResult { - let (_hrp, data, _variant) = - bech32::decode(addr.as_str()).map_err(Into::::into)?; - - let value = Vec::::from_base32(&data).map_err(Into::::into)?; - let mut result: [u8; 32] = [0; 32]; - - let start_point = cmp::max(0, 32 - value.len()); - result[start_point..32].copy_from_slice(value.as_slice()); - - Ok(H256::from(result)) -} - -/// encode H256 to bech32 address -pub fn digest_to_addr(digest: H256, prefix: &str) -> ChainResult { - let addr = bech32::encode( - prefix, - digest.as_bytes().to_base32(), - bech32::Variant::Bech32, - ) - .map_err(|_| ChainCommunicationError::InvalidRequest { - msg: "invalid address".to_string(), - })?; - - Ok(addr) -} - -/// encode H256 to bech32 address -pub fn sha256_digest(bz: impl AsRef<[u8]>) -> ChainResult<[u8; 32]> { - let mut hasher = Sha256::new(); - - hasher.update(bz); - - hasher - .finalize() - .as_slice() - .try_into() - .map_err(|_| ChainCommunicationError::ParseError { - msg: "sha256 digest".to_string(), - }) -} - -/// encode H256 to bech32 address -pub fn ripemd160_digest(bz: impl AsRef<[u8]>) -> ChainResult<[u8; 20]> { - let mut hasher = Ripemd160::new(); - - hasher.update(bz); - - hasher - .finalize() - .as_slice() - .try_into() - .map_err(|_| ChainCommunicationError::ParseError { - msg: "ripemd160".to_string(), - }) -} - -/// encode H256 to bech32 address -pub fn pub_to_addr(pub_key: Vec, prefix: &str) -> ChainResult { - let sha_hash = sha256_digest(pub_key)?; - let rip_hash = ripemd160_digest(sha_hash)?; - - let addr = - bech32::encode(prefix, rip_hash.to_base32(), bech32::Variant::Bech32).map_err(|_| { - ChainCommunicationError::ParseError { - msg: "bech32".to_string(), - } - })?; - - Ok(addr) -} - -/// encode H256 to bech32 address -pub fn priv_to_binary_addr(priv_key: Vec) -> ChainResult { - let sha_hash = sha256_digest( - SigningKey::from_slice(priv_key.as_slice())? - .public_key() - .to_bytes(), - )?; - let rip_hash = ripemd160_digest(sha_hash)?; - - Ok(H160::from_slice(rip_hash.as_slice())) -} - -/// encode H256 to bech32 address -pub fn priv_to_addr_string(prefix: String, priv_key: Vec) -> ChainResult { - let sha_hash = sha256_digest( - SigningKey::from_slice(priv_key.as_slice())? - .public_key() - .to_bytes(), - )?; - let rip_hash = ripemd160_digest(sha_hash)?; - - let addr = - bech32::encode(&prefix, rip_hash.to_base32(), bech32::Variant::Bech32).map_err(|_| { - ChainCommunicationError::ParseError { - msg: "bech32".to_string(), - } - })?; - - Ok(addr) -} - -/// encode H256 to bech32 address -pub fn pub_to_binary_addr(pub_key: Vec) -> ChainResult { - let sha_hash = match (pub_key.len() == 33) && (pub_key[0] == 0x02 || pub_key[0] == 0x03) { - true => sha256_digest(pub_key)?, - false => { - let comp_pub_key = vec![0x03]; - let comp_pub_key = comp_pub_key - .into_iter() - .chain(pub_key[1..33].iter().cloned()) - .collect::>(); - - sha256_digest(comp_pub_key)? - } - }; - let rip_hash = ripemd160_digest(sha_hash)?; - - Ok(H160::from_slice(rip_hash.as_slice())) -} diff --git a/rust/chains/hyperlane-cosmos/src/mailbox.rs b/rust/chains/hyperlane-cosmos/src/mailbox.rs index d14e28f32c..1279c8e160 100644 --- a/rust/chains/hyperlane-cosmos/src/mailbox.rs +++ b/rust/chains/hyperlane-cosmos/src/mailbox.rs @@ -4,6 +4,7 @@ use std::io::Cursor; use std::num::NonZeroU64; use std::ops::RangeInclusive; +use crate::address::CosmosAddress; use crate::grpc::{WasmGrpcProvider, WasmProvider}; use crate::payloads::mailbox::{ GeneralMailboxQuery, ProcessMessageRequest, ProcessMessageRequestInner, @@ -11,14 +12,13 @@ use crate::payloads::mailbox::{ use crate::payloads::{general, mailbox}; use crate::rpc::{CosmosWasmIndexer, WasmIndexer}; use crate::CosmosProvider; -use crate::{signers::Signer, utils::get_block_height_for_lag, verify, ConnectionConf}; +use crate::{address, signers::Signer, utils::get_block_height_for_lag, ConnectionConf}; use async_trait::async_trait; use cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse; use cosmrs::proto::cosmos::tx::v1beta1::SimulateResponse; use cosmrs::tendermint::abci::EventAttribute; -use crate::binary::h256_to_h512; use hyperlane_core::{ utils::fmt_bytes, ChainResult, HyperlaneChain, HyperlaneContract, HyperlaneDomain, HyperlaneMessage, HyperlaneProvider, Indexer, LogMeta, Mailbox, TxCostEstimate, TxOutcome, @@ -134,7 +134,7 @@ impl Mailbox for CosmosMailbox { #[instrument(err, ret, skip(self))] async fn recipient_ism(&self, recipient: H256) -> ChainResult { - let address = verify::digest_to_addr(recipient, &self.signer.prefix)?; + let address = CosmosAddress::from_h256(self.address, &self.signer.prefix)?.address(); let payload = mailbox::RecipientIsmRequest { recipient_ism: mailbox::RecipientIsmRequestInner { @@ -149,7 +149,7 @@ impl Mailbox for CosmosMailbox { let response: mailbox::RecipientIsmResponse = serde_json::from_slice(&data)?; // convert Hex to H256 - let ism = verify::bech32_decode(response.ism)?; + let ism = address::bech32_decode(response.ism)?; Ok(ism) } @@ -172,9 +172,7 @@ impl Mailbox for CosmosMailbox { .wasm_send(process_message, tx_gas_limit) .await?; Ok(TxOutcome { - transaction_id: h256_to_h512(H256::from_slice( - hex::decode(response.txhash)?.as_slice(), - )), + 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), diff --git a/rust/chains/hyperlane-cosmos/src/multisig_ism.rs b/rust/chains/hyperlane-cosmos/src/multisig_ism.rs index 83d6f6646d..d946b1dd40 100644 --- a/rust/chains/hyperlane-cosmos/src/multisig_ism.rs +++ b/rust/chains/hyperlane-cosmos/src/multisig_ism.rs @@ -1,7 +1,6 @@ use std::str::FromStr; use crate::{ - binary::h160_to_h256, grpc::{WasmGrpcProvider, WasmProvider}, payloads::ism_routes::QueryIsmGeneralRequest, signers::Signer, @@ -10,7 +9,7 @@ use crate::{ use async_trait::async_trait; use hyperlane_core::{ ChainResult, ContractLocator, HyperlaneChain, HyperlaneContract, HyperlaneDomain, - HyperlaneMessage, HyperlaneProvider, MultisigIsm, RawHyperlaneMessage, H160, H256, + HyperlaneMessage, HyperlaneProvider, MultisigIsm, RawHyperlaneMessage, H256, }; use crate::payloads::multisig_ism::{self, VerifyInfoRequest, VerifyInfoRequestInner}; @@ -78,7 +77,7 @@ impl MultisigIsm for CosmosMultisigIsm { let validators: ChainResult> = response .validators .iter() - .map(|v| H160::from_str(v).map(h160_to_h256).map_err(Into::into)) + .map(|v| H256::from_str(v).map_err(Into::into)) .collect(); Ok((validators?, response.threshold)) diff --git a/rust/chains/hyperlane-cosmos/src/providers/grpc.rs b/rust/chains/hyperlane-cosmos/src/providers/grpc.rs index 021033e0b2..a39db5a8b0 100644 --- a/rust/chains/hyperlane-cosmos/src/providers/grpc.rs +++ b/rust/chains/hyperlane-cosmos/src/providers/grpc.rs @@ -24,8 +24,9 @@ use hyperlane_core::{ }; use serde::Serialize; +use crate::address::CosmosAddress; +use crate::HyperlaneCosmosError; use crate::{signers::Signer, ConnectionConf}; -use crate::{verify, HyperlaneCosmosError}; const DEFAULT_GAS_PRICE: f32 = 0.05; const DEFAULT_GAS_ADJUSTMENT: f32 = 1.25; @@ -106,7 +107,8 @@ impl WasmGrpcProvider { } fn get_contract_addr(&self) -> ChainResult { - verify::digest_to_addr(self.address, self.signer.prefix.as_str()) + let cosmos_address = CosmosAddress::from_h256(self.address, &self.conf.get_prefix())?; + Ok(cosmos_address.address()) } } diff --git a/rust/chains/hyperlane-cosmos/src/providers/rpc.rs b/rust/chains/hyperlane-cosmos/src/providers/rpc.rs index deb266c29a..3cbcc5e05e 100644 --- a/rust/chains/hyperlane-cosmos/src/providers/rpc.rs +++ b/rust/chains/hyperlane-cosmos/src/providers/rpc.rs @@ -1,6 +1,5 @@ use std::ops::RangeInclusive; -use crate::binary::h256_to_h512; use async_trait::async_trait; use cosmrs::rpc::client::{Client, HttpClient}; use cosmrs::rpc::endpoint::tx; @@ -12,7 +11,7 @@ use hyperlane_core::{ }; use tracing::debug; -use crate::verify::{self, bech32_decode}; +use crate::address::{bech32_decode, CosmosAddress}; use crate::ConnectionConf; const PAGINATION_LIMIT: u8 = 100; @@ -78,7 +77,8 @@ impl CosmosWasmIndexer { /// get contract address pub fn get_contract_addr(&self) -> ChainResult { - verify::digest_to_addr(self.address, self.conf.get_prefix().as_str()) + let cosmos_address = CosmosAddress::from_h256(self.address, &self.conf.get_prefix())?; + Ok(cosmos_address.address()) } } @@ -160,7 +160,7 @@ impl WasmIndexer for CosmosWasmIndexer { block_number: tx.height.value(), // FIXME: block_hash is not available in tx_search block_hash: H256::zero(), - transaction_id: h256_to_h512(H256::from_slice(tx.hash.as_bytes())), + transaction_id: H256::from_slice(tx.hash.as_bytes()).into(), transaction_index: tx.index as u64, log_index: U256::from(log_idx), }; diff --git a/rust/chains/hyperlane-cosmos/src/routing_ism.rs b/rust/chains/hyperlane-cosmos/src/routing_ism.rs index 7f96175664..bb8c58ea00 100644 --- a/rust/chains/hyperlane-cosmos/src/routing_ism.rs +++ b/rust/chains/hyperlane-cosmos/src/routing_ism.rs @@ -6,12 +6,12 @@ use hyperlane_core::{ }; use crate::{ + address::bech32_decode, grpc::{WasmGrpcProvider, WasmProvider}, payloads::ism_routes::{ IsmRouteRequest, IsmRouteRequestInner, IsmRouteRespnose, QueryRoutingIsmGeneralRequest, }, signers::Signer, - verify::bech32_decode, ConnectionConf, CosmosProvider, }; diff --git a/rust/chains/hyperlane-cosmos/src/signers.rs b/rust/chains/hyperlane-cosmos/src/signers.rs index e07de304e1..0194bb5452 100644 --- a/rust/chains/hyperlane-cosmos/src/signers.rs +++ b/rust/chains/hyperlane-cosmos/src/signers.rs @@ -1,7 +1,7 @@ use cosmrs::crypto::{secp256k1::SigningKey, PublicKey}; use hyperlane_core::ChainResult; -use crate::verify; +use crate::address::CosmosAddress; #[derive(Clone, Debug)] /// Signer for cosmos chain @@ -23,10 +23,8 @@ impl Signer { /// * `private_key` - private key for signer /// * `prefix` - prefix for signer address pub fn new(private_key: Vec, prefix: String) -> ChainResult { - let address = Self::address(&private_key, &prefix)?; - + let address = CosmosAddress::from_privkey(&private_key, &prefix)?.address(); let signing_key = Self::build_signing_key(&private_key)?; - SigningKey::from_slice(&private_key)?; let public_key = signing_key.public_key(); Ok(Self { public_key, @@ -36,17 +34,6 @@ impl Signer { }) } - /// get bech32 address - fn address(private_key: &Vec, prefix: &str) -> ChainResult { - let address = verify::pub_to_addr( - SigningKey::from_slice(private_key.as_slice())? - .public_key() - .to_bytes(), - prefix, - )?; - Ok(address) - } - /// Build a SigningKey from a private key. This cannot be /// precompiled and stored in `Signer`, because `SigningKey` is not `Sync`. pub fn signing_key(&self) -> ChainResult { diff --git a/rust/chains/hyperlane-cosmos/src/types.rs b/rust/chains/hyperlane-cosmos/src/types.rs new file mode 100644 index 0000000000..d2e7c965ad --- /dev/null +++ b/rust/chains/hyperlane-cosmos/src/types.rs @@ -0,0 +1,24 @@ +use hyperlane_core::ModuleType; + +pub struct IsmType(pub hpl_interface::ism::ISMType); + +impl From for IsmType { + fn from(value: hpl_interface::ism::ISMType) -> Self { + IsmType(value) + } +} + +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, + } + } +} diff --git a/rust/chains/hyperlane-cosmos/src/validator_announce.rs b/rust/chains/hyperlane-cosmos/src/validator_announce.rs index dc59c8c0bb..59a98a7462 100644 --- a/rust/chains/hyperlane-cosmos/src/validator_announce.rs +++ b/rust/chains/hyperlane-cosmos/src/validator_announce.rs @@ -4,11 +4,10 @@ use cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse; use hyperlane_core::{ Announcement, ChainCommunicationError, ChainResult, ContractLocator, HyperlaneChain, HyperlaneContract, HyperlaneDomain, HyperlaneProvider, SignedType, TxOutcome, - ValidatorAnnounce, H256, U256, + ValidatorAnnounce, H160, H256, U256, }; use crate::{ - binary::h256_to_h160, grpc::{WasmGrpcProvider, WasmProvider}, payloads::validator_announce::{ self, AnnouncementRequest, AnnouncementRequestInner, GetAnnounceStorageLocationsRequest, @@ -67,7 +66,7 @@ impl ValidatorAnnounce for CosmosValidatorAnnounce { ) -> ChainResult>> { let vss = validators .iter() - .map(|v| h256_to_h160(*v)) + .map(|v| H160::from(*v)) .map(|v| hex::encode(v.as_bytes())) .collect::>(); diff --git a/rust/utils/run-locally/Cargo.toml b/rust/utils/run-locally/Cargo.toml index 04b272658b..be20928df6 100644 --- a/rust/utils/run-locally/Cargo.toml +++ b/rust/utils/run-locally/Cargo.toml @@ -10,6 +10,8 @@ publish.workspace = true version.workspace = true [dependencies] +hyperlane-core = { path = "../../hyperlane-core" } +hyperlane-cosmos = { path = "../../chains/hyperlane-cosmos" } toml_edit.workspace = true k256.workspace = true ripemd.workspace = true @@ -26,6 +28,5 @@ ureq = { workspace = true, default-features = false } which.workspace = true macro_rules_attribute.workspace = true regex.workspace = true -hyperlane-core = { path = "../../hyperlane-core" } hpl-interface.workspace = true cosmwasm-schema.workspace = true diff --git a/rust/utils/run-locally/src/cosmos/crypto.rs b/rust/utils/run-locally/src/cosmos/crypto.rs index b583ee3b89..e4520cbcbf 100644 --- a/rust/utils/run-locally/src/cosmos/crypto.rs +++ b/rust/utils/run-locally/src/cosmos/crypto.rs @@ -1,3 +1,7 @@ +// TODO: this file can be removed if `CosmosAddress` can be imported from `hyperlane-cosmos`. +// However, adding a hyperlane-cosmos dep creates a dep cycle. +// Look into how this can be fixed. + use k256::ecdsa::{SigningKey, VerifyingKey}; use ripemd::Ripemd160; use sha2::{Digest, Sha256};