Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
20aee21
Remove TypeSegmenter and dynclone dependency
ascjones Sep 29, 2021
3de2815
Publicly expose Rpc mod
ascjones Sep 29, 2021
c5ef0fa
Unused import warnings
ascjones Sep 29, 2021
b2f0ddf
Add getter for runtime metadata
ascjones Sep 29, 2021
e8256e0
Add pallet and event indices for raw events
ascjones Sep 29, 2021
d0dda23
Add is_call and is_event convenience trait functions
ascjones Oct 1, 2021
6198ac2
Add missing docs
ascjones Oct 4, 2021
cbbf0e1
Refactor tests crate
ascjones Oct 4, 2021
76d7b11
Restore remaining client tests
ascjones Oct 4, 2021
c86a9ce
Fmt
ascjones Oct 4, 2021
d439722
Fix warnings
ascjones Oct 4, 2021
997d6b7
Restore get_mod as test helper and fmt
ascjones Oct 4, 2021
44ec197
Use client references for api calls
ascjones Oct 4, 2021
950845f
Fix api usages with methods
ascjones Oct 4, 2021
3cb4000
Use Bytes for RawEvent debug
ascjones Oct 4, 2021
602f62b
Update metadata
ascjones Oct 5, 2021
4d1de1b
Restoring some Balances tests
ascjones Oct 5, 2021
384f88e
Populate runtime storage metadata
ascjones Oct 5, 2021
b340bc2
Restore balances lock test
ascjones Oct 5, 2021
f1b7b85
Restore Balances error test
ascjones Oct 5, 2021
ec90ecc
Fmt
ascjones Oct 5, 2021
e4907d4
Restore transfer subscription API
ascjones Oct 5, 2021
bab2aef
Staking test
ascjones Oct 5, 2021
696ee63
Restore another staking test
ascjones Oct 5, 2021
560ceb5
Restore another staking test
ascjones Oct 5, 2021
c5915b9
Restore another staking test
ascjones Oct 5, 2021
5e9b7d2
Partially restore chill_works_for_controller_only staking test
ascjones Oct 5, 2021
34e1da5
Fix fetching Optional storage entries
ascjones Oct 6, 2021
442fe24
Restore staking bond test
ascjones Oct 6, 2021
35a3141
Restore remaining staking tests
ascjones Oct 6, 2021
83af04e
Fmt
ascjones Oct 6, 2021
b95ce3d
Restore sudo tests
ascjones Oct 6, 2021
79355d3
Add some system tests
ascjones Oct 6, 2021
5e7b7e7
Fmt
ascjones Oct 6, 2021
368ec3b
Resolve some todos
ascjones Oct 6, 2021
f819cb6
Remove pass through rpc methods on Client, expose via rpc() getter
ascjones Oct 6, 2021
903b153
Remove more rpc pass through methods
ascjones Oct 6, 2021
d984dd5
Remove submit tx pass through rpc methods
ascjones Oct 6, 2021
a9d1e8f
Add some comments to SubmittableExtrinsic methods
ascjones Oct 7, 2021
ccb1491
Construct the runtime api from the client
ascjones Oct 7, 2021
ffc1a3c
Fmt
ascjones Oct 7, 2021
f46c944
Use From trait instead of new for AccountData query
ascjones Oct 8, 2021
f834035
Rename subxt_proc_macro crate to subxt_macro
ascjones Oct 12, 2021
fc80bb0
Fix AccountData From impl
ascjones Oct 12, 2021
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
5 changes: 2 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
members = [".", "proc-macro", "tests"]
members = [".", "macro", "tests"]

[package]
name = "substrate-subxt"
Expand Down Expand Up @@ -27,7 +27,6 @@ async-trait = "0.1.49"
codec = { package = "parity-scale-codec", version = "2", default-features = false, features = ["derive", "full"] }
chameleon = "0.1.0"
scale-info = "1.0.0"
dyn-clone = "1.0.3"
futures = "0.3.13"
hex = "0.4.3"
jsonrpsee-proc-macros = "0.3.0"
Expand All @@ -41,7 +40,7 @@ serde_json = "1.0.64"
thiserror = "1.0.24"
url = "2.2.1"

subxt-proc-macro = { version = "0.1.0", path = "proc-macro" }
subxt-macro = { version = "0.1.0", path = "macro" }

sp-core = { package = "sp-core", git = "https://github.com/paritytech/substrate/", branch = "master" }
sp-runtime = { package = "sp-runtime", git = "https://github.com/paritytech/substrate/", branch = "master" }
Expand Down
2 changes: 1 addition & 1 deletion proc-macro/Cargo.toml → macro/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
name = "subxt-proc-macro"
name = "subxt-macro"
version = "0.1.0"
authors = ["Parity Technologies <[email protected]>"]
edition = "2018"
Expand Down
178 changes: 94 additions & 84 deletions proc-macro/src/generate_runtime.rs → macro/src/generate_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ impl RuntimeGenerator {
pub fn generate_runtime(&self, item_mod: syn::ItemMod) -> TokenStream2 {
let type_substitutes = Self::parse_type_substitutes(&item_mod);
let type_gen =
TypeGenerator::new(&self.metadata.types, "__types", type_substitutes);
TypeGenerator::new(&self.metadata.types, "runtime_types", type_substitutes);
let types_mod = type_gen.generate_types_mod();
let types_mod_ident = types_mod.ident();
let pallets_with_mod_names = self
Expand All @@ -122,22 +122,19 @@ impl RuntimeGenerator {
.collect::<Vec<_>>();
let modules = pallets_with_mod_names.iter().map(|(pallet, mod_name)| {
let calls = if let Some(ref calls) = pallet.calls {
let (call_structs, call_fns) = self.generate_calls(&type_gen, pallet, calls);
let (call_structs, call_fns) =
self.generate_calls(&type_gen, pallet, calls);
quote! {
pub mod calls {
use super::#types_mod_ident;
#( #call_structs )*

pub struct TransactionApi<T: ::subxt::Runtime> {
client: ::std::sync::Arc<::subxt::Client<T>>,
pub struct TransactionApi<'a, T: ::subxt::Runtime> {
client: &'a ::subxt::Client<T>,
}

impl<T: ::subxt::Runtime> TransactionApi<T>
where
<<T::Extra as ::subxt::SignedExtra<T>>::Extra as ::subxt::sp_runtime::traits::SignedExtension>::AdditionalSigned:
Send + Sync
{
pub fn new(client: ::std::sync::Arc<::subxt::Client<T>>) -> Self {
impl<'a, T: ::subxt::Runtime> TransactionApi<'a, T> {
pub fn new(client: &'a ::subxt::Client<T>) -> Self {
Self { client }
}

Expand All @@ -163,7 +160,8 @@ impl RuntimeGenerator {
quote!()
};

let (storage_structs, storage_fns) = if let Some(ref storage) = pallet.storage {
let (storage_structs, storage_fns) = if let Some(ref storage) = pallet.storage
{
let (storage_structs, storage_fns) = storage
.entries
.iter()
Expand All @@ -176,25 +174,24 @@ impl RuntimeGenerator {
(Vec::new(), Vec::new())
};

let storage_mod =
quote! {
pub mod storage {
use super::#types_mod_ident;
#( #storage_structs )*

pub struct StorageApi<T: ::subxt::Runtime> {
client: ::std::sync::Arc<::subxt::Client<T>>,
}
let storage_mod = quote! {
pub mod storage {
use super::#types_mod_ident;
#( #storage_structs )*

impl<T: ::subxt::Runtime> StorageApi<T> {
pub fn new(client: ::std::sync::Arc<::subxt::Client<T>>) -> Self {
Self { client }
}
pub struct StorageApi<'a, T: ::subxt::Runtime> {
client: &'a ::subxt::Client<T>,
}

#( #storage_fns )*
impl<'a, T: ::subxt::Runtime> StorageApi<'a, T> {
pub fn new(client: &'a ::subxt::Client<T>) -> Self {
Self { client }
}

#( #storage_fns )*
}
};
}
};

quote! {
pub mod #mod_name {
Expand Down Expand Up @@ -228,27 +225,19 @@ impl RuntimeGenerator {

// todo: [AJ] keep all other code items from decorated mod?
let mod_ident = item_mod.ident;
let (pallet_storage_cli_fields, pallet_storage_cli_fields_init): (Vec<_>, Vec<_>) = pallets_with_mod_names.iter().filter_map(|(pallet, pallet_mod_name)| {
if pallet.storage.is_some() {
let pallet_storage_cli_field = quote!( pub #pallet_mod_name: #pallet_mod_name::storage::StorageApi<T> );
let pallet_storage_cli_field_init = quote!( #pallet_mod_name: #pallet_mod_name::storage::StorageApi::new(client.clone()) );
Some((pallet_storage_cli_field, pallet_storage_cli_field_init))
} else {
None
}
}).unzip();
let (pallet_calls_cli_fields, pallet_calls_cli_fields_init): (Vec<_>, Vec<_>) = pallets_with_mod_names
.iter()
.filter_map(|(pallet, pallet_mod_name)| {
if pallet.calls.is_some() {
let cli_field = quote!( pub #pallet_mod_name: #pallet_mod_name::calls::TransactionApi<T> );
let cli_field_init = quote!( #pallet_mod_name: #pallet_mod_name::calls::TransactionApi::new(client.clone()) );
Some((cli_field, cli_field_init))
} else {
None
}
})
.unzip();
let pallets_with_storage =
pallets_with_mod_names
.iter()
.filter_map(|(pallet, pallet_mod_name)| {
pallet.storage.as_ref().map(|_| pallet_mod_name)
});
let pallets_with_calls =
pallets_with_mod_names
.iter()
.filter_map(|(pallet, pallet_mod_name)| {
pallet.calls.as_ref().map(|_| pallet_mod_name)
});

quote! {
#[allow(dead_code, unused_imports, non_camel_case_types)]
pub mod #mod_ident {
Expand All @@ -257,40 +246,47 @@ impl RuntimeGenerator {
#types_mod

pub struct RuntimeApi<T: ::subxt::Runtime> {
pub client: ::std::sync::Arc<::subxt::Client<T>>,
pub storage: StorageApi<T>,
pub tx: TransactionApi<T>,
pub client: ::subxt::Client<T>,
}

impl<T: ::subxt::Runtime> RuntimeApi<T>
where
<<T::Extra as ::subxt::SignedExtra<T>>::Extra as ::subxt::sp_runtime::traits::SignedExtension>::AdditionalSigned:
Send + Sync
{
pub fn new(client: ::subxt::Client<T>) -> Self {
let client = ::std::sync::Arc::new(client);
Self {
client: client.clone(),
storage: StorageApi {
client: client.clone(),
#( #pallet_storage_cli_fields_init, )*
},
tx: TransactionApi {
client: client.clone(),
#( #pallet_calls_cli_fields_init, )*
}
}
impl<T: ::subxt::Runtime> ::core::convert::From<::subxt::Client<T>> for RuntimeApi<T> {
fn from(client: ::subxt::Client<T>) -> Self {
Self { client }
}
}

impl<'a, T: ::subxt::Runtime> RuntimeApi<T> {
pub fn storage(&'a self) -> StorageApi<'a, T> {
StorageApi { client: &self.client }
}

pub fn tx(&'a self) -> TransactionApi<'a, T> {
TransactionApi { client: &self.client }
}
}

pub struct StorageApi<T: ::subxt::Runtime> {
client: ::std::sync::Arc<::subxt::Client<T>>,
#( #pallet_storage_cli_fields, )*
pub struct StorageApi<'a, T: ::subxt::Runtime> {
client: &'a ::subxt::Client<T>,
}

pub struct TransactionApi<T: ::subxt::Runtime> {
client: ::std::sync::Arc<::subxt::Client<T>>,
#( #pallet_calls_cli_fields, )*
impl<'a, T: ::subxt::Runtime> StorageApi<'a, T> {
#(
pub fn #pallets_with_storage(&self) -> #pallets_with_storage::storage::StorageApi<'a, T> {
#pallets_with_storage::storage::StorageApi::new(self.client)
}
)*
}

pub struct TransactionApi<'a, T: ::subxt::Runtime> {
client: &'a ::subxt::Client<T>,
}

impl<'a, T: ::subxt::Runtime> TransactionApi<'a, T> {
#(
pub fn #pallets_with_calls(&self) -> #pallets_with_calls::calls::TransactionApi<'a, T> {
#pallets_with_calls::calls::TransactionApi::new(self.client)
}
)*
}
}
}
Expand All @@ -310,8 +306,14 @@ impl RuntimeGenerator {
let meta = attr.parse_meta().unwrap_or_else(|e| {
abort!(attr.span(), "Error parsing attribute: {}", e)
});
let substitute_type_args =
Subxt::from_meta(&meta).unwrap(); // todo
let substitute_type_args = Subxt::from_meta(&meta)
.unwrap_or_else(|e| {
abort!(
attr.span(),
"Error parsing attribute meta: {}",
e
)
});
substitute_type_args
})
.collect::<Vec<_>>();
Expand Down Expand Up @@ -379,7 +381,7 @@ impl RuntimeGenerator {
#( #call_fn_args, )*
) -> ::subxt::SubmittableExtrinsic<T, #call_struct_name> {
let call = #call_struct_name { #( #call_args, )* };
::subxt::SubmittableExtrinsic::new(self.client.clone(), call)
::subxt::SubmittableExtrinsic::new(self.client, call)
}
};
(call_struct, client_fn)
Expand Down Expand Up @@ -535,14 +537,22 @@ impl RuntimeGenerator {
let pallet_name = &pallet.name;
let storage_name = &storage_entry.name;
let fn_name = format_ident!("{}", storage_entry.name.to_snake_case());
let return_ty = match storage_entry.ty {
let storage_entry_ty = match storage_entry.ty {
StorageEntryType::Plain(ref ty) => ty,
StorageEntryType::Map { ref value, .. } => value,
};
let return_ty_path = type_gen.resolve_type_path(return_ty.id(), &[]);
let return_ty = match storage_entry.modifier {
StorageEntryModifier::Default => quote!( #return_ty_path ),
StorageEntryModifier::Optional => quote!( Option<#return_ty_path> ),
let storage_entry_value_ty =
type_gen.resolve_type_path(storage_entry_ty.id(), &[]);
let (return_ty, fetch) = match storage_entry.modifier {
StorageEntryModifier::Default => {
(quote!( #storage_entry_value_ty ), quote!(fetch_or_default))
}
StorageEntryModifier::Optional => {
(
quote!( ::core::option::Option<#storage_entry_value_ty> ),
quote!(fetch),
)
}
};

let storage_entry_type = quote! {
Expand All @@ -551,7 +561,7 @@ impl RuntimeGenerator {
impl ::subxt::StorageEntry for #entry_struct_ident {
const PALLET: &'static str = #pallet_name;
const STORAGE: &'static str = #storage_name;
type Value = #return_ty;
type Value = #storage_entry_value_ty;
fn key(&self) -> ::subxt::StorageEntryKey {
#key_impl
}
Expand All @@ -568,7 +578,7 @@ impl RuntimeGenerator {
hash: ::core::option::Option<T::Hash>,
) -> ::core::result::Result<#return_ty, ::subxt::Error> {
let entry = #constructor;
self.client.storage().fetch_or_default(&entry, hash).await
self.client.storage().#fetch(&entry, hash).await
}
};

Expand Down
Loading