Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add light client platform WASM compatible #1026

Merged
merged 39 commits into from
Jul 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
a1a6178
Cargo update in prep for wasm build
lexnv Jun 23, 2023
4f0f69e
Add light client test
lexnv Jun 23, 2023
467a4e8
Implement low level socket
lexnv Jun 23, 2023
52ee64d
Add native platform primitives
lexnv Jun 23, 2023
f2b3547
Add wasm platform primitives
lexnv Jun 23, 2023
9a52898
Implement smoldot platform
lexnv Jun 23, 2023
ebb0ba8
Adjust code to use custom platform
lexnv Jun 23, 2023
a8576ac
Adjust feature flags
lexnv Jun 26, 2023
4dec3b7
tests: Adjust wasm endpoint to accept ws for p2p
lexnv Jun 26, 2023
2e660bb
Adjust wasm socket
lexnv Jun 26, 2023
f9b0834
Book mention of wasm
lexnv Jun 26, 2023
d23b398
ci: Propagate env variable properly
lexnv Jun 26, 2023
03407cd
subxt: Revert to native feature flags
lexnv Jun 26, 2023
540172f
cli: Use tokio rt-multi-thread feature
lexnv Jun 26, 2023
b25ce5c
subxt: Add tokio feature flags for native platform
lexnv Jun 26, 2023
ad33620
wasm: Use polkadot live for wasm testing
lexnv Jun 26, 2023
8ba2e0f
wasm: Add support for DNS p2p addresses
lexnv Jun 26, 2023
4452fc3
wasm: Disable logs
lexnv Jun 26, 2023
1615313
wasm: Run wasm test for firefox driver
lexnv Jun 26, 2023
680aadd
Merge remote-tracking branch 'origin/master' into lexnv/light_client_…
lexnv Jun 26, 2023
1e8c949
wasm: Reenable chrome driver
lexnv Jun 26, 2023
3a65573
Move lightclient RPC to dedicated crate for better feature flags and …
lexnv Jun 27, 2023
5e850aa
Use subxt-lightclient low level RPC crate
lexnv Jun 27, 2023
2b99fd4
Apply cargo fmt
lexnv Jun 27, 2023
a3eedc6
Enable default:native feature for cargo check
lexnv Jun 27, 2023
2dc1384
ci: Extra step for subxt-lightclient similar to signer crate
lexnv Jun 27, 2023
6223e05
Remove native platform code and use smoldot instead
lexnv Jun 28, 2023
33880cc
codegen: Enable tokio/multi-threads
lexnv Jun 29, 2023
290651d
lightclient: Refactor modules
lexnv Jul 17, 2023
a58f04f
Adjust testing crates
lexnv Jul 17, 2023
d119ae6
ci: Run light-client WASM tests
lexnv Jul 17, 2023
95a9c8f
wasm-rpc: Remove light-client imports
lexnv Jul 17, 2023
085d3dd
Merge remote-tracking branch 'origin/master' into lexnv/light_client_…
lexnv Jul 17, 2023
4d4f085
testing: Update wasm cargo.lock files
lexnv Jul 17, 2023
1293210
ci: Spawn substrate node with deterministic p2p address for WASM tests
lexnv Jul 17, 2023
a781435
wasm_socket: Use rc and refcell
lexnv Jul 17, 2023
7178f55
Merge remote-tracking branch 'origin/master' into lexnv/light_client_…
lexnv Jul 17, 2023
6c46995
wasm_socket: Switch back to Arc<Mutex<>>
lexnv Jul 18, 2023
e172bbb
Add comments
lexnv Jul 18, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 21 additions & 3 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ env:
CARGO_TERM_COLOR: always
# TODO: Currently pointing at latest substrate; is there a suitable binary we can pin to here?
SUBSTRATE_URL: https://releases.parity.io/substrate/x86_64-debian:bullseye/latest/substrate/substrate
# Increase wasm test timeout from 20 seconds (default) to 1 minute.
WASM_BINDGEN_TEST_TIMEOUT: 60

jobs:
build:
Expand Down Expand Up @@ -70,9 +72,13 @@ jobs:
- name: Cargo check subxt-signer
run: cargo check -p subxt-signer

# We can't enable web features here, so no cargo hack.
- name: Cargo check subxt-lightclient
run: cargo check -p subxt-lightclient

# Next, check each other package in isolation.
- name: Cargo hack; check each feature/crate on its own
run: cargo hack --exclude subxt --exclude subxt-signer --exclude-all-features --each-feature check --workspace
run: cargo hack --exclude subxt --exclude subxt-signer --exclude subxt-lightclient --exclude-all-features --each-feature check --workspace

fmt:
name: Cargo fmt
Expand Down Expand Up @@ -259,11 +265,23 @@ jobs:

- name: Run subxt WASM tests
run: |
substrate --dev --tmp > /dev/null 2>&1 &
# `listen-addr` is used to configure p2p to accept websocket connections instead of TCP.
# `node-key` provides a deterministic p2p address.
substrate --dev --node-key 0000000000000000000000000000000000000000000000000000000000000001 --listen-addr /ip4/0.0.0.0/tcp/30333/ws > /dev/null 2>&1 &
wasm-pack test --headless --firefox
wasm-pack test --headless --chrome
pkill substrate
working-directory: testing/wasm-rpc-tests

- name: Run subxt-lightclient WASM tests
run: |
# `listen-addr` is used to configure p2p to accept websocket connections instead of TCP.
# `node-key` provides a deterministic p2p address.
substrate --dev --node-key 0000000000000000000000000000000000000000000000000000000000000001 --listen-addr /ip4/0.0.0.0/tcp/30333/ws > /dev/null 2>&1 &
wasm-pack test --headless --firefox
wasm-pack test --headless --chrome
pkill substrate
working-directory: testing/wasm-tests
working-directory: testing/wasm-lightclient-tests

- name: Run subxt-signer WASM tests
run: |
Expand Down
40 changes: 37 additions & 3 deletions Cargo.lock

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

18 changes: 16 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
members = [
"cli",
"codegen",
"lightclient",
"testing/substrate-runner",
"testing/test-runtime",
"testing/integration-tests",
Expand All @@ -16,7 +17,8 @@ members = [
# exclusive feature flags and thus can't compile with the
# workspace:
exclude = [
"testing/wasm-tests",
"testing/wasm-rpc-tests",
"testing/wasm-lightclient-tests",
"signer/wasm-tests",
"examples/wasm-example"
]
Expand Down Expand Up @@ -67,7 +69,7 @@ serde = { version = "1.0.171" }
serde_json = { version = "1.0.100" }
syn = { version = "2.0.15", features = ["full", "extra-traits"] }
thiserror = "1.0.40"
tokio = { version = "1.29", features = ["macros", "time", "rt-multi-thread"] }
tokio = { version = "1.29", default-features = false }
tracing = "0.1.34"
tracing-wasm = "0.2.1"
tracing-subscriber = "0.3.17"
Expand All @@ -77,10 +79,21 @@ wasm-bindgen-test = "0.3.24"
which = "4.4.0"

# Light client support:
smoldot = { version = "0.8.0", default-features = false }
smoldot-light = { version = "0.6.0", default-features = false }
tokio-stream = "0.1.14"
futures-util = "0.3.28"

# Light client wasm:
web-sys = { version = "0.3.61", features = ["BinaryType", "CloseEvent", "MessageEvent", "WebSocket"] }
wasm-bindgen = "0.2.84"
send_wrapper = "0.6.0"
js-sys = "0.3.61"
wasm-bindgen-futures = "0.4.19"
futures-timer = "3"
instant = { version = "0.1.12", default-features = false }
tokio-util = "0.7.8"

# Substrate crates:
sp-core = { version = "21.0.0", default-features = false }
sp-core-hashing = "9.0.0"
Expand All @@ -94,6 +107,7 @@ subxt-macro = { version = "0.29.0", path = "macro" }
subxt-metadata = { version = "0.29.0", path = "metadata" }
subxt-codegen = { version = "0.29.0", path = "codegen" }
subxt-signer = { version = "0.29.0", path = "signer" }
subxt-lightclient = { version = "0.29.0", path = "lightclient", default-features = false }
test-runtime = { path = "testing/test-runtime" }
substrate-runner = { path = "testing/substrate-runner" }

Expand Down
2 changes: 1 addition & 1 deletion cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ scale-info = { workspace = true }
scale-value = { workspace = true }
syn = { workspace = true }
jsonrpsee = { workspace = true, features = ["async-client", "client-ws-transport", "http-client"] }
tokio = { workspace = true }
tokio = { workspace = true, features = ["rt-multi-thread"] }
2 changes: 1 addition & 1 deletion codegen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ scale-info = { workspace = true }
subxt-metadata = { workspace = true }
jsonrpsee = { workspace = true, features = ["async-client", "client-ws-transport", "http-client"] }
hex = { workspace = true }
tokio = { workspace = true }
tokio = { workspace = true, features = ["rt-multi-thread"] }
thiserror = { workspace = true }

[dev-dependencies]
Expand Down
86 changes: 86 additions & 0 deletions lightclient/Cargo.toml
Copy link
Collaborator

@jsdw jsdw Jul 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea to have this as a separate crate!

Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
[package]
name = "subxt-lightclient"
version.workspace = true
authors.workspace = true
edition.workspace = true
rust-version.workspace = true
publish = true

license.workspace = true
readme = "../README.md"
repository.workspace = true
documentation.workspace = true
homepage.workspace = true
description = "Light Client for chain interaction"
keywords = ["parity", "substrate", "blockchain"]

[features]
default = ["native"]

# Enable this for native (ie non web/wasm builds).
# Exactly 1 of "web" and "native" is expected.
native = [
"smoldot-light/std",
"tokio-stream",
"tokio/sync",
"tokio/rt",
"futures-util",
]

# Enable this for web/wasm builds.
# Exactly 1 of "web" and "native" is expected.
web = [
"getrandom/js",

"smoldot",
"smoldot-light",
"tokio-stream",
"tokio/sync",
"futures-util",

# For the light-client platform.
"wasm-bindgen-futures",
"futures-timer/wasm-bindgen",
"instant/wasm-bindgen",

# For websocket.
"js-sys",
"send_wrapper",
"web-sys",
"wasm-bindgen",
]

[dependencies]
futures = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true, features = ["raw_value"] }
thiserror = { workspace = true }
tracing = { workspace = true }

# Light client support:
smoldot = { workspace = true, optional = true }
smoldot-light = { workspace = true, optional = true }
either = { workspace = true, optional = true }
tokio = { workspace = true, optional = true }
tokio-stream = { workspace = true, optional = true }
futures-util = { workspace = true, optional = true }
js-sys = { workspace = true, optional = true }
send_wrapper = { workspace = true, optional = true }
web-sys = { workspace = true, optional = true }
wasm-bindgen = { workspace = true, optional = true }
wasm-bindgen-futures = { workspace = true, optional = true }
jsdw marked this conversation as resolved.
Show resolved Hide resolved
futures-timer = { workspace = true, optional = true }
instant = { workspace = true, optional = true }
tokio-util = { workspace = true, optional = true }

# Included if "web" feature is enabled, to enable its js feature.
getrandom = { workspace = true, optional = true }

[profile.dev.package.smoldot-light]
opt-level = 2
[profile.test.package.smoldot-light]
opt-level = 2
[profile.dev.package.smoldot]
opt-level = 2
[profile.test.package.smoldot]
opt-level = 2
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,17 @@ use futures::stream::StreamExt;
use futures_util::future::{self, Either};
use serde::Deserialize;
use serde_json::value::RawValue;
use std::{collections::HashMap, str::FromStr, sync::Arc};
use std::{collections::HashMap, str::FromStr};
use tokio::sync::{mpsc, oneshot};

use super::LightClientError;
use smoldot_light::{platform::default::DefaultPlatform as Platform, ChainId};
use super::platform::PlatformType;
use super::LightClientRpcError;
use smoldot_light::ChainId;

const LOG_TARGET: &str = "light-client-background";

/// The response of an RPC method.
pub type MethodResponse = Result<Box<RawValue>, LightClientError>;
pub type MethodResponse = Result<Box<RawValue>, LightClientRpcError>;

/// Message protocol between the front-end client that submits the RPC requests
/// and the backend handler that produces responses from the chain.
Expand Down Expand Up @@ -50,7 +51,7 @@ pub enum FromSubxt {
/// Background task data.
pub struct BackgroundTask {
/// Smoldot light client implementation that leverages the exposed platform.
client: smoldot_light::Client<Arc<Platform>>,
client: smoldot_light::Client<PlatformType>,
/// The ID of the chain used to identify the chain protocol (ie. substrate).
///
/// Note: A single chain is supported for a client. This aligns with the subxt's
Expand Down Expand Up @@ -79,7 +80,7 @@ pub struct BackgroundTask {

impl BackgroundTask {
/// Constructs a new [`BackgroundTask`].
pub fn new(client: smoldot_light::Client<Arc<Platform>>, chain_id: ChainId) -> BackgroundTask {
pub fn new(client: smoldot_light::Client<PlatformType>, chain_id: ChainId) -> BackgroundTask {
BackgroundTask {
client,
chain_id,
Expand Down Expand Up @@ -127,7 +128,7 @@ impl BackgroundTask {

// Send the error back to frontend.
if sender
.send(Err(LightClientError::Request(err.to_string())))
.send(Err(LightClientRpcError::Request(err.to_string())))
.is_err()
{
tracing::warn!(
Expand Down Expand Up @@ -167,7 +168,7 @@ impl BackgroundTask {

// Send the error back to frontend.
if sub_id
.send(Err(LightClientError::Request(err.to_string())))
.send(Err(LightClientRpcError::Request(err.to_string())))
.is_err()
{
tracing::warn!(
Expand All @@ -191,7 +192,7 @@ impl BackgroundTask {

if let Some(sender) = self.requests.remove(&id) {
if sender
.send(Err(LightClientError::Request(error.to_string())))
.send(Err(LightClientRpcError::Request(error.to_string())))
.is_err()
{
tracing::warn!(
Expand All @@ -201,7 +202,7 @@ impl BackgroundTask {
}
} else if let Some((sub_id_sender, _)) = self.id_to_subscription.remove(&id) {
if sub_id_sender
.send(Err(LightClientError::Request(error.to_string())))
.send(Err(LightClientRpcError::Request(error.to_string())))
.is_err()
{
tracing::warn!(
Expand Down
Loading
Loading