From 9c6961939f62af3d8b3dcd4549a7b20383c8eb02 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Mon, 26 Feb 2024 19:57:00 +0200 Subject: [PATCH] XXX/lightclient: Use unstable backend Signed-off-by: Alexandru Vasile --- subxt/Cargo.toml | 4 ++- subxt/examples/light_client_parachains.rs | 44 ++++++++++++++++------- subxt/src/client/light_client/mod.rs | 28 ++++++++++++++- 3 files changed, 62 insertions(+), 14 deletions(-) diff --git a/subxt/Cargo.toml b/subxt/Cargo.toml index 4a18bb2b41..758b83c160 100644 --- a/subxt/Cargo.toml +++ b/subxt/Cargo.toml @@ -61,7 +61,7 @@ unstable-metadata = [] # Activate this to expose the Light Client functionality. # Note that this feature is experimental and things may break or not work as expected. -unstable-light-client = ["subxt-lightclient", "tokio-stream"] +unstable-light-client = ["subxt-lightclient", "tokio-stream", "tokio"] [dependencies] async-trait = { workspace = true } @@ -118,6 +118,8 @@ getrandom = { workspace = true, optional = true } # Included if "native" feature is enabled tokio-util = { workspace = true, features = ["compat"], optional = true } +tokio = { workspace = true, features = ["macros", "time", "rt-multi-thread"], optional = true } + [dev-dependencies] bitvec = { workspace = true } codec = { workspace = true, features = ["derive", "bit-vec"] } diff --git a/subxt/examples/light_client_parachains.rs b/subxt/examples/light_client_parachains.rs index fde72459ea..e552c6d0a8 100644 --- a/subxt/examples/light_client_parachains.rs +++ b/subxt/examples/light_client_parachains.rs @@ -3,14 +3,14 @@ //! Run: `cargo run --example light_client_parachains --features="unstable-light-client native"`. #![allow(missing_docs)] +use sp_core::crypto::{AccountId32, Ss58Codec}; +use sp_core::ByteArray; +use std::collections::BTreeSet; use std::{iter, num::NonZeroU32}; use subxt::{ client::{LightClient, RawLightClient}, PolkadotConfig, }; -use sp_core::crypto::{AccountId32, Ss58Codec}; -use std::collections::BTreeSet; -use sp_core::ByteArray; // Generate an interface that we can use from the node's metadata. #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] @@ -89,18 +89,38 @@ async fn main() -> Result<(), Box> { raw_light_client.for_chain(parachain_chain_id).await?; // Step 6. Subscribe to the finalized blocks of the chains. - let key = collectives::storage().fellowship_collective().members_iter(); - let mut query = parachain_api.storage().at_latest().await.unwrap().iter(key).await?; - let mut members = BTreeSet::new(); + { + let key = collectives::storage() + .fellowship_collective() + .members_iter(); + let mut query = parachain_api + .storage() + .at_latest() + .await + .unwrap() + .iter(key) + .await?; + let mut members = BTreeSet::new(); + let mut members_by_key = BTreeSet::new(); - while let Some(Ok((id, fellow))) = query.next().await { - let account = AccountId32::from_slice(&id[id.len() - 32..]).unwrap(); + while let Some(Ok((id, fellow))) = query.next().await { + let account = AccountId32::from_slice(&id[id.len() - 32..]).unwrap(); - println!("Fetched member: {} rank {}", account.to_ss58check(), fellow.rank); - if members.contains(&account) { - println!("ERROR: Fetched account twice"); + println!( + "Fetched member: {} rank {}", + account.to_ss58check(), + fellow.rank + ); + if members.contains(&account) { + let cont = members_by_key.contains(&id); + println!( + "ERROR: Fetched account twice. However is the key already inserted? {}", + cont + ); + } + members.insert(account); + members_by_key.insert(id); } - members.insert(account); } Ok(()) diff --git a/subxt/src/client/light_client/mod.rs b/subxt/src/client/light_client/mod.rs index a4b116652e..5d8e723d9f 100644 --- a/subxt/src/client/light_client/mod.rs +++ b/subxt/src/client/light_client/mod.rs @@ -93,7 +93,33 @@ impl RawLightClient { ) -> Result, crate::Error> { let raw_rpc = self.raw_rpc.for_chain(chain_id); let rpc_client = RpcClient::new(raw_rpc.clone()); - let client = OnlineClient::::from_rpc_client(rpc_client).await?; + + use crate::backend::unstable::UnstableBackend; + use std::sync::Arc; + + let (backend, mut driver) = UnstableBackend::builder().build(rpc_client); + + let future = async move { + use futures::StreamExt; + while let Some(val) = driver.next().await { + if let Err(e) = val { + // This is a test; bail if something does wrong and try to + // ensure that the message makes it to some logs. + eprintln!("Error driving unstable backend in tests (will panic): {e}"); + panic!("Error driving unstable backend in tests: {e}"); + } + } + }; + + // The unstable backend needs driving: + #[cfg(feature = "native")] + tokio::spawn(future); + #[cfg(feature = "web")] + wasm_bindgen_futures::spawn_local(future); + + let client = OnlineClient::from_backend(Arc::new(backend)) + .await + .map_err(|e| format!("Cannot construct OnlineClient from backend: {e}"))?; Ok(LightClient { client, chain_id }) }