Skip to content

Commit

Permalink
Support WASM in avail-light-core
Browse files Browse the repository at this point in the history
  • Loading branch information
aterentic-ethernal committed Oct 24, 2024
1 parent 6d9dfad commit ab8ba97
Show file tree
Hide file tree
Showing 22 changed files with 705 additions and 521 deletions.
736 changes: 314 additions & 422 deletions Cargo.lock

Large diffs are not rendered by default.

17 changes: 13 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,16 @@ color-eyre = "0.6.2"
confy = "0.5.1"
hex = "0.4.3"
rand = "0.8.4"
libp2p = { version = "0.54", features = ["kad", "identify", "ping", "mdns", "autonat", "relay", "dcutr", "upnp", "noise", "yamux", "dns", "metrics", "tokio", "macros", "tcp", "quic", "serde", "websocket"] }
libp2p-allow-block-list = "0.4"
libp2p-webrtc = { version = "=0.8.0-alpha", features = ["tokio"] }
libp2p = { git = "https://github.com/libp2p/rust-libp2p", rev = "9a45db3f82b760c93099e66ec77a7a772d1f6cd3", features = ["kad", "identify", "ping", "mdns", "autonat", "relay", "dcutr", "upnp", "noise", "yamux", "dns", "metrics", "tokio", "macros", "tcp", "quic", "serde", "websocket"] }
libp2p-allow-block-list = { git = "https://github.com/libp2p/rust-libp2p", rev = "9a45db3f82b760c93099e66ec77a7a772d1f6cd3" }
libp2p-webrtc = { git = "https://github.com/libp2p/rust-libp2p", rev = "9a45db3f82b760c93099e66ec77a7a772d1f6cd3" }
libp2p-webrtc-websys = { git = "https://github.com/libp2p/rust-libp2p", rev = "9a45db3f82b760c93099e66ec77a7a772d1f6cd3" }
# libp2p = { version = "0.54", features = ["kad", "identify", "ping", "mdns", "autonat", "relay", "dcutr", "upnp", "noise", "yamux", "dns", "metrics", "tokio", "macros", "tcp", "quic", "serde", "websocket"] }
# libp2p-allow-block-list = "0.4"
multihash = { version = "0.14.0", default-features = false, features = ["blake3", "sha3"] }
semver = "1.0.23"
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1.35", features = ["full"] }
tokio = { version = "1.35", default-features = false, features = ["sync", "macros", "io-util", "rt", "time"] }
tokio-stream = { version = "0.1.15", features = ["sync"] }
tracing = "0.1.35"
tracing-subscriber = { version = "0.3.17", features = ["json", "env-filter"] }
Expand All @@ -60,3 +63,9 @@ incremental = false
inherits = "release"
lto = "fat"
codegen-units = 1

[patch.crates-io]
# Patching sp-io since some dependencies references patched and some non-patched versions,
# and we need to specify `disable-allocator` feature to enable wasm compilation.
# Patch needs to match patched tag of dependencies, for feature toggle to be applied.
sp-io = { git = "https://github.com/availproject/polkadot-sdk.git", tag = "polkadot-1.7.1-patch-10" }
63 changes: 41 additions & 22 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,66 +4,85 @@ version = "1.0.3"
edition = "2021"
description = "Avail Light core driving library"

[lib]
crate-type = ["cdylib", "rlib"]

[dependencies]
# Internal deps
avail-rust = { workspace = true }
dusk-plonk = { workspace = true }

# 3rd-party
async-std = { workspace = true }
async-stream = "0.3.5"
async-trait = { workspace = true }
base64 = "0.21.0"
better-panic = "0.3.0"
chrono = "0.4.19"
blake2b_simd = "1.0.2"
clap = { workspace = true }
codec = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive", "full", "bit-vec"] }
color-eyre = { workspace = true }
confy = { workspace = true }
derive_more = { version = "0.99.17", features = ["from"] }
derive_more = { version = "1", features = ["from"] }
dusk-bytes = { version = "0.1.6", default-features = false }
futures = { workspace = true }
getrandom = { version = "0.2.15", features = ["js"] }
hex = { workspace = true }
hyper = { version = "0.14.23", features = ["full", "http1"] }
itertools = "0.10.5"
jsonrpsee-core = { version = "0.21.0", features = ["client"] }
libc = "0.2.150"
libp2p = { workspace = true }
libp2p-allow-block-list = { workspace = true }
libp2p-webrtc = { version = "=0.8.0-alpha", features = ["tokio"] }
mockall = "0.11.3"
multihash = { workspace = true }
num = "0.4.0"
num_cpus = "1.13.0"
pcap = "1.1.0"
rand = "0.8.4"
rand_chacha = "0.3"
rocksdb = { version = "0.21.0", features = ["snappy", "multi-threaded-cf"], optional = true }
semver = { workspace = true }
serde = { workspace = true }
serde_json = "1.0.125"
smallvec = "1.6.1"
strip-ansi-escapes = "0.2.0"
strum = { version = "0.26.3", features = ["derive"] }
sysinfo = "0.30.12"
thiserror = "1.0.64"
threadpool = "1.8.1"
tokio = { workspace = true }
tokio-retry = "0.3"
tokio-stream = { workspace = true }
tokio-util = "0.7.10"
tracing = { workspace = true }
tracing-subscriber = { workspace = true }
uuid = { workspace = true }

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
async-std = { workspace = true }
chrono = "0.4.19"
libp2p = { workspace = true }
hyper = { version = "0.14.23", features = ["full", "http1"] }
jsonrpsee-core = { version = "0.21.0", features = ["client"] }
libc = "0.2.150"
libp2p-webrtc = { workspace = true, features = ["tokio"] }
multihash = { workspace = true }
num = "0.4.0"
num_cpus = "1.13.0"
pcap = "1.1.0"
rand = "0.8.4"
rand_chacha = "0.3"
rocksdb = { version = "0.21.0", features = ["snappy", "multi-threaded-cf"], optional = true }
thiserror = "1.0.64"
threadpool = "1.8.1"
void = { workspace = true }
warp = { workspace = true }

# OpenTelemetry
clap = { workspace = true }
opentelemetry = { workspace = true }
opentelemetry-otlp = { workspace = true }
opentelemetry_sdk = { workspace = true }
strum = { version = "0.26.3", features = ["derive"] }
tracing-subscriber = { workspace = true }

[dev-dependencies]
hex-literal = "0.4.0"
[target.'cfg(target_arch = "wasm32")'.dependencies]
ed25519-compact = "2.1.1"
thiserror-no-std = "2.0.2"
rand = { version = "0.8.4", default-features = false }
libp2p = { workspace = true, features = ["wasm-bindgen"] }
libp2p-webrtc-websys = { workspace = true }
wasm-bindgen = "0.2.90"
wasm-timer = "0.2.5"
web-time = "1.1.0"
tokio_with_wasm = { version = "0.7.1", default-features = false, features = ["sync", "macros", "rt", "time"] }

[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
hex-literal = "0.4.1"
proptest = "1.0.0"
test-case = "3.2.1"

Expand Down
3 changes: 1 addition & 2 deletions core/src/api/v2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,7 @@ mod tests {
Database, IsSyncedKey, LatestHeaderKey, LatestSyncKey, MemoryDB, RpcNodeKey,
VerifiedCellCountKey, VerifiedDataKey, VerifiedHeaderKey, VerifiedSyncDataKey,
},
network::rpc::Node,
types::BlockRange,
types::{BlockRange, Node},
};
use async_trait::async_trait;
use avail_rust::{
Expand Down
36 changes: 24 additions & 12 deletions core/src/finality.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
use std::collections::HashMap;

use avail_rust::sp_core::{
blake2_256,
ed25519::{self, Public},
Pair, H256,
};
#[cfg(not(target_arch = "wasm32"))]
use avail_rust::sp_core::ed25519;
use avail_rust::sp_core::{ed25519::Public, H256};
use codec::Encode;
use itertools::Itertools;
use serde::{Deserialize, Serialize};
use tracing::{info, warn};

use crate::types::{GrandpaJustification, SignerMessage};
use crate::{
types::{GrandpaJustification, SignerMessage},
utils::blake2_256,
};
use color_eyre::{eyre::eyre, Result};

#[derive(Clone, Debug, Serialize, Deserialize)]
Expand All @@ -19,6 +20,22 @@ pub struct ValidatorSet {
pub validator_set: Vec<Public>,
}

#[cfg(not(target_arch = "wasm32"))]
fn verify_signature(public_key: [u8; 32], signature: [u8; 64], message: Vec<u8>) -> bool {
<ed25519::Pair as avail_rust::sp_core::Pair>::verify(
&ed25519::Signature(signature),
message,
&ed25519::Public(public_key),
)
}

#[cfg(target_arch = "wasm32")]
fn verify_signature(public_key: [u8; 32], signature: [u8; 64], message: Vec<u8>) -> bool {
let public_key = ed25519_compact::PublicKey::from_slice(&public_key).unwrap();
let signature = ed25519_compact::Signature::from_slice(&signature).unwrap();
public_key.verify(message, &signature).is_ok()
}

pub fn check_finality(
validator_set: &ValidatorSet,
justification: &GrandpaJustification,
Expand Down Expand Up @@ -47,12 +64,7 @@ pub fn check_finality(
&justification.round,
&validator_set.set_id, // Set ID is needed here.
));
let is_ok = <ed25519::Pair as Pair>::verify(
&precommit.signature,
signed_message,
&precommit.id,
);

let is_ok = verify_signature(precommit.id.0, precommit.signature.0, signed_message);
let ancestry = confirm_ancestry(
&precommit.precommit.target_hash,
&justification.commit.target_hash,
Expand Down
8 changes: 8 additions & 0 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
#[cfg(not(target_arch = "wasm32"))]
pub mod api;
#[cfg(not(target_arch = "wasm32"))]
pub mod app_client;
#[cfg(not(target_arch = "wasm32"))]
#[cfg(feature = "crawl")]
pub mod crawl_client;
pub mod data;
#[cfg(not(target_arch = "wasm32"))]
pub mod fat_client;
pub mod finality;
pub mod light_client;
#[cfg(not(target_arch = "wasm32"))]
pub mod maintenance;
pub mod network;
pub mod proof;
pub mod shutdown;
#[cfg(not(target_arch = "wasm32"))]
pub mod sync_client;
#[cfg(not(target_arch = "wasm32"))]
pub mod sync_finality;
#[cfg(not(target_arch = "wasm32"))]
pub mod telemetry;
pub mod types;
pub mod utils;
8 changes: 6 additions & 2 deletions core/src/light_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,18 @@
use avail_rust::{
kate_recovery::{commitments, matrix::Dimensions},
sp_core::blake2_256,
AvailHeader, H256,
};
use codec::Encode;
use color_eyre::Result;
#[cfg(not(target_arch = "wasm32"))]
use std::time::Instant;
use tokio::sync::mpsc::UnboundedSender;
#[cfg(target_arch = "wasm32")]
use tokio_with_wasm::alias as tokio;
use tracing::{error, info};
#[cfg(target_arch = "wasm32")]
use web_time::Instant;

use crate::{
data::{AchievedConfidenceKey, BlockHeaderKey, Database, VerifiedCellCountKey},
Expand All @@ -36,7 +40,7 @@ use crate::{
},
shutdown::Controller,
types::{self, BlockRange, ClientChannels, Delay},
utils::{calculate_confidence, extract_kate},
utils::{blake2_256, calculate_confidence, extract_kate},
};

pub enum OutputEvent {
Expand Down
9 changes: 8 additions & 1 deletion core/src/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,17 @@ use color_eyre::{eyre::WrapErr, Result};
use dusk_plonk::prelude::PublicParameters;
use libp2p::{Multiaddr, PeerId};
use mockall::automock;
use std::{str::FromStr, sync::Arc, time::Duration};
#[cfg(not(target_arch = "wasm32"))]
use std::time::Duration;
use std::{str::FromStr, sync::Arc};
use strum::Display;
#[cfg(not(target_arch = "wasm32"))]
use tokio::time::Instant;
use tracing::{debug, info};
#[cfg(target_arch = "wasm32")]
use web_time::Duration;
#[cfg(target_arch = "wasm32")]
use web_time::Instant;

use crate::{data::Database, proof};

Expand Down
39 changes: 36 additions & 3 deletions core/src/network/p2p.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,35 @@ use libp2p::{
autonat, dcutr, identify,
identity::{self, ed25519, Keypair},
kad::{self, Mode, PeerRecord, QueryStats, Record, RecordKey},
mdns, noise, ping, relay,
noise, ping, relay,
swarm::NetworkBehaviour,
tcp, upnp, yamux, Multiaddr, PeerId, Swarm, SwarmBuilder,
yamux, Multiaddr, PeerId, Swarm, SwarmBuilder,
};
#[cfg(not(target_arch = "wasm32"))]
use libp2p::{mdns, tcp, upnp};
#[cfg(not(target_arch = "wasm32"))]
use libp2p_webrtc as webrtc;
#[cfg(not(target_arch = "wasm32"))]
use multihash::{self, Hasher};
#[cfg(not(target_arch = "wasm32"))]
use rand::thread_rng;
use semver::Version;
use serde::{Deserialize, Serialize};
use std::{fmt, net::Ipv4Addr, str::FromStr, time::Duration};
#[cfg(not(target_arch = "wasm32"))]
use std::time::Duration;
use std::{fmt, net::Ipv4Addr, str::FromStr};
use tokio::sync::{
mpsc::{self, UnboundedReceiver},
oneshot,
};
#[cfg(target_arch = "wasm32")]
use tokio_with_wasm::alias as tokio;
use tracing::{info, warn};
#[cfg(target_arch = "wasm32")]
use web_time::Duration;

#[cfg(feature = "network-analysis")]
#[cfg(not(target_arch = "wasm32"))]
pub mod analyzer;
mod client;
pub mod configuration;
Expand Down Expand Up @@ -172,10 +184,12 @@ pub struct Behaviour {
kademlia: kad::Behaviour<Store>,
identify: identify::Behaviour,
ping: ping::Behaviour,
#[cfg(not(target_arch = "wasm32"))]
mdns: mdns::tokio::Behaviour,
auto_nat: autonat::Behaviour,
relay_client: relay::client::Behaviour,
dcutr: dcutr::Behaviour,
#[cfg(not(target_arch = "wasm32"))]
upnp: upnp::tokio::Behaviour,
blocked_peers: allow_block_list::Behaviour<BlockedPeers>,
}
Expand Down Expand Up @@ -276,8 +290,12 @@ async fn build_swarm(

// build the Swarm, connecting the lower transport logic with the
// higher layer network behaviour logic
#[cfg(not(target_arch = "wasm32"))]
let tokio_swarm = SwarmBuilder::with_existing_identity(id_keys.clone()).with_tokio();

#[cfg(target_arch = "wasm32")]
let tokio_swarm = SwarmBuilder::with_existing_identity(id_keys.clone()).with_wasm_bindgen();

let mut swarm;

let kad_cfg: kad::Config = kad_config(cfg, genesis_hash);
Expand All @@ -290,12 +308,26 @@ async fn build_swarm(
dcutr: dcutr::Behaviour::new(key.public().to_peer_id()),
kademlia: kad::Behaviour::with_config(key.public().to_peer_id(), kad_store, kad_cfg),
auto_nat: autonat::Behaviour::new(key.public().to_peer_id(), autonat_cfg),
#[cfg(not(target_arch = "wasm32"))]
mdns: mdns::Behaviour::new(mdns::Config::default(), key.public().to_peer_id())?,
#[cfg(not(target_arch = "wasm32"))]
upnp: upnp::tokio::Behaviour::default(),
blocked_peers: allow_block_list::Behaviour::default(),
})
};
#[cfg(target_arch = "wasm32")]
{
swarm = tokio_swarm
.with_other_transport(|key| {
libp2p_webrtc_websys::Transport::new(libp2p_webrtc_websys::Config::new(&key))
})?
.with_relay_client(noise::Config::new, yamux::Config::default)?
.with_behaviour(behaviour)?
.with_swarm_config(|c| generate_config(c, cfg))
.build();
}

#[cfg(not(target_arch = "wasm32"))]
if cfg.ws_transport_enable {
swarm = tokio_swarm
.with_websocket(noise::Config::new, yamux::Config::default)
Expand Down Expand Up @@ -342,6 +374,7 @@ async fn build_swarm(
// From such generated keypair it derives multihash identifier of the local peer.
fn keypair(secret_key: &SecretKey) -> Result<identity::Keypair> {
let keypair = match secret_key {
#[cfg(not(target_arch = "wasm32"))]
// If seed is provided, generate secret key from seed
SecretKey::Seed { seed } => {
let seed_digest = multihash::Sha3_256::digest(seed.as_bytes());
Expand Down
5 changes: 5 additions & 0 deletions core/src/network/p2p/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,15 @@ use libp2p::{
swarm::dial_opts::DialOpts,
Multiaddr, PeerId,
};
#[cfg(not(target_arch = "wasm32"))]
use std::time::{Duration, Instant};
use sysinfo::System;
use tokio::sync::{mpsc::UnboundedSender, oneshot};
#[cfg(target_arch = "wasm32")]
use tokio_with_wasm::alias as tokio;
use tracing::{debug, info, trace};
#[cfg(target_arch = "wasm32")]
use web_time::{Duration, Instant};

use super::{
event_loop::ConnectionEstablishedInfo, is_global, is_multiaddr_global, Command, EventLoop,
Expand Down
Loading

0 comments on commit ab8ba97

Please sign in to comment.