Skip to content

Commit 861756c

Browse files
authored
Merge pull request #105 from bitfinity-network/http_outcall_fix
[EPROD-642] http outcall client fix
2 parents e552ca5 + 0fbc115 commit 861756c

6 files changed

Lines changed: 63 additions & 38 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ tokio = { version = "1.24", features = ["macros", "rt", "signal"] }
7979
wiremock = "0.5"
8080
yup-oauth2 = "8.3.2"
8181
zip = "0.6"
82+
url = "2.5"
8283

8384
[profile.dev]
8485
debug = false

src/ethereum-json-rpc-client/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pocket-ic-tests-client = [
1515
"ic-canister-client/pocket-ic-client",
1616
]
1717
reqwest = ["dep:reqwest"]
18+
http-outcall = ["dep:url"]
1819

1920
[dependencies]
2021
anyhow = { workspace = true }
@@ -23,6 +24,7 @@ did = { path = "../did" }
2324
hex = { workspace = true }
2425
ic-exports = { workspace = true }
2526
ic-canister-client = { workspace = true, optional = true }
27+
url = { workspace = true, optional = true }
2628
itertools = { workspace = true }
2729
log = { workspace = true }
2830
reqwest = { workspace = true, optional = true, features = [

src/ethereum-json-rpc-client/src/canister_client.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,20 @@ impl<T: CanisterClient + Sync + 'static> Client for T {
3535

3636
let args = HttpRequest::new(&request)?;
3737

38-
let http_response: HttpResponse = if is_update_call {
38+
let http_response: Result<HttpResponse, _> = if is_update_call {
3939
client.update("http_request_update", (args,)).await
4040
} else {
4141
client.query("http_request", (args,)).await
4242
}
43-
.context("failed to send RPC request")?;
43+
.map_err(anyhow::Error::from);
44+
45+
let http_response = match http_response {
46+
Ok(response) => response,
47+
Err(e) => {
48+
log::warn!("failed to send RPC request: {e}");
49+
return Err(e);
50+
}
51+
};
4452

4553
let response = serde_json::from_slice(&http_response.body)
4654
.context("failed to deserialize RPC request")?;

src/ethereum-json-rpc-client/src/http_outcall.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use ic_exports::ic_cdk::api::management_canister::http_request::{
77
self, CanisterHttpRequestArgument, HttpHeader, HttpMethod, TransformContext,
88
};
99
use jsonrpc_core::Request;
10-
use reqwest::Url;
1110

1211
use crate::Client;
1312

@@ -56,12 +55,12 @@ impl Client for HttpOutcallClient {
5655
Box::pin(async move {
5756
log::trace!("CanisterClient - sending 'http_outcall'. url: {url}");
5857

59-
let real_url =
60-
Url::parse(&url).map_err(|e| anyhow::format_err!("error parsing the url {e}"))?;
58+
let parsed_url = url::Url::parse(&url)
59+
.map_err(|e| anyhow::format_err!("failed to parse url `{url}`: {e}"))?;
6160

62-
let host = real_url
61+
let host = parsed_url
6362
.host_str()
64-
.ok_or_else(|| anyhow::format_err!("empty host of url".to_string()))?;
63+
.ok_or_else(|| anyhow::format_err!("no host in url `{parsed_url}`"))?;
6564

6665
let headers = vec![
6766
HttpHeader {

src/ethereum-json-rpc-client/src/lib.rs

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ pub mod reqwest;
1717
#[cfg(feature = "ic-canister-client")]
1818
pub mod canister_client;
1919

20+
#[cfg(feature = "http-outcall")]
2021
pub mod http_outcall;
2122

2223
const ETH_CHAIN_ID_METHOD: &str = "eth_chainId";
@@ -336,7 +337,8 @@ impl<C: Client> EthJsonRcpClient<C> {
336337
#[derive(Debug, Clone, Serialize, Deserialize)]
337338
pub struct EthGetLogsParams {
338339
/// Addresses of contracts to filter logs for.
339-
pub address: Vec<H160>,
340+
#[serde(skip_serializing_if = "Option::is_none")]
341+
pub address: Option<Vec<H160>>,
340342

341343
/// Start search logs from this block number.
342344
#[serde(rename = "fromBlock")]
@@ -347,7 +349,8 @@ pub struct EthGetLogsParams {
347349
pub to_block: BlockNumber,
348350

349351
/// Filter logs by topics.
350-
pub topics: Vec<H256>,
352+
#[serde(skip_serializing_if = "Option::is_none")]
353+
pub topics: Option<Vec<Vec<H256>>>,
351354
}
352355

353356
pub trait Client: Clone + Send + Sync {
@@ -366,22 +369,28 @@ mod tests {
366369
#[test]
367370
fn test_eth_get_logs_params_serialization() {
368371
let get_logs_params = EthGetLogsParams {
369-
address: vec!["0xb59f67a8bff5d8cd03f6ac17265c550ed8f33907"
372+
address: Some(vec!["0xb59f67a8bff5d8cd03f6ac17265c550ed8f33907"
370373
.parse()
371-
.unwrap()],
374+
.unwrap()]),
372375
from_block: BlockNumber::Number(42u64.into()),
373376
to_block: BlockNumber::Latest,
374-
topics: vec![
375-
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
376-
.parse()
377-
.unwrap(),
378-
"0x00000000000000000000000000b46c2526e227482e2ebb8f4c69e4674d262e75"
379-
.parse()
380-
.unwrap(),
381-
"0x00000000000000000000000054a2d42a40f51259dedd1978f6c118a0f0eff078"
382-
.parse()
383-
.unwrap(),
384-
],
377+
topics: Some(vec![
378+
vec![
379+
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
380+
.parse()
381+
.unwrap(),
382+
],
383+
vec![
384+
"0x00000000000000000000000000b46c2526e227482e2ebb8f4c69e4674d262e75"
385+
.parse()
386+
.unwrap(),
387+
],
388+
vec![
389+
"0x00000000000000000000000054a2d42a40f51259dedd1978f6c118a0f0eff078"
390+
.parse()
391+
.unwrap(),
392+
],
393+
]),
385394
};
386395

387396
let json = serde_json::to_string(&get_logs_params).unwrap();
@@ -391,9 +400,9 @@ mod tests {
391400
\"fromBlock\":\"0x2a\",\
392401
\"toBlock\":\"latest\",\
393402
\"topics\":[\
394-
\"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef\",\
395-
\"0x00000000000000000000000000b46c2526e227482e2ebb8f4c69e4674d262e75\",\
396-
\"0x00000000000000000000000054a2d42a40f51259dedd1978f6c118a0f0eff078\"\
403+
[\"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef\"],\
404+
[\"0x00000000000000000000000000b46c2526e227482e2ebb8f4c69e4674d262e75\"],\
405+
[\"0x00000000000000000000000054a2d42a40f51259dedd1978f6c118a0f0eff078\"]\
397406
]}";
398407
assert_eq!(json, expected_json);
399408
}

src/ethereum-json-rpc-client/tests/reqwest/mod.rs

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -105,22 +105,28 @@ async fn should_get_full_blocks_by_number() {
105105
#[tokio::test]
106106
async fn should_get_logs() {
107107
let params = EthGetLogsParams {
108-
address: vec!["0xb59f67a8bff5d8cd03f6ac17265c550ed8f33907"
108+
address: Some(vec!["0xb59f67a8bff5d8cd03f6ac17265c550ed8f33907"
109109
.parse()
110-
.unwrap()],
110+
.unwrap()]),
111111
from_block: "0x429d3b".parse().unwrap(),
112112
to_block: BlockNumber::Latest,
113-
topics: vec![
114-
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
115-
.parse()
116-
.unwrap(),
117-
"0x00000000000000000000000000b46c2526e227482e2ebb8f4c69e4674d262e75"
118-
.parse()
119-
.unwrap(),
120-
"0x00000000000000000000000054a2d42a40f51259dedd1978f6c118a0f0eff078"
121-
.parse()
122-
.unwrap(),
123-
],
113+
topics: Some(vec![
114+
vec![
115+
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
116+
.parse()
117+
.unwrap(),
118+
],
119+
vec![
120+
"0x00000000000000000000000000b46c2526e227482e2ebb8f4c69e4674d262e75"
121+
.parse()
122+
.unwrap(),
123+
],
124+
vec![
125+
"0x00000000000000000000000054a2d42a40f51259dedd1978f6c118a0f0eff078"
126+
.parse()
127+
.unwrap(),
128+
],
129+
]),
124130
};
125131

126132
let result = reqwest_client().get_logs(params).await.unwrap();

0 commit comments

Comments
 (0)