Skip to content

Commit 5aed75a

Browse files
feat(sdk): fix client tls connections (#2223)
Co-authored-by: Lukasz Klimek <[email protected]>
1 parent 5e996ed commit 5aed75a

File tree

7 files changed

+111
-45
lines changed

7 files changed

+111
-45
lines changed

Cargo.lock

Lines changed: 9 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/rs-dapi-client/Cargo.toml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,14 @@ dump = ["mocks"]
1919
offline-testing = []
2020

2121
[dependencies]
22-
backon = "0.5"
23-
dapi-grpc = { path = "../dapi-grpc" }
22+
backon = { version = "1.2", default-features = false, features = [
23+
"tokio-sleep",
24+
] }
25+
dapi-grpc = { path = "../dapi-grpc", features = [
26+
"core",
27+
"platform",
28+
"client",
29+
], default-features = false }
2430
futures = "0.3.28"
2531
http-serde = { version = "2.1", optional = true }
2632
rand = { version = "0.8.5", features = ["small_rng"] }

packages/rs-dapi-client/src/connection_pool.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,19 +67,21 @@ impl ConnectionPool {
6767
/// * `prefix` - Prefix for the item in the pool. Used to distinguish between Core and Platform clients.
6868
/// * `uri` - URI of the node.
6969
/// * `settings` - Applied request settings.
70-
pub fn get_or_create(
70+
pub fn get_or_create<E>(
7171
&self,
7272
prefix: PoolPrefix,
7373
uri: &Uri,
7474
settings: Option<&AppliedRequestSettings>,
75-
create: impl FnOnce() -> PoolItem,
76-
) -> PoolItem {
75+
create: impl FnOnce() -> Result<PoolItem, E>,
76+
) -> Result<PoolItem, E> {
7777
if let Some(cli) = self.get(prefix, uri, settings) {
78-
return cli;
78+
return Ok(cli);
7979
}
8080

8181
let cli = create();
82-
self.put(uri, settings, cli.clone());
82+
if let Ok(cli) = &cli {
83+
self.put(uri, settings, cli.clone());
84+
}
8385
cli
8486
}
8587

packages/rs-dapi-client/src/dapi_client.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,13 @@ impl DapiRequestExecutor for DapiClient {
199199
address.uri().clone(),
200200
&applied_settings,
201201
&pool,
202-
);
202+
)
203+
.map_err(|e| {
204+
DapiClientError::<<R::Client as TransportClient>::Error>::Transport(
205+
e,
206+
address.clone(),
207+
)
208+
})?;
203209

204210
let response = transport_request
205211
.execute_transport(&mut transport_client, &applied_settings)
@@ -250,7 +256,7 @@ impl DapiRequestExecutor for DapiClient {
250256
// Start the routine with retry policy applied:
251257
// We allow let_and_return because `result` is used later if dump feature is enabled
252258
let result = routine
253-
.retry(&retry_settings)
259+
.retry(retry_settings)
254260
.notify(|error, duration| {
255261
tracing::warn!(
256262
?error,

packages/rs-dapi-client/src/transport.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,12 @@ pub trait TransportClient: Send + Sized {
5151
type Error: CanRetry + Send + Debug + Mockable;
5252

5353
/// Build client using node's url.
54-
fn with_uri(uri: Uri, pool: &ConnectionPool) -> Self;
54+
fn with_uri(uri: Uri, pool: &ConnectionPool) -> Result<Self, Self::Error>;
5555

5656
/// Build client using node's url and [AppliedRequestSettings].
5757
fn with_uri_and_settings(
5858
uri: Uri,
5959
settings: &AppliedRequestSettings,
6060
pool: &ConnectionPool,
61-
) -> Self;
61+
) -> Result<Self, Self::Error>;
6262
}

packages/rs-dapi-client/src/transport/grpc.rs

Lines changed: 66 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::{request_settings::AppliedRequestSettings, RequestSettings};
88
use dapi_grpc::core::v0::core_client::CoreClient;
99
use dapi_grpc::core::v0::{self as core_proto};
1010
use dapi_grpc::platform::v0::{self as platform_proto, platform_client::PlatformClient};
11-
use dapi_grpc::tonic::transport::Uri;
11+
use dapi_grpc::tonic::transport::{ClientTlsConfig, Uri};
1212
use dapi_grpc::tonic::Streaming;
1313
use dapi_grpc::tonic::{transport::Channel, IntoRequest};
1414
use futures::{future::BoxFuture, FutureExt, TryFutureExt};
@@ -18,59 +18,101 @@ pub type PlatformGrpcClient = PlatformClient<Channel>;
1818
/// Core Client using gRPC transport.
1919
pub type CoreGrpcClient = CoreClient<Channel>;
2020

21-
fn create_channel(uri: Uri, settings: Option<&AppliedRequestSettings>) -> Channel {
22-
let mut builder = Channel::builder(uri);
21+
fn create_channel(
22+
uri: Uri,
23+
settings: Option<&AppliedRequestSettings>,
24+
) -> Result<Channel, dapi_grpc::tonic::transport::Error> {
25+
let mut builder = Channel::builder(uri).tls_config(
26+
ClientTlsConfig::new()
27+
.with_native_roots()
28+
.with_webpki_roots()
29+
.assume_http2(true),
30+
)?;
2331

2432
if let Some(settings) = settings {
2533
if let Some(timeout) = settings.connect_timeout {
2634
builder = builder.connect_timeout(timeout);
2735
}
2836
}
2937

30-
builder.connect_lazy()
38+
Ok(builder.connect_lazy())
3139
}
3240

3341
impl TransportClient for PlatformGrpcClient {
3442
type Error = dapi_grpc::tonic::Status;
3543

36-
fn with_uri(uri: Uri, pool: &ConnectionPool) -> Self {
37-
pool.get_or_create(PoolPrefix::Platform, &uri, None, || {
38-
Self::new(create_channel(uri.clone(), None)).into()
39-
})
40-
.into()
44+
fn with_uri(uri: Uri, pool: &ConnectionPool) -> Result<Self, Self::Error> {
45+
Ok(pool
46+
.get_or_create(PoolPrefix::Platform, &uri, None, || {
47+
match create_channel(uri.clone(), None) {
48+
Ok(channel) => Ok(Self::new(channel).into()),
49+
Err(e) => Err(dapi_grpc::tonic::Status::failed_precondition(format!(
50+
"Channel creation failed: {}",
51+
e
52+
))),
53+
}
54+
})?
55+
.into())
4156
}
4257

4358
fn with_uri_and_settings(
4459
uri: Uri,
4560
settings: &AppliedRequestSettings,
4661
pool: &ConnectionPool,
47-
) -> Self {
48-
pool.get_or_create(PoolPrefix::Platform, &uri, Some(settings), || {
49-
Self::new(create_channel(uri.clone(), Some(settings))).into()
50-
})
51-
.into()
62+
) -> Result<Self, Self::Error> {
63+
Ok(pool
64+
.get_or_create(
65+
PoolPrefix::Platform,
66+
&uri,
67+
Some(settings),
68+
|| match create_channel(uri.clone(), Some(settings)) {
69+
Ok(channel) => Ok(Self::new(channel).into()),
70+
Err(e) => Err(dapi_grpc::tonic::Status::failed_precondition(format!(
71+
"Channel creation failed: {}",
72+
e
73+
))),
74+
},
75+
)?
76+
.into())
5277
}
5378
}
5479

5580
impl TransportClient for CoreGrpcClient {
5681
type Error = dapi_grpc::tonic::Status;
5782

58-
fn with_uri(uri: Uri, pool: &ConnectionPool) -> Self {
59-
pool.get_or_create(PoolPrefix::Core, &uri, None, || {
60-
Self::new(create_channel(uri.clone(), None)).into()
61-
})
62-
.into()
83+
fn with_uri(uri: Uri, pool: &ConnectionPool) -> Result<Self, Self::Error> {
84+
Ok(pool
85+
.get_or_create(PoolPrefix::Core, &uri, None, || {
86+
match create_channel(uri.clone(), None) {
87+
Ok(channel) => Ok(Self::new(channel).into()),
88+
Err(e) => Err(dapi_grpc::tonic::Status::failed_precondition(format!(
89+
"Channel creation failed: {}",
90+
e
91+
))),
92+
}
93+
})?
94+
.into())
6395
}
6496

6597
fn with_uri_and_settings(
6698
uri: Uri,
6799
settings: &AppliedRequestSettings,
68100
pool: &ConnectionPool,
69-
) -> Self {
70-
pool.get_or_create(PoolPrefix::Core, &uri, Some(settings), || {
71-
Self::new(create_channel(uri.clone(), Some(settings))).into()
72-
})
73-
.into()
101+
) -> Result<Self, Self::Error> {
102+
Ok(pool
103+
.get_or_create(
104+
PoolPrefix::Core,
105+
&uri,
106+
Some(settings),
107+
|| match create_channel(uri.clone(), Some(settings)) {
108+
Ok(channel) => Ok(Self::new(channel).into()),
109+
Err(e) => Err(dapi_grpc::tonic::Status::failed_precondition(format!(
110+
"Channel creation failed: {}",
111+
e
112+
))),
113+
},
114+
)?
115+
.into())
74116
}
75117
}
76118

packages/rs-sdk/src/platform/types/evonode.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use futures::{FutureExt, TryFutureExt};
1010
use rs_dapi_client::transport::{
1111
AppliedRequestSettings, PlatformGrpcClient, TransportClient, TransportRequest,
1212
};
13-
use rs_dapi_client::{Address, ConnectionPool, RequestSettings};
13+
use rs_dapi_client::{Address, ConnectionPool, DapiClientError, RequestSettings};
1414
#[cfg(feature = "mocks")]
1515
use serde::{Deserialize, Serialize};
1616
use std::fmt::Debug;
@@ -74,7 +74,16 @@ impl TransportRequest for EvoNode {
7474
// We also create a new client to use with this request, so that the user does not need to
7575
// reconfigure SDK to use a single node.
7676
let pool = ConnectionPool::new(1);
77-
let mut client = Self::Client::with_uri_and_settings(uri.clone(), settings, &pool);
77+
// We create a new client with the given URI and settings
78+
let client_result = Self::Client::with_uri_and_settings(uri.clone(), settings, &pool);
79+
80+
// Handle the result manually to create a proper error response
81+
let mut client = match client_result {
82+
Ok(client) => client,
83+
Err(e) => {
84+
return async { Err(e) }.boxed();
85+
}
86+
};
7887
let mut grpc_request = GetStatusRequest {
7988
version: Some(get_status_request::Version::V0(GetStatusRequestV0 {})),
8089
}

0 commit comments

Comments
 (0)