Merge remote-tracking branch 'origin/master' into lexnv/update-smoldot

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
This commit is contained in:
Alexandru Vasile
2024-04-03 19:05:40 +03:00
190 changed files with 27843 additions and 18050 deletions
+3 -3
View File
@@ -12,6 +12,6 @@ homepage.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
scale-info = { workspace = true, features = ["bit-vec"] }
frame-metadata = { workspace = true }
codec = { package = "parity-scale-codec", workspace = true, features = ["derive", "bit-vec"] }
scale-info = { workspace = true, features = ["std", "bit-vec"] }
frame-metadata = { workspace = true, features = ["decode", "current"] }
codec = { package = "parity-scale-codec", workspace = true, features = ["std", "derive", "bit-vec"] }
+1 -1
View File
@@ -34,7 +34,7 @@ scale-info = { workspace = true, features = ["bit-vec"] }
sp-core = { workspace = true }
syn = { workspace = true }
subxt = { workspace = true, features = ["unstable-metadata", "native", "jsonrpsee", "substrate-compat"] }
subxt-signer = { workspace = true }
subxt-signer = { workspace = true, features = ["default"] }
subxt-codegen = { workspace = true }
subxt-metadata = { workspace = true }
test-runtime = { workspace = true }
@@ -14,7 +14,9 @@ use subxt::{
FollowEvent, Initialized, MethodResponse, RuntimeEvent, RuntimeVersionEvent, StorageQuery,
StorageQueryType,
},
utils::AccountId32,
config::Hasher,
utils::{AccountId32, MultiAddress},
SubstrateConfig,
};
use subxt_signer::sr25519::dev;
@@ -32,7 +34,7 @@ async fn chainhead_unstable_follow() {
assert_eq!(
event,
FollowEvent::Initialized(Initialized {
finalized_block_hash,
finalized_block_hashes: vec![finalized_block_hash],
finalized_block_runtime: None,
})
);
@@ -47,10 +49,10 @@ async fn chainhead_unstable_follow() {
assert_matches!(
event,
FollowEvent::Initialized(init) => {
assert_eq!(init.finalized_block_hash, finalized_block_hash);
assert_eq!(init.finalized_block_hashes, vec![finalized_block_hash]);
if let Some(RuntimeEvent::Valid(RuntimeVersionEvent { spec })) = init.finalized_block_runtime {
assert_eq!(spec.spec_version, runtime_version.spec_version);
assert_eq!(spec.transaction_version, runtime_version.transaction_version);
assert_eq!(spec.spec_version, runtime_version.spec_version());
assert_eq!(spec.transaction_version, runtime_version.transaction_version());
} else {
panic!("runtime details not provided with init event, got {:?}", init.finalized_block_runtime);
}
@@ -66,7 +68,7 @@ async fn chainhead_unstable_body() {
let mut blocks = rpc.chainhead_unstable_follow(false).await.unwrap();
let event = blocks.next().await.unwrap().unwrap();
let hash = match event {
FollowEvent::Initialized(init) => init.finalized_block_hash,
FollowEvent::Initialized(init) => init.finalized_block_hashes.last().unwrap().clone(),
_ => panic!("Unexpected event"),
};
let sub_id = blocks.subscription_id().unwrap();
@@ -95,7 +97,7 @@ async fn chainhead_unstable_header() {
let mut blocks = rpc.chainhead_unstable_follow(false).await.unwrap();
let event = blocks.next().await.unwrap().unwrap();
let hash = match event {
FollowEvent::Initialized(init) => init.finalized_block_hash,
FollowEvent::Initialized(init) => init.finalized_block_hashes.last().unwrap().clone(),
_ => panic!("Unexpected event"),
};
let sub_id = blocks.subscription_id().unwrap();
@@ -123,7 +125,7 @@ async fn chainhead_unstable_storage() {
let mut blocks = rpc.chainhead_unstable_follow(false).await.unwrap();
let event = blocks.next().await.unwrap().unwrap();
let hash = match event {
FollowEvent::Initialized(init) => init.finalized_block_hash,
FollowEvent::Initialized(init) => init.finalized_block_hashes.last().unwrap().clone(),
_ => panic!("Unexpected event"),
};
let sub_id = blocks.subscription_id().unwrap();
@@ -168,7 +170,7 @@ async fn chainhead_unstable_call() {
let mut blocks = rpc.chainhead_unstable_follow(true).await.unwrap();
let event = blocks.next().await.unwrap().unwrap();
let hash = match event {
FollowEvent::Initialized(init) => init.finalized_block_hash,
FollowEvent::Initialized(init) => init.finalized_block_hashes.last().unwrap().clone(),
_ => panic!("Unexpected event"),
};
let sub_id = blocks.subscription_id().unwrap();
@@ -205,7 +207,7 @@ async fn chainhead_unstable_unpin() {
let mut blocks = rpc.chainhead_unstable_follow(true).await.unwrap();
let event = blocks.next().await.unwrap().unwrap();
let hash = match event {
FollowEvent::Initialized(init) => init.finalized_block_hash,
FollowEvent::Initialized(init) => init.finalized_block_hashes.last().unwrap().clone(),
_ => panic!("Unexpected event"),
};
let sub_id = blocks.subscription_id().unwrap();
@@ -261,7 +263,7 @@ async fn transaction_unstable_submit_and_watch() {
let tx_bytes = ctx
.client()
.tx()
.create_signed_with_nonce(&payload, &dev::alice(), 0, Default::default())
.create_signed_offline(&payload, &dev::alice(), Default::default())
.unwrap()
.into_encoded();
@@ -309,3 +311,108 @@ async fn next_operation_event<
panic!("Cannot find operation related event after {NUM_EVENTS} produced events");
}
#[tokio::test]
async fn transaction_unstable_broadcast() {
let bob = dev::bob();
let bob_address: MultiAddress<AccountId32, u32> = bob.public_key().into();
let ctx = test_context().await;
let api = ctx.client();
let rpc = ctx.unstable_rpc_methods().await;
let tx = node_runtime::tx()
.balances()
.transfer_allow_death(bob_address.clone(), 10_001);
let tx_bytes = ctx
.client()
.tx()
.create_signed_offline(&tx, &dev::alice(), Default::default())
.unwrap()
.into_encoded();
let tx_hash = <SubstrateConfig as subxt::Config>::Hasher::hash(&tx_bytes[2..]);
// Subscribe to finalized blocks.
let mut finalized_sub = api.blocks().subscribe_finalized().await.unwrap();
// Expect the tx to be encountered in a maximum number of blocks.
let mut num_blocks: usize = 10;
// Submit the transaction.
let _operation_id = rpc
.transaction_unstable_broadcast(&tx_bytes)
.await
.unwrap()
.expect("Server is not overloaded by 1 tx; qed");
while let Some(finalized) = finalized_sub.next().await {
let finalized = finalized.unwrap();
// Started with positive, should not overflow.
num_blocks = num_blocks.saturating_sub(1);
if num_blocks == 0 {
panic!("Did not find the tx in due time");
}
let extrinsics = finalized.extrinsics().await.unwrap();
let block_extrinsics = extrinsics
.iter()
.map(|res| res.unwrap())
.collect::<Vec<_>>();
let Some(ext) = block_extrinsics
.iter()
.find(|ext| <SubstrateConfig as subxt::Config>::Hasher::hash(ext.bytes()) == tx_hash)
else {
continue;
};
let ext = ext
.as_extrinsic::<node_runtime::balances::calls::types::TransferAllowDeath>()
.unwrap()
.unwrap();
assert_eq!(ext.value, 10_001);
return;
}
}
#[tokio::test]
async fn transaction_unstable_stop() {
let bob = dev::bob();
let bob_address: MultiAddress<AccountId32, u32> = bob.public_key().into();
let ctx = test_context().await;
let rpc = ctx.unstable_rpc_methods().await;
// Cannot stop an operation that was not started.
let _err = rpc
.transaction_unstable_stop("non-existent-operation-id")
.await
.unwrap_err();
// Submit a transaction and stop it.
let tx = node_runtime::tx()
.balances()
.transfer_allow_death(bob_address.clone(), 10_001);
let tx_bytes = ctx
.client()
.tx()
.create_signed_offline(&tx, &dev::alice(), Default::default())
.unwrap()
.into_encoded();
// Submit the transaction.
let operation_id = rpc
.transaction_unstable_broadcast(&tx_bytes)
.await
.unwrap()
.expect("Server is not overloaded by 1 tx; qed");
let _ = rpc.transaction_unstable_stop(&operation_id).await.unwrap();
// Cannot stop it twice.
let _err = rpc
.transaction_unstable_stop(&operation_id)
.await
.unwrap_err();
}
@@ -1,214 +0,0 @@
// Copyright 2019-2023 Parity Technologies (UK) Ltd.
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
// see LICENSE for license details.
use frame_metadata::{
v15::{ExtrinsicMetadata, RuntimeMetadataV15},
RuntimeMetadataPrefixed,
};
use scale_info::{meta_type, IntoPortable, PortableRegistry, Registry, TypeInfo};
use subxt_codegen::CodegenBuilder;
use syn::__private::quote;
fn generate_runtime_interface_from_metadata(metadata: RuntimeMetadataPrefixed) -> String {
// Generate a runtime interface from the provided metadata.
let metadata = metadata
.try_into()
.expect("frame_metadata should be convertible into Metadata");
CodegenBuilder::new()
.no_docs()
.generate(metadata)
.expect("API generation must be valid")
.to_string()
}
fn generate_runtime_interface_with_type_registry<F>(f: F) -> String
where
F: Fn(&mut scale_info::Registry),
{
#[derive(TypeInfo)]
struct Runtime;
#[derive(TypeInfo)]
enum RuntimeCall {}
#[derive(TypeInfo)]
enum RuntimeEvent {}
#[derive(TypeInfo)]
pub enum DispatchError {}
// We need these types for codegen to work:
let mut registry = scale_info::Registry::new();
let ty = registry.register_type(&meta_type::<Runtime>());
registry.register_type(&meta_type::<RuntimeCall>());
registry.register_type(&meta_type::<RuntimeEvent>());
registry.register_type(&meta_type::<DispatchError>());
// Allow custom types to be added for testing:
f(&mut registry);
let extrinsic = ExtrinsicMetadata {
ty: meta_type::<()>(),
version: 0,
signed_extensions: vec![],
}
.into_portable(&mut registry);
let metadata = RuntimeMetadataV15 {
types: registry.into(),
pallets: Vec::new(),
extrinsic,
ty,
apis: vec![],
};
let metadata = RuntimeMetadataPrefixed::from(metadata);
generate_runtime_interface_from_metadata(metadata)
}
#[test]
fn dupe_types_do_not_overwrite_each_other() {
let interface = generate_runtime_interface_with_type_registry(|registry| {
// Now we duplicate some types with same type info. We need two unique types here,
// and can't just add one type to the registry twice, because the registry knows if
// type IDs are the same.
enum Foo {}
impl TypeInfo for Foo {
type Identity = Self;
fn type_info() -> scale_info::Type {
scale_info::Type::builder()
.path(scale_info::Path::new("DuplicateType", "dupe_mod"))
.variant(
scale_info::build::Variants::new()
.variant("FirstDupeTypeVariant", |builder| builder.index(0)),
)
}
}
enum Bar {}
impl TypeInfo for Bar {
type Identity = Self;
fn type_info() -> scale_info::Type {
scale_info::Type::builder()
.path(scale_info::Path::new("DuplicateType", "dupe_mod"))
.variant(
scale_info::build::Variants::new()
.variant("SecondDupeTypeVariant", |builder| builder.index(0)),
)
}
}
registry.register_type(&meta_type::<Foo>());
registry.register_type(&meta_type::<Bar>());
});
assert!(interface.contains("DuplicateType"));
assert!(interface.contains("FirstDupeTypeVariant"));
assert!(interface.contains("DuplicateType2"));
assert!(interface.contains("SecondDupeTypeVariant"));
}
#[test]
fn generic_types_overwrite_each_other() {
let interface = generate_runtime_interface_with_type_registry(|registry| {
// If we have two types mentioned in the registry that have generic params,
// only one type will be output (the codegen assumes that the generic param will disambiguate)
enum Foo {}
impl TypeInfo for Foo {
type Identity = Self;
fn type_info() -> scale_info::Type {
scale_info::Type::builder()
.path(scale_info::Path::new("DuplicateType", "dupe_mod"))
.type_params([scale_info::TypeParameter::new("T", Some(meta_type::<u8>()))])
.variant(scale_info::build::Variants::new())
}
}
enum Bar {}
impl TypeInfo for Bar {
type Identity = Self;
fn type_info() -> scale_info::Type {
scale_info::Type::builder()
.path(scale_info::Path::new("DuplicateType", "dupe_mod"))
.type_params([scale_info::TypeParameter::new("T", Some(meta_type::<u8>()))])
.variant(scale_info::build::Variants::new())
}
}
registry.register_type(&meta_type::<Foo>());
registry.register_type(&meta_type::<Bar>());
});
assert!(interface.contains("DuplicateType"));
// We do _not_ expect this to exist, since a generic is present on the type:
assert!(!interface.contains("DuplicateType2"));
}
#[test]
fn more_than_1_generic_parameters_work() {
#[allow(unused)]
#[derive(TypeInfo)]
struct Foo<T, U, V, W> {
a: T,
b: U,
c: V,
d: W,
}
#[allow(unused)]
#[derive(TypeInfo)]
struct Bar {
p: Foo<u32, u32, u64, u128>,
q: Foo<u8, u8, u8, u8>,
}
let mut registry = Registry::new();
registry.register_type(&meta_type::<Bar>());
let portable_types: PortableRegistry = registry.into();
let type_gen = subxt_codegen::TypeGenerator::new(
&portable_types,
"root",
Default::default(),
Default::default(),
CratePath::default(),
false,
);
let types = type_gen.generate_types_mod().unwrap();
let generated_mod = quote::quote!( #types);
let expected_mod = quote::quote! {
pub mod root {
use super::root;
pub mod integration_tests {
use super::root;
pub mod codegen {
use super::root;
pub mod codegen_tests {
use super::root;
pub struct Bar {
pub p: root::integration_tests::codegen::codegen_tests::Foo<
::core::primitive::u32,
::core::primitive::u32,
::core::primitive::u64,
::core::primitive::u128
>,
pub q: root::integration_tests::codegen::codegen_tests::Foo<
::core::primitive::u8,
::core::primitive::u8,
::core::primitive::u8,
::core::primitive::u8
>,
}
pub struct Foo<_0, _1, _2, _3> {
pub a: _0,
pub b: _1,
pub c: _2,
pub d: _3,
}
}
}
}
}
};
assert_eq!(generated_mod.to_string(), expected_mod.to_string());
}
@@ -4,7 +4,7 @@
use codec::Decode;
use regex::Regex;
use subxt_codegen::{ syn, CodegenBuilder };
use subxt_codegen::{syn, CodegenBuilder};
use subxt_metadata::Metadata;
fn load_test_metadata() -> Metadata {
@@ -14,5 +14,4 @@
#[allow(clippy::all)]
mod polkadot;
mod codegen_tests;
mod documentation;
File diff suppressed because one or more lines are too long
@@ -102,7 +102,6 @@ impl ContractsTestContext {
.find_first::<system::events::ExtrinsicSuccess>()?
.ok_or_else(|| Error::Other("Failed to find a ExtrinsicSuccess event".into()))?;
tracing::info!(" Block hash: {:?}", events.block_hash());
tracing::info!(" Code hash: {:?}", code_stored.code_hash);
tracing::info!(" Contract address: {:?}", instantiated.contract);
Ok((code_stored.code_hash, instantiated.contract))
@@ -2,15 +2,10 @@
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
// see LICENSE for license details.
#[cfg(test)]
mod blocks;
#[cfg(test)]
mod client;
#[cfg(test)]
mod codegen;
mod frame;
#[cfg(test)]
mod metadata;
#[cfg(test)]
mod runtime_api;
#[cfg(test)]
mod storage;
@@ -56,10 +56,6 @@ async fn storage_map_lookup() -> Result<(), subxt::Error> {
Ok(())
}
// This fails until the fix in https://github.com/paritytech/subxt/pull/458 is introduced.
// Here we create a key that looks a bit like a StorageNMap key, but should in fact be
// treated as a StorageKey (ie we should hash both values together with one hasher, rather
// than hash both values separately, or ignore the second value).
#[tokio::test]
async fn storage_n_mapish_key_is_properly_created() -> Result<(), subxt::Error> {
use codec::Encode;
@@ -73,18 +69,21 @@ async fn storage_n_mapish_key_is_properly_created() -> Result<(), subxt::Error>
.session()
.key_owner(KeyTypeId([1, 2, 3, 4]), [5u8, 6, 7, 8]);
let actual_key_bytes = api.storage().address_bytes(&actual_key)?;
// Let's manually hash to what we assume it should be and compare:
let expected_key_bytes = {
// Hash the prefix to the storage entry:
let mut bytes = sp_core::twox_128("Session".as_bytes()).to_vec();
bytes.extend(&sp_core::twox_128("KeyOwner".as_bytes())[..]);
// twox64_concat a *tuple* of the args expected:
let suffix = (KeyTypeId([1, 2, 3, 4]), vec![5u8, 6, 7, 8]).encode();
bytes.extend(sp_core::twox_64(&suffix));
bytes.extend(&suffix);
// Both keys, use twox64_concat hashers:
let key1 = KeyTypeId([1, 2, 3, 4]).encode();
let key2 = vec![5u8, 6, 7, 8].encode();
bytes.extend(sp_core::twox_64(&key1));
bytes.extend(&key1);
bytes.extend(sp_core::twox_64(&key2));
bytes.extend(&key2);
bytes
};
dbg!(&expected_key_bytes);
assert_eq!(actual_key_bytes, expected_key_bytes);
Ok(())
@@ -167,9 +166,9 @@ async fn storage_partial_lookup() -> Result<(), subxt::Error> {
let addr_bytes = api.storage().address_bytes(&addr)?;
let mut results = api.storage().at_latest().await?.iter(addr).await?;
let mut approvals = Vec::new();
while let Some(Ok((key, value))) = results.next().await {
assert!(key.starts_with(&addr_bytes));
approvals.push(value);
while let Some(Ok(kv)) = results.next().await {
assert!(kv.key_bytes.starts_with(&addr_bytes));
approvals.push(kv.value);
}
assert_eq!(approvals.len(), assets.len());
let mut amounts = approvals.iter().map(|a| a.amount).collect::<Vec<_>>();
@@ -188,9 +187,10 @@ async fn storage_partial_lookup() -> Result<(), subxt::Error> {
let mut results = api.storage().at_latest().await?.iter(addr).await?;
let mut approvals = Vec::new();
while let Some(Ok((key, value))) = results.next().await {
assert!(key.starts_with(&addr_bytes));
approvals.push(value);
while let Some(Ok(kv)) = results.next().await {
assert!(kv.key_bytes.starts_with(&addr_bytes));
assert!(kv.keys.decoded().is_ok());
approvals.push(kv.value);
}
assert_eq!(approvals.len(), 1);
assert_eq!(approvals[0].amount, amount);
@@ -29,13 +29,10 @@
use crate::utils::node_runtime;
use codec::Compact;
use subxt::{
client::{LightClient, LightClientBuilder, OnlineClientT},
config::PolkadotConfig,
};
use subxt::{client::OnlineClient, config::PolkadotConfig, lightclient::LightClient};
use subxt_metadata::Metadata;
type Client = LightClient<PolkadotConfig>;
type Client = OnlineClient<PolkadotConfig>;
// Check that we can subscribe to non-finalized blocks.
async fn non_finalized_headers_subscription(api: &Client) -> Result<(), subxt::Error> {
@@ -167,11 +164,13 @@ async fn dynamic_events(api: &Client) -> Result<(), subxt::Error> {
#[tokio::test]
async fn light_client_testing() -> Result<(), subxt::Error> {
tracing_subscriber::fmt::init();
let now = std::time::Instant::now();
let api: LightClient<PolkadotConfig> = LightClientBuilder::new()
.build_from_url("wss://rpc.polkadot.io:443")
.await?;
let chainspec = subxt::utils::fetch_chainspec_from_rpc_node("wss://rpc.polkadot.io:443")
.await
.unwrap();
let (_lc, rpc) = LightClient::relay_chain(chainspec.get())?;
let api = Client::from_rpc_client(rpc).await?;
println!("Light client initialization took {:?}\n", now.elapsed());
@@ -11,9 +11,6 @@ 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.
@@ -24,12 +21,7 @@ pub struct TestNodeProcess<R: Config> {
legacy_client: RefCell<Option<OnlineClient<R>>>,
rpc_client: rpc::RpcClient,
#[cfg(not(feature = "unstable-light-client"))]
client: OnlineClient<R>,
#[cfg(feature = "unstable-light-client")]
client: LightClient<R>,
}
impl<R> TestNodeProcess<R>
@@ -92,16 +84,9 @@ where
/// will use the legacy backend by default or the unstable backend if the
/// "unstable-backend-client" feature is enabled, so that we can run each
/// test against both.
#[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.
@@ -201,7 +186,7 @@ async fn build_rpc_client(ws_url: &str) -> Result<rpc::RpcClient, String> {
async fn build_legacy_client<T: Config>(
rpc_client: rpc::RpcClient,
) -> Result<OnlineClient<T>, String> {
let backend = legacy::LegacyBackend::new(rpc_client);
let backend = legacy::LegacyBackend::builder().build(rpc_client);
let client = OnlineClient::from_backend(Arc::new(backend))
.await
.map_err(|e| format!("Cannot construct OnlineClient from backend: {e}"))?;
@@ -235,28 +220,41 @@ async fn build_unstable_client<T: Config>(
}
#[cfg(feature = "unstable-light-client")]
async fn build_light_client<T: Config>(proc: &SubstrateNode) -> Result<LightClient<T>, String> {
async fn build_light_client<T: Config>(proc: &SubstrateNode) -> Result<OnlineClient<T>, String> {
use subxt::lightclient::{ChainConfig, LightClient};
// 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.
// Wait for a few blocks to be produced using the subxt client.
let client = OnlineClient::<T>::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.
// Now, configure a light client; fetch the chain spec and modify the bootnodes.
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())
let chain_spec = subxt::utils::fetch_chainspec_from_rpc_node(ws_url.as_str())
.await
.map_err(|e| format!("Failed to construct light client {}", e.to_string()))
.map_err(|e| format!("Failed to obtain chain spec from local machine: {e}"))?;
let chain_config = ChainConfig::chain_spec(chain_spec.get())
.set_bootnodes([bootnode.as_str()])
.map_err(|e| format!("Light client: cannot update boot nodes: {e}"))?;
// Instantiate the light client.
let (_lightclient, rpc) = LightClient::relay_chain(chain_config)
.map_err(|e| format!("Light client: cannot add relay chain: {e}"))?;
// Instantiate subxt client from this.
let api = OnlineClient::from_rpc_client(rpc)
.await
.map_err(|e| format!("Failed to build OnlineClient from light client RPC: {e}"))?;
Ok(api)
}
+1
View File
@@ -0,0 +1 @@
/target
+2344
View File
File diff suppressed because it is too large Load Diff
+24
View File
@@ -0,0 +1,24 @@
[package]
name = "subxt-core-no-std-tests"
edition = "2021"
publish = false
version = "0.0.0"
resolver = "2"
[dependencies]
subxt-metadata = { path = "../../metadata", default-features = false }
subxt-core = { path = "../../core", default-features = false }
subxt-signer = { path = "../../signer", default-features = false, features = ["subxt", "sr25519"] }
subxt-macro = { path = "../../macro" }
codec = { package = "parity-scale-codec", version = "3.6.9", default-features = false, features = ["derive"] }
libc_alloc = { version = "1.0.6" }
[profile.dev]
panic = "abort"
[profile.release]
panic = "abort"
# this shouldn't be needed, it's in workspace.exclude, but still
# I get the complaint unless I add it...
[workspace]
+7
View File
@@ -0,0 +1,7 @@
# No-Std Testing Crate
To test the no-std compatibility of various subxt-* crates, please run:
```bash
cargo build --target thumbv7em-none-eabi
```
+1
View File
@@ -0,0 +1 @@
nightly
+70
View File
@@ -0,0 +1,70 @@
// Copyright 2019-2023 Parity Technologies (UK) Ltd.
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
// see LICENSE for license details.
#![allow(internal_features)]
#![feature(lang_items, start)]
#![feature(alloc_error_handler)]
#![no_std]
#[start]
fn start(_argc: isize, _argv: *const *const u8) -> isize {
compile_test();
0
}
#[lang = "eh_personality"]
#[no_mangle]
pub extern "C" fn rust_eh_personality() {}
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
}
use libc_alloc::LibcAlloc;
#[global_allocator]
static ALLOCATOR: LibcAlloc = LibcAlloc;
//////////////////////////////////////////////////////////////////////////////
extern crate alloc;
/// Including code here makes sure it is not pruned.
/// We want all code included to compile fine for the `thumbv7em-none-eabi` target.
fn compile_test() {
// Subxt Metadata compiles:
use codec::Decode;
let bytes: alloc::vec::Vec<u8> = alloc::vec![0, 1, 2, 3, 4];
subxt_metadata::Metadata::decode(&mut &bytes[..]).expect_err("invalid byte sequence");
const METADATA: &[u8] = include_bytes!("../../../artifacts/polkadot_metadata_small.scale");
subxt_metadata::Metadata::decode(&mut &METADATA[..]).expect("should be valid metadata");
// Subxt Signer compiles:
use subxt_signer::sr25519;
let keypair = sr25519::dev::alice();
let message = b"Hello!";
let _signature = keypair.sign(message);
let _public_key = keypair.public_key();
// Note: `ecdsa` is not compiling for the `thumbv7em-none-eabi` target.
//
// use subxt_signer::ecdsa;
// let keypair = ecdsa::dev::alice();
// let message = b"Hello!";
// let _signature = keypair.sign(message);
// let _public_key = keypair.public_key();
//
// Subxt Core compiles:
let _era = subxt_core::utils::Era::Immortal;
}
#[subxt_macro::subxt(
runtime_metadata_path = "../../artifacts/polkadot_metadata_full.scale",
crate="::subxt_core"
)]
pub mod polkadot{}
+14 -2
View File
@@ -21,7 +21,7 @@ pub struct SubstrateNodeBuilder {
impl Default for SubstrateNodeBuilder {
fn default() -> Self {
Self::new()
SubstrateNodeBuilder::new()
}
}
@@ -29,11 +29,23 @@ impl SubstrateNodeBuilder {
/// Configure a new Substrate node.
pub fn new() -> Self {
SubstrateNodeBuilder {
binary_paths: vec!["substrate-node".into(), "substrate".into()],
binary_paths: vec![],
custom_flags: Default::default(),
}
}
/// Provide "substrate-node" and "substrate" as binary paths
pub fn substrate(&mut self) -> &mut Self {
self.binary_paths = vec!["substrate-node".into(), "substrate".into()];
self
}
/// Provide "polkadot" as binary path.
pub fn polkadot(&mut self) -> &mut Self {
self.binary_paths = vec!["polkadot".into()];
self
}
/// Set the path to the `substrate` binary; defaults to "substrate-node"
/// or "substrate".
pub fn binary_paths<Paths, S>(&mut self, paths: Paths) -> &mut Self
@@ -35,10 +35,8 @@ fn construct_offline_client() -> OfflineClient<PolkadotConfig> {
let bytes = hex::decode(h).unwrap();
H256::from_slice(&bytes)
};
let runtime_version = subxt::backend::RuntimeVersion {
spec_version: 9370,
transaction_version: 20,
};
let runtime_version = subxt::client::RuntimeVersion::new(9370, 20);
let metadata = {
let bytes = std::fs::read("../../../../artifacts/metadata_with_custom_values.scale").unwrap();
Metadata::decode(&mut &*bytes).unwrap()
+1 -1
View File
@@ -84,7 +84,7 @@ fn ui_tests() {
}
// Validation should succeed when metadata we codegen from is stripped and
// client metadata is full:
// client state is full:
{
let mut metadata = MetadataTestRunner::load_metadata();
metadata.retain(
+66 -64
View File
@@ -455,12 +455,12 @@ dependencies = [
[[package]]
name = "darling"
version = "0.20.3"
version = "0.20.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e"
checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391"
dependencies = [
"darling_core 0.20.3",
"darling_macro 0.20.3",
"darling_core 0.20.8",
"darling_macro 0.20.8",
]
[[package]]
@@ -479,9 +479,9 @@ dependencies = [
[[package]]
name = "darling_core"
version = "0.20.3"
version = "0.20.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621"
checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f"
dependencies = [
"fnv",
"ident_case",
@@ -504,11 +504,11 @@ dependencies = [
[[package]]
name = "darling_macro"
version = "0.20.3"
version = "0.20.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5"
checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f"
dependencies = [
"darling_core 0.20.3",
"darling_core 0.20.8",
"quote",
"syn 2.0.48",
]
@@ -589,9 +589,9 @@ dependencies = [
[[package]]
name = "either"
version = "1.9.0"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a"
[[package]]
name = "equivalent"
@@ -1114,18 +1114,18 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]]
name = "js-sys"
version = "0.3.67"
version = "0.3.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1"
checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "jsonrpsee"
version = "0.21.0"
version = "0.22.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9579d0ca9fb30da026bac2f0f7d9576ec93489aeb7cd4971dd5b4617d82c79b2"
checksum = "87f3ae45a64cfc0882934f963be9431b2a165d667f53140358181f262aca0702"
dependencies = [
"jsonrpsee-client-transport",
"jsonrpsee-core",
@@ -1135,9 +1135,9 @@ dependencies = [
[[package]]
name = "jsonrpsee-client-transport"
version = "0.21.0"
version = "0.22.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9f9ed46590a8d5681975f126e22531698211b926129a40a2db47cbca429220"
checksum = "455fc882e56f58228df2aee36b88a1340eafd707c76af2fa68cf94b37d461131"
dependencies = [
"futures-channel",
"futures-util",
@@ -1158,9 +1158,9 @@ dependencies = [
[[package]]
name = "jsonrpsee-core"
version = "0.21.0"
version = "0.22.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "776d009e2f591b78c038e0d053a796f94575d66ca4e77dd84bfc5e81419e436c"
checksum = "b75568f4f9696e3a47426e1985b548e1a9fcb13372a5e320372acaf04aca30d1"
dependencies = [
"anyhow",
"async-lock",
@@ -1183,9 +1183,9 @@ dependencies = [
[[package]]
name = "jsonrpsee-http-client"
version = "0.21.0"
version = "0.22.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78b7de9f3219d95985eb77fd03194d7c1b56c19bce1abfcc9d07462574b15572"
checksum = "9e7a95e346f55df84fb167b7e06470e196e7d5b9488a21d69c5d9732043ba7ba"
dependencies = [
"async-trait",
"hyper",
@@ -1203,9 +1203,9 @@ dependencies = [
[[package]]
name = "jsonrpsee-types"
version = "0.21.0"
version = "0.22.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3266dfb045c9174b24c77c2dfe0084914bb23a6b2597d70c9dc6018392e1cd1b"
checksum = "3467fd35feeee179f71ab294516bdf3a81139e7aeebdd860e46897c12e1a3368"
dependencies = [
"anyhow",
"beef",
@@ -1504,18 +1504,18 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "pin-project"
version = "1.1.3"
version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422"
checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
version = "1.1.3"
version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
dependencies = [
"proc-macro2",
"quote",
@@ -1616,9 +1616,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.76"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c"
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
dependencies = [
"unicode-ident",
]
@@ -2036,9 +2036,9 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73"
[[package]]
name = "serde"
version = "1.0.195"
version = "1.0.197"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02"
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
dependencies = [
"serde_derive",
]
@@ -2054,9 +2054,9 @@ dependencies = [
[[package]]
name = "serde_derive"
version = "1.0.195"
version = "1.0.197"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c"
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
dependencies = [
"proc-macro2",
"quote",
@@ -2065,9 +2065,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.111"
version = "1.0.114"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4"
checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0"
dependencies = [
"itoa",
"ryu",
@@ -2272,10 +2272,10 @@ dependencies = [
]
[[package]]
name = "sp-core-hashing"
version = "13.0.0"
name = "sp-crypto-hashing"
version = "15.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb8524f01591ee58b46cd83c9dbc0fcffd2fd730dabec4f59326cd58a00f17e2"
checksum = "1e0f4990add7b2cefdeca883c0efa99bb4d912cb2196120e1500c0cc099553b0"
dependencies = [
"blake2b_simd",
"byteorder",
@@ -2311,7 +2311,7 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
[[package]]
name = "subxt"
version = "0.33.0"
version = "0.35.0"
dependencies = [
"async-trait",
"base58",
@@ -2334,19 +2334,18 @@ dependencies = [
"scale-value",
"serde",
"serde_json",
"sp-core-hashing",
"sp-crypto-hashing",
"subxt-lightclient",
"subxt-macro",
"subxt-metadata",
"thiserror",
"tokio-stream",
"tracing",
"url",
]
[[package]]
name = "subxt-codegen"
version = "0.33.0"
version = "0.35.0"
dependencies = [
"frame-metadata 16.0.0",
"getrandom",
@@ -2366,7 +2365,7 @@ dependencies = [
[[package]]
name = "subxt-lightclient"
version = "0.33.0"
version = "0.35.0"
dependencies = [
"futures",
"futures-timer",
@@ -2391,24 +2390,27 @@ dependencies = [
[[package]]
name = "subxt-macro"
version = "0.33.0"
version = "0.35.0"
dependencies = [
"darling 0.20.3",
"darling 0.20.8",
"parity-scale-codec",
"proc-macro-error",
"quote",
"scale-typegen",
"subxt-codegen",
"syn 2.0.48",
]
[[package]]
name = "subxt-metadata"
version = "0.33.0"
version = "0.35.0"
dependencies = [
"derive_more",
"frame-metadata 16.0.0",
"hashbrown",
"parity-scale-codec",
"scale-info",
"sp-core-hashing",
"thiserror",
"sp-crypto-hashing",
]
[[package]]
@@ -2441,18 +2443,18 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]]
name = "thiserror"
version = "1.0.56"
version = "1.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad"
checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.56"
version = "1.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471"
checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
dependencies = [
"proc-macro2",
"quote",
@@ -2486,9 +2488,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.35.1"
version = "1.36.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104"
checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931"
dependencies = [
"backtrace",
"bytes",
@@ -2774,9 +2776,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
version = "0.2.90"
version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406"
checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
@@ -2784,9 +2786,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.90"
version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd"
checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da"
dependencies = [
"bumpalo",
"log",
@@ -2811,9 +2813,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.90"
version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999"
checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@@ -2821,9 +2823,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.90"
version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7"
checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
dependencies = [
"proc-macro2",
"quote",
@@ -2834,9 +2836,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.90"
version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b"
checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
[[package]]
name = "wasm-bindgen-test"
+13 -6
View File
@@ -1,10 +1,7 @@
#![cfg(target_arch = "wasm32")]
use futures_util::StreamExt;
use subxt::{
client::{LightClient, LightClientBuilder},
config::PolkadotConfig,
};
use subxt::{client::OnlineClient, config::PolkadotConfig, lightclient::LightClient};
use wasm_bindgen_test::*;
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
@@ -49,15 +46,25 @@ async fn light_client_works() {
/// We connect to an RPC node because the light client can struggle to sync in
/// time to a new local node for some reason. Because this can be brittle (eg RPC nodes can
/// go down or have network issues), we try a few RPC nodes until we find one that works.
async fn connect_to_rpc_node() -> LightClient<PolkadotConfig> {
async fn connect_to_rpc_node() -> OnlineClient<PolkadotConfig> {
let rpc_node_urls = [
"wss://rpc.polkadot.io",
"wss://1rpc.io/dot",
"wss://polkadot-public-rpc.blockops.network/ws",
];
async fn do_connect(
url: &str,
) -> Result<OnlineClient<PolkadotConfig>, Box<dyn std::error::Error + Send + Sync + 'static>>
{
let chainspec = subxt::utils::fetch_chainspec_from_rpc_node(url).await?;
let (_lc, rpc) = LightClient::relay_chain(chainspec.get())?;
let api = OnlineClient::from_rpc_client(rpc).await?;
Ok(api)
}
for url in rpc_node_urls {
let res = LightClientBuilder::new().build_from_url(url).await;
let res = do_connect(url).await;
match res {
Ok(api) => return api,
+3 -3
View File
@@ -2294,7 +2294,7 @@ dependencies = [
]
[[package]]
name = "sp-core-hashing"
name = "sp-crypto-hashing"
version = "13.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb8524f01591ee58b46cd83c9dbc0fcffd2fd730dabec4f59326cd58a00f17e2"
@@ -2362,7 +2362,7 @@ dependencies = [
"scale-value",
"serde",
"serde_json",
"sp-core-hashing",
"sp-crypto-hashing",
"subxt-lightclient",
"subxt-macro",
"subxt-metadata",
@@ -2434,7 +2434,7 @@ dependencies = [
"frame-metadata 16.0.0",
"parity-scale-codec",
"scale-info",
"sp-core-hashing",
"sp-crypto-hashing",
"thiserror",
]