diff --git a/Cargo.lock b/Cargo.lock index 529dfae..bd64289 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2070,10 +2070,10 @@ dependencies = [ "console_error_panic_hook", "ethers", "execution", + "futures", "hex", "serde", "serde-wasm-bindgen 0.4.5", - "serde_json", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", diff --git a/Cargo.toml b/Cargo.toml index 70e19d5..72998d0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ exclude = [ ] [build] -target = "wasm64-unknown-unknown" +target = "wasm32-unknown-unknown" [workspace] members = [ diff --git a/client/src/client.rs b/client/src/client.rs index e7b1f37..8fec402 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -37,8 +37,8 @@ use crate::rpc::Rpc; #[derive(Default)] pub struct ClientBuilder { network: Option, - consensus_rpc: Option, - execution_rpc: Option, + consensus_rpc: Option>, + execution_rpc: Option>, checkpoint: Option>, #[cfg(not(target_arch = "wasm32"))] rpc_port: Option, @@ -60,12 +60,12 @@ impl ClientBuilder { self } - pub fn consensus_rpc(mut self, consensus_rpc: wasm_bindgen::JsValue) -> Self { + pub fn consensus_rpc(mut self, consensus_rpc: Arc) -> Self { self.consensus_rpc = Some(consensus_rpc); self } - pub fn execution_rpc(mut self, execution_rpc: wasm_bindgen::JsValue) -> Self { + pub fn execution_rpc(mut self, execution_rpc: Arc) -> Self { self.execution_rpc = Some(execution_rpc); self } diff --git a/config/src/base.rs b/config/src/base.rs index a691841..f28f476 100644 --- a/config/src/base.rs +++ b/config/src/base.rs @@ -1,4 +1,5 @@ use serde::Serialize; +use std::sync::Arc; use wasm_bindgen::JsValue; use crate::types::{ChainConfig, Forks}; @@ -9,7 +10,7 @@ use crate::utils::bytes_serialize; pub struct BaseConfig { pub rpc_port: u16, #[serde(skip_serializing, skip_deserializing)] - pub consensus_rpc: Option, + pub consensus_rpc: Option>, #[serde( deserialize_with = "bytes_deserialize", serialize_with = "bytes_serialize" diff --git a/config/src/config.rs b/config/src/config.rs index a703564..10440ad 100644 --- a/config/src/config.rs +++ b/config/src/config.rs @@ -4,6 +4,7 @@ use figment::{ }; use serde::de::Error; use serde::{Deserialize, Deserializer}; +use std::sync::Arc; use std::{path::PathBuf, process::exit}; use wasm_bindgen::JsValue; @@ -16,9 +17,9 @@ use crate::utils::{bytes_deserialize, bytes_opt_deserialize}; #[derive(Deserialize, Debug, Default)] pub struct Config { #[serde(skip_serializing, skip_deserializing)] - pub consensus_rpc: wasm_bindgen::JsValue, + pub consensus_rpc: Arc, #[serde(skip_serializing, skip_deserializing)] - pub execution_rpc: wasm_bindgen::JsValue, + pub execution_rpc: Arc, pub rpc_port: Option, #[serde(deserialize_with = "bytes_deserialize")] pub default_checkpoint: Vec, diff --git a/config/src/networks.rs b/config/src/networks.rs index 953a0b1..a97816b 100644 --- a/config/src/networks.rs +++ b/config/src/networks.rs @@ -1,5 +1,6 @@ use common::utils::hex_str_to_bytes; use serde::{Deserialize, Serialize}; +use std::sync::Arc; use strum::{Display, EnumIter}; use wasm_bindgen::JsValue; @@ -41,7 +42,7 @@ pub fn mainnet() -> BaseConfig { ) .unwrap(), rpc_port: 8545, - consensus_rpc: Some(JsValue::null()), + consensus_rpc: Some(Arc::from(JsValue::null())), chain: ChainConfig { chain_id: 1, genesis_time: 1606824023, diff --git a/consensus/src/consensus.rs b/consensus/src/consensus.rs index e5c0e27..e3cbc6e 100644 --- a/consensus/src/consensus.rs +++ b/consensus/src/consensus.rs @@ -55,7 +55,7 @@ struct LightClientStore { impl ConsensusClient { pub fn new( - rpc_handler: wasm_bindgen::JsValue, + rpc_handler: Arc, checkpoint_block_root: &[u8], config: Arc, ) -> Result> { @@ -660,8 +660,8 @@ mod tests { async fn get_client(strict_checkpoint_age: bool) -> ConsensusClient { let base_config = networks::goerli(); let config = Config { - consensus_rpc: wasm_bindgen::JsValue::null(), - execution_rpc: wasm_bindgen::JsValue::null(), + consensus_rpc: Arc::from(wasm_bindgen::JsValue::null()), + execution_rpc: Arc::from(wasm_bindgen::JsValue::null()), chain: base_config.chain, forks: base_config.forks, strict_checkpoint_age, @@ -672,9 +672,12 @@ mod tests { hex::decode("1e591af1e90f2db918b2a132991c7c2ee9a4ab26da496bd6e71e4f0bd65ea870") .unwrap(); - let mut client = - ConsensusClient::new(wasm_bindgen::JsValue::null(), &checkpoint, Arc::new(config)) - .unwrap(); + let mut client = ConsensusClient::new( + Arc::from(wasm_bindgen::JsValue::null()), + &checkpoint, + Arc::new(config), + ) + .unwrap(); client.bootstrap().await.unwrap(); client } diff --git a/consensus/src/rpc/mod.rs b/consensus/src/rpc/mod.rs index 1061cec..f907448 100644 --- a/consensus/src/rpc/mod.rs +++ b/consensus/src/rpc/mod.rs @@ -2,6 +2,7 @@ pub mod nimbus_rpc; use async_trait::async_trait; use eyre::Result; +use std::sync::Arc; use crate::types::{BeaconBlock, Bootstrap, FinalityUpdate, OptimisticUpdate, Update}; @@ -9,7 +10,7 @@ use crate::types::{BeaconBlock, Bootstrap, FinalityUpdate, OptimisticUpdate, Upd #[cfg_attr(not(target_arch = "wasm32"), async_trait)] #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] pub trait ConsensusRpc { - fn new(rpc_handler: wasm_bindgen::JsValue) -> Self; + fn new(rpc_handler: Arc) -> Self; async fn get_bootstrap(&self, block_root: &'_ [u8]) -> Result; async fn get_updates(&self, period: u64, count: u8) -> Result>; async fn get_finality_update(&self) -> Result; diff --git a/consensus/src/rpc/nimbus_rpc.rs b/consensus/src/rpc/nimbus_rpc.rs index f06b646..deddccc 100644 --- a/consensus/src/rpc/nimbus_rpc.rs +++ b/consensus/src/rpc/nimbus_rpc.rs @@ -1,11 +1,11 @@ use std::cmp; use std::fmt::{Display, Formatter, Result as FmtResult}; +use std::sync::Arc; use async_trait::async_trait; use eyre::{Result, WrapErr}; -use js_sys::then; use serde::Deserialize; -use serde_wasm_bindgen::from_value as from_js_value; +use serde_json::from_str as from_json_str; use wasm_bindgen::{JsCast, JsValue}; use wasm_bindgen_futures::JsFuture; @@ -30,13 +30,12 @@ impl std::error::Error for RpcError {} #[derive(Debug)] pub struct NimbusRpc { - rpc_handler: wasm_bindgen::JsValue, + rpc_handler: Arc, } -#[cfg_attr(not(target_arch = "wasm32"), async_trait)] -#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[async_trait(?Send)] impl ConsensusRpc for NimbusRpc { - fn new(rpc_handler: JsValue) -> Self { + fn new(rpc_handler: Arc) -> Self { NimbusRpc { rpc_handler } } @@ -142,7 +141,7 @@ struct Spec { } impl NimbusRpc { - async fn request(&self, path: String, error_type: &str) -> Result + async fn request(&self, path: String, error_type: &str) -> Result where for<'a> T: Deserialize<'a>, { @@ -150,18 +149,21 @@ impl NimbusRpc { js_params.set(&JsValue::from_str("method"), &JsValue::from_str("GET")); js_params.set(&JsValue::from_str("path"), &JsValue::from_str(&path)); - let promise = self - .rpc_handler + let rpc_handler_clone = self.rpc_handler.clone(); + let promise = Arc::clone(&rpc_handler_clone) .dyn_into::() .unwrap() .call1(&JsValue::null(), &js_params) .expect("Failed to make JSON-RPC request"); - let result = match promise.dyn_into::() { + let result = match promise.dyn_into::() { Ok(promise) => JsFuture::from(promise).await.unwrap(), Err(_) => panic!("Unable to convert JS value to Promise"), }; - Ok(result) + let json = result.as_string().unwrap(); + let response: T = serde_json::from_str(&json)?; + + Ok(response) } } diff --git a/execution/src/rpc/http_rpc.rs b/execution/src/rpc/http_rpc.rs index 9f8ad42..bbb0343 100644 --- a/execution/src/rpc/http_rpc.rs +++ b/execution/src/rpc/http_rpc.rs @@ -1,6 +1,7 @@ use std::error::Error; use std::fmt::{Debug, Display, Formatter}; use std::str::FromStr; +use std::sync::Arc; use async_trait::async_trait; use ethers::prelude::{Address, Http}; @@ -30,7 +31,7 @@ use wasm_bindgen_futures::JsFuture; pub struct HttpRpc { provider: Provider, - rpc_handler: JsValue, + rpc_handler: Arc, } impl Clone for HttpRpc { @@ -65,15 +66,17 @@ impl From for ProviderError { #[derive(Clone, Debug)] pub struct LumeProvider { - pub rpc_handler: JsValue, + pub rpc_handler: Arc, } impl LumeProvider { - pub fn new(rpc_handler: JsValue) -> Self { + pub fn new(rpc_handler: Arc) -> Self { LumeProvider { rpc_handler } } } +#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] impl JsonRpcClient for LumeProvider { type Error = LumeError; @@ -98,11 +101,9 @@ impl JsonRpcClient for LumeProvider { } } -#[cfg_attr(not(target_arch = "wasm32"), async_trait)] -#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[async_trait(?Send)] impl ExecutionRpc for HttpRpc { - fn new(rpc_handler: wasm_bindgen::JsValue) -> Result { - let http = Http::from_str(rpc)?; + fn new(rpc_handler: Arc) -> Result { let mut client = LumeProvider::new(rpc_handler.clone()); let provider = Provider::new(client); diff --git a/helios-ts/Cargo.toml b/helios-ts/Cargo.toml index bd9fe42..143ec93 100644 --- a/helios-ts/Cargo.toml +++ b/helios-ts/Cargo.toml @@ -1,3 +1,6 @@ +[build] +target = "wasm32-unknown-unknown" + [package] name = "helios-ts" version = "0.1.0" @@ -13,11 +16,12 @@ wasm-bindgen = "0.2.84" wasm-bindgen-futures = "0.4.33" serde-wasm-bindgen = "0.4.5" console_error_panic_hook = "0.1.7" +futures = "0.3" +serde = { version = "1.0.85", features = ["derive"] } ethers = "1.0.0" hex = "0.4.3" -serde = { version = "1.0.143", features = ["derive"] } -serde_json = "1.0.85" + client = { path = "../client" } common = { path = "../common" } diff --git a/helios-ts/src/lib.rs b/helios-ts/src/lib.rs index df8f436..a7936aa 100644 --- a/helios-ts/src/lib.rs +++ b/helios-ts/src/lib.rs @@ -2,6 +2,7 @@ extern crate console_error_panic_hook; extern crate web_sys; use std::str::FromStr; +use std::sync::Arc; use common::types::BlockTag; use ethers::types::{Address, Filter, H256}; @@ -39,6 +40,9 @@ impl Client { let chain_id = base.chain.chain_id; + let execution_rpc = Arc::new(execution_rpc); + let consensus_rpc = Arc::new(consensus_rpc); + let checkpoint = Some( checkpoint .as_ref()