Skip to content

Commit 3d4be1a

Browse files
Implement avail-light-web
1 parent 38e1c34 commit 3d4be1a

File tree

9 files changed

+248
-5
lines changed

9 files changed

+248
-5
lines changed

.github/workflows/default.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ jobs:
3333
- uses: actions-rust-lang/setup-rust-toolchain@v1
3434
with:
3535
components: clippy
36-
- run: cargo clippy --workspace -- -D warnings
36+
# TODO: Enable avail-light-web once issue with rocksdb feature being applied
37+
# accross the workspace is resolved
38+
- run: cargo clippy --workspace --exclude avail-light-web -- -D warnings
3739

3840
test:
3941
name: cargo test
@@ -42,7 +44,9 @@ jobs:
4244
- uses: actions/checkout@v4
4345
- uses: arduino/setup-protoc@v2
4446
- uses: actions-rust-lang/setup-rust-toolchain@v1
45-
- run: cargo test --workspace --benches --tests
47+
# TODO: Enable avail-light-web once issue with rocksdb feature being applied
48+
# accross the workspace is resolved
49+
- run: cargo test --workspace --benches --tests --exclude avail-light-web
4650
env:
4751
RUSTFLAGS: "-C instrument-coverage"
4852
LLVM_PROFILE_FILE: "profile-%p-%m.profraw"

Cargo.lock

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

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ members = [
77
"crawler",
88
"fat",
99
"relay",
10+
"web",
1011
]
1112
default-members = ["client"]
1213
resolver = "2"

core/src/light_client.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ use crate::{
4343
utils::{blake2_256, calculate_confidence, extract_kate},
4444
};
4545

46+
#[derive(Debug)]
4647
pub enum OutputEvent {
4748
RecordBlockProcessingDelay(f64),
4849
CountSessionBlocks,

core/src/network/p2p.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -317,10 +317,9 @@ async fn build_swarm(
317317
};
318318
#[cfg(target_arch = "wasm32")]
319319
{
320+
use libp2p_webrtc_websys as webrtc;
320321
swarm = tokio_swarm
321-
.with_other_transport(|key| {
322-
libp2p_webrtc_websys::Transport::new(libp2p_webrtc_websys::Config::new(&key))
323-
})?
322+
.with_other_transport(|key| webrtc::Transport::new(webrtc::Config::new(&key)))?
324323
.with_relay_client(noise::Config::new, yamux::Config::default)?
325324
.with_behaviour(behaviour)?
326325
.with_swarm_config(|c| generate_config(c, cfg))

web/Cargo.toml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
[package]
2+
name = "avail-light-web"
3+
version = "0.1.0"
4+
authors.workspace = true
5+
edition = "2021"
6+
repository.workspace = true
7+
8+
[lib]
9+
crate-type = ["cdylib", "rlib"]
10+
11+
[features]
12+
default = ["console_error_panic_hook"]
13+
14+
[dependencies]
15+
avail-light-core = { workspace = true }
16+
avail-rust = { workspace = true }
17+
clap = { workspace = true }
18+
console_error_panic_hook = { version = "0.1.7", optional = true }
19+
futures = { workspace = true }
20+
sp-io = { version = "30", features = ["disable_allocator", "disable_panic_handler"], default-features = false }
21+
tokio = { version = "^1", default-features = false, features = ["sync", "macros", "io-util", "rt"] }
22+
tokio_with_wasm = { version = "0.7.1", features = ["sync", "macros", "rt"] }
23+
tracing = { workspace = true }
24+
tracing-subscriber = { workspace = true }
25+
tracing-wasm = "0.2.1"
26+
wasm-bindgen = "0.2.93"
27+
wasm-bindgen-futures = "0.4.43"
28+
web-sys = { version = "0.3.70", features = ["console"] }
29+
web-time = "1.1.0"

web/README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Avail Light Client (Web)
2+
3+
## Compile
4+
5+
`wasm-pack build --target web --dev`
6+
7+
## Run
8+
9+
`cp www/index.html pkg/`
10+
`cd pkg`
11+
`python3 -m http.server --directory .`

web/src/lib.rs

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
use std::sync::Arc;
2+
3+
use avail_light_core::data;
4+
use avail_light_core::light_client::OutputEvent as LcEvent;
5+
use avail_light_core::network::{self, p2p, rpc};
6+
use avail_light_core::shutdown::Controller;
7+
use avail_light_core::types::{Delay, MultiaddrConfig};
8+
use avail_light_core::utils::spawn_in_span;
9+
use avail_rust::kate_recovery::couscous;
10+
use tokio::sync::{broadcast, mpsc};
11+
use tokio_with_wasm::alias as tokio;
12+
use tracing::{error, info, warn};
13+
use wasm_bindgen::prelude::*;
14+
use web_time::Duration;
15+
16+
#[tokio::main(flavor = "current_thread")]
17+
#[wasm_bindgen(start)]
18+
async fn main_js() {}
19+
20+
#[wasm_bindgen]
21+
pub async fn run() {
22+
console_error_panic_hook::set_once();
23+
tracing_wasm::set_as_global_default();
24+
25+
let version = clap::crate_version!();
26+
let shutdown = Controller::new();
27+
let db = data::DB::default();
28+
// TODO: Store and read client_id from local storage
29+
// let client_id = Uuid::new_v4();
30+
// let execution_id = Uuid::new_v4();
31+
32+
let pp = Arc::new(couscous::public_params());
33+
34+
let network = network::Network::Local;
35+
36+
let cfg_rpc = rpc::configuration::RPCConfig {
37+
full_node_ws: network.full_node_ws(),
38+
..Default::default()
39+
};
40+
41+
let cfg_libp2p = p2p::configuration::LibP2PConfig {
42+
bootstraps: vec![MultiaddrConfig::PeerIdAndMultiaddr((
43+
network.bootstrap_peer_id(),
44+
network.bootstrap_multiaddr(),
45+
))],
46+
..Default::default()
47+
};
48+
49+
let genesis_hash = &network.genesis_hash().to_string();
50+
51+
let (rpc_client, rpc_events, rpc_subscriptions) =
52+
rpc::init(db.clone(), genesis_hash, &cfg_rpc, shutdown.clone())
53+
.await
54+
.unwrap();
55+
56+
let (id_keys, _peer_id) = p2p::identity(&cfg_libp2p, db.clone()).unwrap();
57+
58+
let project_name = "avail".to_string();
59+
let (p2p_client, p2p_event_loop, _p2p_event_receiver) = p2p::init(
60+
cfg_libp2p.clone(),
61+
project_name,
62+
id_keys,
63+
version,
64+
"DEV",
65+
false,
66+
shutdown.clone(),
67+
)
68+
.await
69+
.unwrap();
70+
71+
let network_client = network::new(p2p_client.clone(), rpc_client, pp, false);
72+
73+
// spawn the RPC Network task for Event Loop to run in the background
74+
// and shut it down, without delays
75+
let _rpc_subscriptions_handle = spawn_in_span(shutdown.with_cancel(shutdown.with_trigger(
76+
"Subscription loop failure triggered shutdown".to_string(),
77+
async {
78+
let result = rpc_subscriptions.run().await;
79+
if let Err(ref err) = result {
80+
error!(%err, "Subscription loop ended with error");
81+
};
82+
result
83+
},
84+
)));
85+
86+
let (lc_sender, mut lc_receiver) = mpsc::unbounded_channel::<LcEvent>();
87+
let (block_tx, _block_rx) =
88+
broadcast::channel::<avail_light_core::types::BlockVerified>(1 << 7);
89+
90+
let channels = avail_light_core::types::ClientChannels {
91+
block_sender: block_tx,
92+
rpc_event_receiver: rpc_events.subscribe(),
93+
};
94+
95+
spawn_in_span(async move {
96+
loop {
97+
let Some(message) = lc_receiver.recv().await else {
98+
info!("Exiting...");
99+
break;
100+
};
101+
info!("{message:?}");
102+
}
103+
});
104+
105+
let light_client_handle = tokio::task::spawn(avail_light_core::light_client::run(
106+
db.clone(),
107+
network_client,
108+
99.9,
109+
Delay(Some(Duration::from_secs(20))),
110+
channels,
111+
shutdown.clone(),
112+
lc_sender,
113+
));
114+
115+
tokio::task::spawn(p2p_event_loop.run());
116+
117+
let bootstraps = cfg_libp2p.bootstraps.clone();
118+
let bootstrap_p2p_client = p2p_client.clone();
119+
spawn_in_span(shutdown.with_cancel(async move {
120+
info!("Bootstraping the DHT with bootstrap nodes...");
121+
let bs_result = bootstrap_p2p_client
122+
.clone()
123+
.bootstrap_on_startup(&bootstraps)
124+
.await;
125+
match bs_result {
126+
Ok(_) => {
127+
info!("Bootstrap done.");
128+
},
129+
Err(e) => {
130+
warn!("Bootstrap process: {e:?}.");
131+
},
132+
}
133+
}));
134+
135+
if let Err(error) = light_client_handle.await {
136+
error!("Error running light client: {error}")
137+
};
138+
}

web/www/index.html

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Avail Light Client Web</title>
7+
</head>
8+
<body>
9+
<h1>Avail Light Client Web</h1>
10+
<script type="module">
11+
import init, { run } from './avail_light_web.js';
12+
(async () => {
13+
await init();
14+
await run();
15+
})();
16+
</script>
17+
</body>
18+
</html>

0 commit comments

Comments
 (0)