Skip to content

Commit

Permalink
WIP: feat(wasm): make Beerus buildable against wasm32 target
Browse files Browse the repository at this point in the history
  • Loading branch information
sergey-melnychuk committed Jun 22, 2024
1 parent 91331d8 commit 2dfcb6c
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 23 deletions.
1 change: 0 additions & 1 deletion .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ jobs:
- run: cargo test --features skip-zero-root-validation

wasm-check:
if: false ## disabled until wasm effort is in progress
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 19 additions & 9 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ name = "beerus"
version = "0.5.0"

[features]
default = ["rpc"]
default = ["rpc", "blockifier"]
rpc = ["dep:axum"]
blockifier = ["dep:blockifier", "dep:cairo-vm", "dep:ureq"]

## FOR TESTING ONLY
## skip proof validation of state root is 0x0
Expand All @@ -17,11 +18,6 @@ serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde_with = "2.3.3"
async-trait = "0.1.80"
reqwest = { version = "0.12.3", default-features = false, features = [
"json",
"blocking",
"rustls-tls",
] }
## Tokio WASM support: https://docs.rs/tokio/latest/tokio/#wasm-support
tokio = { version = "1", features = [
"sync",
Expand All @@ -46,14 +42,14 @@ ethers = { git = "https://github.com/gakonst/ethers-rs", rev = "3bf1a9e0d698e9fd
helios = { git = "https://github.com/a16z/helios", rev = "1572a24" }

starknet-crypto = "0.6.2"
blockifier = "0.5.0"
blockifier = { version = "0.5.0", optional = true }
starknet_api = "0.10.0"
cairo-vm = "0.9.2"
cairo-vm = { version = "0.9.2", optional = true }

base64 = "0.22.0"
flate2 = "1.0.28"
cairo-lang-starknet-classes = "2.6.3"
ureq = { version = "2.9.6", features = ["json"] }
ureq = { version = "2.9.6", features = ["json"], optional = true }
hex = "0.4.3"
bitvec = "1.0.1"
validator = { version = "0.18.1", features = ["derive"] }
Expand All @@ -63,3 +59,17 @@ clap = { version = "4.5.7", features = ["derive"] }

[dev-dependencies]
wiremock = "0.6.0"

[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen-futures = "0.4.37"
reqwest = { version = "0.12.3", default-features = false, features = [
"json",
"blocking",
] }

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
reqwest = { version = "0.12.3", default-features = false, features = [
"json",
"blocking",
"rustls-tls",
] }
62 changes: 52 additions & 10 deletions src/bin/beerus.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,49 @@
use std::{sync::Arc, time::Duration};
use clap::Parser;

use beerus::config::Config;
use clap::Parser;
use tokio::sync::RwLock;

#[tokio::main]
async fn main() -> eyre::Result<()> {
fn main() -> eyre::Result<()> {
// TODO: expose Beerus with ctor and get_proven_state & get_recent_state methods
// TODO: make a web page that calls those methods periodically (via setTimeout)
// TODO: expose Ethereum methods (via Helios) and Starknet methods (via client)
#[cfg(target_arch = "wasm32")]
{
let _ = wasm_bindgen_futures::spawn_local(async {
tracing_subscriber::fmt::init();

let config = get_config(Args::parse()).expect("config missing");
config.validate_params().await.expect("config invalid");

let beerus = beerus::client::Client::new(&config)
.await
.expect("client failed");
beerus.start().await.expect("start failed");

let state = beerus.get_state().await.expect("get_state failed");
tracing::info!(?state, "initialized");
});

return Ok(());
}

#[cfg(not(target_arch = "wasm32"))]
{
tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()?
.block_on(async {
let _ = run().await;
});

Ok(())
}
}

#[cfg(not(target_arch = "wasm32"))]
async fn run() -> eyre::Result<()> {
use std::{sync::Arc, time::Duration};
use tokio::sync::RwLock;

tracing_subscriber::fmt::init();

let config = get_config(Args::parse())?;
Expand Down Expand Up @@ -39,12 +77,15 @@ async fn main() -> eyre::Result<()> {
});
}

let server =
beerus::rpc::serve(&config.starknet_rpc, &config.rpc_addr, state)
.await?;
#[cfg(not(target_arch = "wasm32"))]
{
let server =
beerus::rpc::serve(&config.starknet_rpc, &config.rpc_addr, state)
.await?;

tracing::info!(port = server.port(), "rpc server started");
server.done().await;
tracing::info!(port = server.port(), "rpc server started");
server.done().await;
}

Ok(())
}
Expand All @@ -56,6 +97,7 @@ struct Args {
config: Option<String>,
}

// #[cfg(not(target_arch = "wasm32"))]
fn get_config(args: Args) -> eyre::Result<Config> {
Ok(if let Some(path) = args.config.as_ref() {
Config::from_file(path)?
Expand Down
13 changes: 12 additions & 1 deletion src/client.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use std::sync::Arc;

use eyre::{Context, Result};
use tokio::sync::RwLock;

use crate::eth::EthereumClient;
use crate::eth::{EthereumClient, Helios};
use crate::gen::client::Client as StarknetClient;
use crate::gen::{BlockId, Felt, Rpc};
use crate::{config::Config, gen::FunctionCall};
Expand Down Expand Up @@ -28,6 +31,14 @@ impl Client {
self.ethereum.start().await
}

pub fn ethereum(&self) -> Arc<RwLock<Helios>> {
self.ethereum.helios()
}

pub fn starknet(&self) -> &StarknetClient {
&self.starknet
}

pub async fn call_starknet(
&self,
request: FunctionCall,
Expand Down
6 changes: 6 additions & 0 deletions src/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ const SEPOLIA_CONSENSUS_RPC: &str =
"http://unstable.sepolia.beacon-api.nimbus.team";
const SEPOLIA_FALLBACK_RPC: &str = "https://sync-sepolia.beaconcha.in";

pub type Helios = Client<DB>;

pub struct EthereumClient {
helios: Arc<RwLock<Client<DB>>>,
starknet_core_contract_address: Address,
Expand Down Expand Up @@ -53,6 +55,10 @@ impl EthereumClient {
Ok(())
}

pub fn helios(&self) -> Arc<RwLock<Helios>> {
self.helios.clone()
}

pub async fn latest(&self) -> Result<(u64, H256)> {
let block_number = self
.helios
Expand Down
8 changes: 6 additions & 2 deletions src/gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2224,7 +2224,8 @@ pub mod gen {
}
}

#[async_trait::async_trait]
#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
pub trait Rpc {
/// Returns merkle proofs of a contract's storage state
async fn getProof(
Expand Down Expand Up @@ -3712,6 +3713,7 @@ pub mod gen {
};
}

#[cfg(not(target_arch = "wasm32"))]
pub mod blocking {
use super::*;
pub trait Rpc {
Expand Down Expand Up @@ -5303,7 +5305,8 @@ pub mod gen {
}
}

#[async_trait::async_trait]
#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
impl super::Rpc for Client {
async fn getProof(
&self,
Expand Down Expand Up @@ -7456,6 +7459,7 @@ pub mod gen {
}
}

#[cfg(not(target_arch = "wasm32"))]
pub mod blocking {
use super::*;

Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
pub mod client;
pub mod config;
pub mod eth;

#[cfg(not(target_arch = "wasm32"))]
pub mod exe;
pub mod gen;
pub mod proof;
Expand Down

0 comments on commit 2dfcb6c

Please sign in to comment.