Skip to content

Commit c8dec1b

Browse files
authored
Merge pull request #77 from bitfinity-network/refactor_eth_client
Refactor ethereum-json-rpc-client
2 parents bb8e9e2 + 9ae393d commit c8dec1b

21 files changed

Lines changed: 568 additions & 932 deletions

File tree

Cargo.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ members = [
55
"src/eth-signer/test_canister",
66
"src/evm-block-extractor",
77
"src/evm-canister-client",
8-
"src/iceth-client",
9-
"src/iceth-client/test-canister",
108
"src/minter-client",
119
"src/minter-did",
1210
"src/register-evm-agent",
@@ -25,7 +23,7 @@ include = ["src/**/*", "LICENSE", "README.md"]
2523
license = "MIT"
2624
name = "bitfinity-evm-sdk"
2725
repository = "https://github.com/bitfinity-network/bitfinity-evm-sdk"
28-
version = "0.7.0"
26+
version = "0.8.0"
2927

3028
[workspace.dependencies]
3129
anyhow = "1.0"
@@ -55,6 +53,7 @@ rand = { version = "0.8", features = ["std_rng", "small_rng"] }
5553
reqwest = { version = "0.11", default-features = false }
5654
rlp = "0.5"
5755
serde = "1.0"
56+
serde_bytes = "0.11"
5857
serde_json = "1.0"
5958
sha2 = "0.10"
6059
sha3 = "0.10"

dfx.json

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,6 @@
44
"candid": "./target/artifact/ic-sign-test-canister.did",
55
"wasm": "./target/artifact/ic-sign-test-canister.wasm",
66
"type": "custom"
7-
},
8-
"iceth-client-test-canister": {
9-
"candid": "./target/artifact/iceth-client-test-canister.did",
10-
"wasm": "./target/artifact/iceth-client-test-canister.wasm",
11-
"type": "custom"
12-
},
13-
"iceth": {
14-
"candid": "./target/artifact/iceth.did",
15-
"wasm": "./target/artifact/iceth.wasm",
16-
"type": "custom"
177
}
188
},
199
"version": 1

scripts/build.sh

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,6 @@ set -e
33
export RUST_BACKTRACE=full
44
export WASM_DIR=./target/artifact
55

6-
build_iceth_client_test_canisters() {
7-
8-
TAG=v0.1.1
9-
ICETH_URL=https://github.com/infinity-swap/iceth/releases/download/${TAG}/iceth-${TAG}.tar.gz
10-
echo "Downloading $ICETH_URL"
11-
curl -fsSL $ICETH_URL | tar -xz -C "$WASM_DIR"
12-
13-
echo "Building iceth-client test canister"
14-
cargo run -p iceth-client-test-canister --features export-api --release > $WASM_DIR/iceth-client-test-canister.did
15-
cargo build -p iceth-client-test-canister --target wasm32-unknown-unknown --features export-api --release
16-
ic-wasm target/wasm32-unknown-unknown/release/iceth-client-test-canister.wasm -o $WASM_DIR/iceth-client-test-canister.wasm shrink
17-
}
18-
196
build_ic_sign_test_canister() {
207
echo "Building ic-sign-client test canisters"
218
cargo run -p ic-sign-test-canister --features "export-api" > $WASM_DIR/ic-sign-test-canister.did
@@ -26,7 +13,6 @@ build_ic_sign_test_canister() {
2613
main() {
2714
mkdir -p $WASM_DIR
2815

29-
build_iceth_client_test_canisters
3016
build_ic_sign_test_canister
3117

3218
}

scripts/dfx_deploy.sh

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,6 @@ set -e
33

44
export WASM_DIR=./target/artifact
55

6-
deploy_iceth_client_test_canisters() {
7-
echo "Deploying iceth artifact..."
8-
dfx deploy iceth
9-
10-
echo "Deploying iceth-client artifact..."
11-
ICETH_PRINCIPAL=$(dfx canister id iceth)
12-
INIT_ARGS="record { url=\"https://testnet.bitfinity.network\"; iceth=principal \"$ICETH_PRINCIPAL\"; chain_id=355113}"
13-
dfx deploy iceth-client-test-canister --argument "$INIT_ARGS" -m reinstall -y
14-
}
15-
166
deploy_ic_sign_test_canister() {
177
echo "Deploying ic-sign-test-canister artifacts..."
188
dfx deploy ic-sign-test-canister
@@ -26,7 +16,6 @@ main() {
2616
# Wait for dfx started
2717
sleep 5
2818

29-
deploy_iceth_client_test_canisters
3019
deploy_ic_sign_test_canister
3120
}
3221

scripts/dfx_test.sh

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,6 @@
22
set -e
33
export RUST_BACKTRACE=full
44

5-
test_iceth_client_test_canisters() {
6-
echo "Running dfx tests for iceth-client..."
7-
dfx canister call iceth-client-test-canister test_send_raw_transaction_signed_with_signing_key
8-
dfx canister call iceth-client-test-canister test_send_raw_transaction_signed_with_management_canister
9-
}
10-
115
test_ic_sign_test_canister() {
126
echo "Running dfx tests for eth-signer..."
137
dfx canister call ic-sign-test-canister sign_and_check
@@ -19,7 +13,6 @@ main() {
1913

2014
./scripts/dfx_deploy.sh
2115

22-
test_iceth_client_test_canisters
2316
test_ic_sign_test_canister
2417
}
2518

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,26 @@ edition.workspace = true
88
license.workspace = true
99
repository.workspace = true
1010

11+
[features]
12+
ic-canister-client = ["candid", "dep:ic-canister-client"]
13+
state-machine-tests-client = ["ic-canister-client", "ic-canister-client/state-machine-tests-client"]
14+
reqwest = ["dep:reqwest"]
15+
1116
[dependencies]
1217
anyhow = { workspace = true }
18+
candid = { workspace = true, optional = true }
19+
hex = { workspace = true }
20+
ic-canister-client = { workspace = true, optional = true }
1321
itertools = { workspace = true }
1422
log = { workspace = true }
15-
reqwest = { workspace = true, features = [
23+
reqwest = { workspace = true, optional = true, features = [
1624
"gzip",
1725
"json",
1826
"rustls-tls",
1927
"trust-dns",
2028
] }
2129
serde = { workspace = true }
30+
serde_bytes = { workspace = true }
2231
serde_json = { workspace = true }
2332
ethers-core = { workspace = true }
2433
jsonrpc-core = { workspace = true }
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
use std::collections::HashMap;
2+
use std::future::Future;
3+
use std::pin::Pin;
4+
5+
use anyhow::Context;
6+
use candid::{CandidType, Deserialize};
7+
use ic_canister_client::CanisterClient;
8+
use jsonrpc_core::{Call, Request, Response};
9+
use serde::Serialize;
10+
use serde_bytes::ByteBuf;
11+
12+
use crate::{Client, ETH_SEND_RAW_TRANSACTION_METHOD};
13+
14+
impl<T: CanisterClient + Sync + 'static> Client for T {
15+
fn send_rpc_request(
16+
&self,
17+
request: Request,
18+
) -> Pin<Box<dyn Future<Output = anyhow::Result<Response>> + Send>> {
19+
let client = self.clone();
20+
21+
Box::pin(async move {
22+
log::trace!("CanisterClient - sending 'http_request'. request: {request:?}");
23+
24+
let is_update_call = match &request {
25+
Request::Single(Call::MethodCall(call)) => is_update_call(&call.method),
26+
Request::Batch(calls) => calls.iter().any(|call| {
27+
if let Call::MethodCall(call) = call {
28+
is_update_call(&call.method)
29+
} else {
30+
false
31+
}
32+
}),
33+
_ => false,
34+
};
35+
36+
let args = HttpRequest::new(&request)?;
37+
38+
let http_response: HttpResponse = if is_update_call {
39+
client.update("http_request_update", (args,)).await
40+
} else {
41+
client.query("http_request", (args,)).await
42+
}
43+
.context("failed to send RPC request")?;
44+
45+
let response = serde_json::from_slice(&http_response.body)
46+
.context("failed to deserialize RPC request")?;
47+
48+
log::trace!("response: {:?}", response);
49+
50+
Ok(response)
51+
})
52+
}
53+
}
54+
55+
/// The important components of an HTTP request.
56+
#[derive(Clone, Debug, CandidType)]
57+
struct HttpRequest {
58+
/// The HTTP method string.
59+
pub method: &'static str,
60+
/// The URL method string.
61+
pub url: &'static str,
62+
/// The request headers.
63+
pub headers: HashMap<&'static str, &'static str>,
64+
/// The request body.
65+
pub body: ByteBuf,
66+
}
67+
68+
impl HttpRequest {
69+
pub fn new<T: ?Sized + Serialize>(data: &T) -> anyhow::Result<Self> {
70+
let mut headers = HashMap::new();
71+
headers.insert("content-type", "application/json");
72+
Ok(Self {
73+
method: "POST",
74+
headers,
75+
url: "",
76+
body: ByteBuf::from(
77+
serde_json::to_vec(data).context("failed to serialize RPC request")?,
78+
),
79+
})
80+
}
81+
}
82+
83+
#[derive(Clone, Debug, CandidType, Deserialize)]
84+
pub struct HttpResponse {
85+
/// The HTTP status code.
86+
pub status_code: u16,
87+
/// The response header map.
88+
pub headers: HashMap<String, String>,
89+
/// The response body.
90+
pub body: ByteBuf,
91+
}
92+
93+
#[inline]
94+
fn is_update_call(method: &str) -> bool {
95+
method.eq(ETH_SEND_RAW_TRANSACTION_METHOD)
96+
}
97+
98+
#[cfg(test)]
99+
mod test {
100+
101+
use super::*;
102+
use crate::ETH_CHAIN_ID_METHOD;
103+
104+
#[test]
105+
fn test_is_update_call() {
106+
assert!(is_update_call(ETH_SEND_RAW_TRANSACTION_METHOD));
107+
assert!(!is_update_call(ETH_CHAIN_ID_METHOD));
108+
}
109+
}

0 commit comments

Comments
 (0)