Skip to content

Commit

Permalink
Fix TLS issues (#484)
Browse files Browse the repository at this point in the history
* try creating endpoint manually

* add roots feature to tonic

* tls test

* fix tls bug

* use archway again

* update channel creation logic

* Nits

---------

Co-authored-by: Buckram <[email protected]>
Co-authored-by: Kayanski <[email protected]>
Co-authored-by: Kayanski <[email protected]>
  • Loading branch information
4 people authored Sep 9, 2024
1 parent 3549b9d commit 4efe16a
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 40 deletions.
3 changes: 2 additions & 1 deletion cw-orch-daemon/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ bech32 = { version = "0.11.0", default-features = false, features = ["alloc"] }
hex = { version = "0.4.3" }
ripemd = { version = "0.1.3" }
tokio = { workspace = true, features = ["full"] }
tonic = { workspace = true, features = ["tls", "tls-roots"] }
tonic = { workspace = true, features = ["tls"] }
reqwest = { version = "0.12.5" }
base64 = { version = "0.22.1" }
hkd32 = { version = "0.7.0", features = ["bip39", "mnemonic", "bech32"] }
Expand Down Expand Up @@ -77,6 +77,7 @@ uid = "0.1.7"

# Deserialize network config
toml = "0.8"
http = "1.1.0"

[dev-dependencies]
cw-orch-daemon = { path = "." }
Expand Down
54 changes: 16 additions & 38 deletions cw-orch-daemon/src/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use cosmrs::proto::cosmos::base::tendermint::v1beta1::{
service_client::ServiceClient, GetNodeInfoRequest,
};
use cw_orch_core::{environment::ChainInfoOwned, log::connectivity_target};
use tonic::transport::{Channel, ClientTlsConfig};
use http::Uri;
use tonic::transport::{Channel, ClientTlsConfig, Endpoint};

use super::error::DaemonError;

Expand All @@ -21,55 +22,32 @@ impl GrpcChannel {
for address in grpc.iter() {
log::debug!(target: &connectivity_target(), "Trying to connect to endpoint: {}", address);

// get grpc endpoint
let endpoint = Channel::builder(address.clone().try_into().unwrap());
let uri = Uri::from_maybe_shared(address.clone()).expect("Invalid URI");

// try to connect to grpc endpoint
let maybe_client = ServiceClient::connect(endpoint.clone()).await;
let maybe_channel = Endpoint::from(uri)
.tls_config(ClientTlsConfig::new().with_enabled_roots())
.unwrap()
.connect()
.await;

// connection succeeded
let mut client = if maybe_client.is_ok() {
maybe_client?
} else {
if maybe_channel.is_err() {
log::warn!(
"Cannot connect to gRPC endpoint: {}, {:?}",
address,
maybe_client.unwrap_err()
maybe_channel.unwrap_err()
);

// try HTTPS approach
// https://github.com/hyperium/tonic/issues/363#issuecomment-638545965
if !(address.contains("https") || address.contains("443")) {
continue;
};

log::debug!(target: &connectivity_target(), "Attempting to connect with TLS");

// re attempt to connect
let endpoint = endpoint.clone().tls_config(ClientTlsConfig::new())?;
let maybe_client = ServiceClient::connect(endpoint.clone()).await;

// connection still fails
if maybe_client.is_err() {
log::warn!(
"Cannot connect to gRPC endpoint: {}, {:?}",
address,
maybe_client.unwrap_err()
);
continue;
};

maybe_client?
continue;
};
let channel = maybe_channel.unwrap();

let mut client = ServiceClient::new(channel.clone());

// get client information for verification down below
// Verify that node is the expected network
let node_info = client
.get_node_info(GetNodeInfoRequest {})
.await?
.into_inner();

// local juno does not return a proper ChainId with epoch format
// verify we are connected to the expected network
if node_info.default_node_info.as_ref().unwrap().network != chain_id {
log::error!(
"Network mismatch: connection:{} != config:{}",
Expand All @@ -80,7 +58,7 @@ impl GrpcChannel {
}

// add endpoint to succesful connections
successful_connections.push(endpoint.connect().await?)
successful_connections.push(channel);
}

// we could not get any succesful connections
Expand Down
12 changes: 11 additions & 1 deletion cw-orch-daemon/src/senders/query_only.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl QuerySender for QueryOnlySender {

#[cfg(test)]
mod tests {
use cw_orch_networks::networks::JUNO_1;
use cw_orch_networks::networks::{ARCHWAY_1, JUNO_1, VOTA_ASH};

use super::QueryOnlyDaemon;
use crate::DaemonBuilder;
Expand All @@ -57,4 +57,14 @@ mod tests {
let _query_only_daemon: QueryOnlyDaemon =
DaemonBuilder::new(JUNO_1).build_sender(()).unwrap();
}

#[test]
#[serial_test::serial]
fn tls_grpc() {
let chain = ARCHWAY_1;
// Make sure this test is up to date
assert!(chain.grpc_urls[0].starts_with("https"));
let _query_only_daemon: QueryOnlyDaemon =
DaemonBuilder::new(chain).build_sender(()).unwrap();
}
}
1 change: 1 addition & 0 deletions packages/cw-orch-core/src/contract/interface_traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ pub trait CwOrchMigrate<Chain: TxHandler>: MigratableContract + ContractInstance
impl<T: MigratableContract + ContractInstance<Chain>, Chain: TxHandler> CwOrchMigrate<Chain> for T {}

/// Trait to implement on the contract to enable it to be uploaded
///
/// Should return [`WasmPath`](crate::contract::interface_traits::WasmPath) for `Chain = Daemon`
/// and [`Box<&dyn Contract>`] for `Chain = Mock`
pub trait Uploadable {
Expand Down
1 change: 1 addition & 0 deletions packages/cw-orch-core/src/contract/paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ mod artifacts_dir {

#[macro_export]
/// Creates an [`ArtifactsDir`] from the current workspace by searching the file tree for a directory named `artifacts`.
///
/// It does this by reading the CARGO_MANIFEST_DIR environment variable and going up the file tree until it finds the `artifacts` directory.
macro_rules! from_workspace {
() => {
Expand Down

0 comments on commit 4efe16a

Please sign in to comment.