mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 08:07:58 +00:00
light-client: Add experimental light-client support (#965)
* rpc/types: Decode `SubstrateTxStatus` for substrate and smoldot Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * lightclient: Add light client Error Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * lightclient: Add background task to manage RPC responses Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * lightclient: Implement the light client RPC in subxt Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * subxt: Expose light client under experimental feature-flag Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * artifacts: Add development chain spec for local nodes Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Update cargo lock Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * examples: Add light client example Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Update sp-* crates and smoldot to use git with branch / rev Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Apply cargo fmt Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Fix clippy Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Import hashmap entry Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * lightclient: Fetch spec only if jsonrpsee feature is enabled Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Update subxt/src/rpc/lightclient/background.rs Co-authored-by: Niklas Adolfsson <niklasadolfsson1@gmail.com> * Fix typo Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * artifacts: Update dev chain spec Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * types: Handle storage replies from chainHead_storage Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * artifacts: Add polkadot spec Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * lightclient: Handle RPC error responses Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * examples: Tx basic with light client for local nodes Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * example: Light client coprehensive example for live chains Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * examples: Remove prior light client example Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * feature: Rename experimental to unstable Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * book: Add light client section Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * testing: Fix clippy Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * lightclient: Ignore validated events Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Adjust tests for light-clients and normal clients Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * testing: Keep lightclient variant Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Remove support for chainHead_storage for light client Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Update light client to point to crates.io Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Update sp-crates from crates.io Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Replace Atomic with u64 Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Add LightClientBuilder Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Adjust chainspec with provided bootnodes Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Add potential_relay_chains to light client builder Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Move the light-client to the background task Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Adjust tracing logs Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Update book and example Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Apply cargo fmt Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Remove dev_spec.json artifact Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Examples fix duplicate Cargo.toml Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Use tracing_subscriber crate Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Fix clippy for different features Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Add comment about bootNodes Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Add comment about tracing-sub dependency Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Run integration-tests with light-client Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Feature guard some incompatible tests Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * ci: Enable light-client tests under feature flag Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * ci: Fix git step name Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Adjust flags for testing Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Adjust warnings Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Rename feature flag jsonrpsee-ws to jsonrpsee Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Fix cargo check Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * ci: Run tests on just 2 threads Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Move light-client to subxt/src/client Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Adjust LightClientBuilder Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Use ws_url to construct light client for testing Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Refactor background Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Address feedback Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Remove polkadot.spec and trim sub_id Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Wait for substrate to produce block before connecting light client Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Adjust builder and tests Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Apply fmt Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * ci: Use release for light client testing Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Add single test for light-client Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Wait for more blocks Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Use polkadot endpoint for testing Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Adjust cargo check Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * examples: Remove light client chain connection example Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Adjust cargo.toml section for the old example Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Adjust background task to use usize for subscription Id Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Build bootnodes with serde_json::Value directly Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Make channel between subxt user and subxt background unbounded Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Update subxt/src/client/lightclient/builder.rs Co-authored-by: Niklas Adolfsson <niklasadolfsson1@gmail.com> * Switch to smoldot 0.6.0 from 0.5.0 Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Move testing to `full_client` and `light_client` higher modules Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Remove subscriptionID type Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Remove subxt/integration-testing feature flag Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Adjust wait_for_blocks documentation Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Adjust utils import for testing Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Remove into_iter from builder construction Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> --------- Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> Co-authored-by: Niklas Adolfsson <niklasadolfsson1@gmail.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
pub(crate) use crate::{node_runtime, TestNodeProcess};
|
||||
pub(crate) use crate::{node_runtime, utils::TestNodeProcess};
|
||||
|
||||
use subxt::SubstrateConfig;
|
||||
|
||||
|
||||
@@ -6,11 +6,19 @@ use std::ffi::{OsStr, OsString};
|
||||
use substrate_runner::SubstrateNode;
|
||||
use subxt::{Config, OnlineClient};
|
||||
|
||||
#[cfg(feature = "unstable-light-client")]
|
||||
use subxt::client::{LightClient, LightClientBuilder};
|
||||
|
||||
/// Spawn a local substrate node for testing subxt.
|
||||
pub struct TestNodeProcess<R: Config> {
|
||||
// Keep a handle to the node; once it's dropped the node is killed.
|
||||
_proc: SubstrateNode,
|
||||
|
||||
#[cfg(not(feature = "unstable-light-client"))]
|
||||
client: OnlineClient<R>,
|
||||
|
||||
#[cfg(feature = "unstable-light-client")]
|
||||
client: LightClient<R>,
|
||||
}
|
||||
|
||||
impl<R> TestNodeProcess<R>
|
||||
@@ -26,9 +34,16 @@ where
|
||||
}
|
||||
|
||||
/// Returns the subxt client connected to the running node.
|
||||
#[cfg(not(feature = "unstable-light-client"))]
|
||||
pub fn client(&self) -> OnlineClient<R> {
|
||||
self.client.clone()
|
||||
}
|
||||
|
||||
/// Returns the subxt client connected to the running node.
|
||||
#[cfg(feature = "unstable-light-client")]
|
||||
pub fn client(&self) -> LightClient<R> {
|
||||
self.client.clone()
|
||||
}
|
||||
}
|
||||
|
||||
/// Construct a test node process.
|
||||
@@ -71,8 +86,13 @@ impl TestNodeProcessBuilder {
|
||||
let proc = node_builder.spawn().map_err(|e| e.to_string())?;
|
||||
let ws_url = format!("ws://127.0.0.1:{}", proc.ws_port());
|
||||
|
||||
#[cfg(feature = "unstable-light-client")]
|
||||
let client = build_light_client(&proc).await;
|
||||
|
||||
// Connect to the node with a subxt client:
|
||||
#[cfg(not(feature = "unstable-light-client"))]
|
||||
let client = OnlineClient::from_url(ws_url.clone()).await;
|
||||
|
||||
match client {
|
||||
Ok(client) => Ok(TestNodeProcess {
|
||||
_proc: proc,
|
||||
@@ -82,3 +102,30 @@ impl TestNodeProcessBuilder {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable-light-client")]
|
||||
async fn build_light_client<R: Config>(proc: &SubstrateNode) -> Result<LightClient<R>, String> {
|
||||
// RPC endpoint.
|
||||
let ws_url = format!("ws://127.0.0.1:{}", proc.ws_port());
|
||||
|
||||
// Step 1. Wait for a few blocks to be produced using the subxt client.
|
||||
let client = OnlineClient::<R>::from_url(ws_url.clone())
|
||||
.await
|
||||
.map_err(|err| format!("Failed to connect to node rpc at {ws_url}: {err}"))?;
|
||||
|
||||
super::wait_for_blocks(&client).await;
|
||||
|
||||
// Step 2. Construct the light client.
|
||||
// P2p bootnode.
|
||||
let bootnode = format!(
|
||||
"/ip4/127.0.0.1/tcp/{}/p2p/{}",
|
||||
proc.p2p_port(),
|
||||
proc.p2p_address()
|
||||
);
|
||||
|
||||
LightClientBuilder::new()
|
||||
.bootnodes([bootnode.as_str()])
|
||||
.build_from_url(ws_url.as_str())
|
||||
.await
|
||||
.map_err(|e| format!("Failed to construct light client {}", e.to_string()))
|
||||
}
|
||||
|
||||
@@ -7,8 +7,20 @@ use subxt::{client::OnlineClientT, Config};
|
||||
/// Wait for blocks to be produced before running tests. Waiting for two blocks
|
||||
/// (the genesis block and another one) seems to be enough to allow tests
|
||||
/// like `dry_run_passes` to work properly.
|
||||
///
|
||||
/// If the "unstable-light-client" feature flag is enabled, this will wait for
|
||||
/// 5 blocks instead of two. The light client needs the extra blocks to avoid
|
||||
/// errors caused by loading information that is not available in the first 2 blocks
|
||||
/// (`Failed to load the block weight for block`).
|
||||
pub async fn wait_for_blocks<C: Config>(api: &impl OnlineClientT<C>) {
|
||||
let mut sub = api.rpc().subscribe_all_block_headers().await.unwrap();
|
||||
sub.next().await;
|
||||
sub.next().await;
|
||||
|
||||
#[cfg(feature = "unstable-light-client")]
|
||||
{
|
||||
sub.next().await;
|
||||
sub.next().await;
|
||||
sub.next().await;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user