mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-09 21:21:11 +00:00
Run cargo fmt on the whole code base (#9394)
* Run cargo fmt on the whole code base * Second run * Add CI check * Fix compilation * More unnecessary braces * Handle weights * Use --all * Use correct attributes... * Fix UI tests * AHHHHHHHHH * 🤦 * Docs * Fix compilation * 🤷 * Please stop * 🤦 x 2 * More * make rustfmt.toml consistent with polkadot Co-authored-by: André Silva <andrerfosilva@gmail.com>
This commit is contained in:
@@ -16,21 +16,25 @@
|
||||
// limitations under the License.
|
||||
|
||||
use crate::utils::{
|
||||
generate_crate_access, generate_hidden_includes, generate_runtime_mod_name_for_trait,
|
||||
fold_fn_decl_for_client_side, extract_parameter_names_types_and_borrows,
|
||||
generate_native_call_generator_fn_name, return_type_extract_type,
|
||||
generate_method_runtime_api_impl_name, generate_call_api_at_fn_name, prefix_function_with_trait,
|
||||
replace_wild_card_parameter_names, AllowSelfRefInParameters,
|
||||
extract_parameter_names_types_and_borrows, fold_fn_decl_for_client_side,
|
||||
generate_call_api_at_fn_name, generate_crate_access, generate_hidden_includes,
|
||||
generate_method_runtime_api_impl_name, generate_native_call_generator_fn_name,
|
||||
generate_runtime_mod_name_for_trait, prefix_function_with_trait,
|
||||
replace_wild_card_parameter_names, return_type_extract_type, AllowSelfRefInParameters,
|
||||
};
|
||||
|
||||
use proc_macro2::{TokenStream, Span};
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
|
||||
use quote::quote;
|
||||
|
||||
use syn::{
|
||||
spanned::Spanned, parse_macro_input, parse::{Parse, ParseStream, Result, Error}, ReturnType,
|
||||
fold::{self, Fold}, parse_quote, ItemTrait, Generics, GenericParam, Attribute, FnArg, Type,
|
||||
visit::{Visit, self}, TraitBound, Meta, NestedMeta, Lit, TraitItem, Ident, TraitItemMethod,
|
||||
fold::{self, Fold},
|
||||
parse::{Error, Parse, ParseStream, Result},
|
||||
parse_macro_input, parse_quote,
|
||||
spanned::Spanned,
|
||||
visit::{self, Visit},
|
||||
Attribute, FnArg, GenericParam, Generics, Ident, ItemTrait, Lit, Meta, NestedMeta, ReturnType,
|
||||
TraitBound, TraitItem, TraitItemMethod, Type,
|
||||
};
|
||||
|
||||
use std::collections::HashMap;
|
||||
@@ -59,9 +63,8 @@ const CHANGED_IN_ATTRIBUTE: &str = "changed_in";
|
||||
/// Is used when a trait method was renamed.
|
||||
const RENAMED_ATTRIBUTE: &str = "renamed";
|
||||
/// All attributes that we support in the declaration of a runtime api trait.
|
||||
const SUPPORTED_ATTRIBUTE_NAMES: &[&str] = &[
|
||||
CORE_TRAIT_ATTRIBUTE, API_VERSION_ATTRIBUTE, CHANGED_IN_ATTRIBUTE, RENAMED_ATTRIBUTE,
|
||||
];
|
||||
const SUPPORTED_ATTRIBUTE_NAMES: &[&str] =
|
||||
&[CORE_TRAIT_ATTRIBUTE, API_VERSION_ATTRIBUTE, CHANGED_IN_ATTRIBUTE, RENAMED_ATTRIBUTE];
|
||||
|
||||
/// The structure used for parsing the runtime api declarations.
|
||||
struct RuntimeApiDecls {
|
||||
@@ -94,14 +97,12 @@ fn extend_generics_with_block(generics: &mut Generics) {
|
||||
/// attribute body as `TokenStream`.
|
||||
fn remove_supported_attributes(attrs: &mut Vec<Attribute>) -> HashMap<&'static str, Attribute> {
|
||||
let mut result = HashMap::new();
|
||||
attrs.retain(|v| {
|
||||
match SUPPORTED_ATTRIBUTE_NAMES.iter().find(|a| v.path.is_ident(a)) {
|
||||
Some(attribute) => {
|
||||
result.insert(*attribute, v.clone());
|
||||
false
|
||||
},
|
||||
None => true,
|
||||
}
|
||||
attrs.retain(|v| match SUPPORTED_ATTRIBUTE_NAMES.iter().find(|a| v.path.is_ident(a)) {
|
||||
Some(attribute) => {
|
||||
result.insert(*attribute, v.clone());
|
||||
false
|
||||
},
|
||||
None => true,
|
||||
});
|
||||
|
||||
result
|
||||
@@ -226,16 +227,17 @@ fn generate_native_call_generators(decl: &ItemTrait) -> Result<TokenStream> {
|
||||
)
|
||||
)
|
||||
} else {
|
||||
quote!( Ok(res) )
|
||||
quote!(Ok(res))
|
||||
};
|
||||
|
||||
let input_names = params.iter().map(|v| &v.0);
|
||||
// If the type is using the block generic type, we will encode/decode it to make it
|
||||
// compatible. To ensure that we forward it by ref/value, we use the value given by the
|
||||
// the user. Otherwise if it is not using the block, we don't need to add anything.
|
||||
let input_borrows = params
|
||||
.iter()
|
||||
.map(|v| if type_is_using_block(&v.1) { v.2.clone() } else { None });
|
||||
let input_borrows =
|
||||
params
|
||||
.iter()
|
||||
.map(|v| if type_is_using_block(&v.1) { v.2.clone() } else { None });
|
||||
|
||||
// Replace all `Block` with `NodeBlock`, add `'a` lifetime to references and collect
|
||||
// all the function inputs.
|
||||
@@ -304,28 +306,23 @@ fn parse_renamed_attribute(renamed: &Attribute) -> Result<(String, u32)> {
|
||||
);
|
||||
|
||||
match meta {
|
||||
Meta::List(list) => {
|
||||
Meta::List(list) =>
|
||||
if list.nested.len() > 2 && list.nested.is_empty() {
|
||||
err
|
||||
} else {
|
||||
let mut itr = list.nested.iter();
|
||||
let old_name = match itr.next() {
|
||||
Some(NestedMeta::Lit(Lit::Str(i))) => {
|
||||
i.value()
|
||||
},
|
||||
Some(NestedMeta::Lit(Lit::Str(i))) => i.value(),
|
||||
_ => return err,
|
||||
};
|
||||
|
||||
let version = match itr.next() {
|
||||
Some(NestedMeta::Lit(Lit::Int(i))) => {
|
||||
i.base10_parse()?
|
||||
},
|
||||
Some(NestedMeta::Lit(Lit::Int(i))) => i.base10_parse()?,
|
||||
_ => return err,
|
||||
};
|
||||
|
||||
Ok((old_name, version))
|
||||
}
|
||||
},
|
||||
},
|
||||
_ => err,
|
||||
}
|
||||
}
|
||||
@@ -353,23 +350,19 @@ fn generate_call_api_at_calls(decl: &ItemTrait) -> Result<TokenStream> {
|
||||
fn_.span(),
|
||||
format!(
|
||||
"`{}` and `{}` are not supported at once.",
|
||||
RENAMED_ATTRIBUTE,
|
||||
CHANGED_IN_ATTRIBUTE
|
||||
)
|
||||
));
|
||||
RENAMED_ATTRIBUTE, CHANGED_IN_ATTRIBUTE
|
||||
),
|
||||
))
|
||||
}
|
||||
|
||||
// We do not need to generate this function for a method that signature was changed.
|
||||
if attrs.contains_key(CHANGED_IN_ATTRIBUTE) {
|
||||
continue;
|
||||
continue
|
||||
}
|
||||
|
||||
// Parse the renamed attributes.
|
||||
let mut renames = Vec::new();
|
||||
if let Some((_, a)) = attrs
|
||||
.iter()
|
||||
.find(|a| a.0 == &RENAMED_ATTRIBUTE)
|
||||
{
|
||||
if let Some((_, a)) = attrs.iter().find(|a| a.0 == &RENAMED_ATTRIBUTE) {
|
||||
let (old_name, version) = parse_renamed_attribute(a)?;
|
||||
renames.push((version, prefix_function_with_trait(&trait_name, &old_name)));
|
||||
}
|
||||
@@ -381,7 +374,7 @@ fn generate_call_api_at_calls(decl: &ItemTrait) -> Result<TokenStream> {
|
||||
versions.push(version);
|
||||
old_names.push(old_name);
|
||||
(versions, old_names)
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Generate the generator function
|
||||
@@ -456,27 +449,32 @@ fn generate_runtime_decls(decls: &[ItemTrait]) -> Result<TokenStream> {
|
||||
extend_generics_with_block(&mut decl.generics);
|
||||
let mod_name = generate_runtime_mod_name_for_trait(&decl.ident);
|
||||
let found_attributes = remove_supported_attributes(&mut decl.attrs);
|
||||
let api_version = get_api_version(&found_attributes).map(|v| {
|
||||
generate_runtime_api_version(v as u32)
|
||||
})?;
|
||||
let api_version =
|
||||
get_api_version(&found_attributes).map(|v| generate_runtime_api_version(v as u32))?;
|
||||
let id = generate_runtime_api_id(&decl.ident.to_string());
|
||||
|
||||
let call_api_at_calls = generate_call_api_at_calls(&decl)?;
|
||||
|
||||
// Remove methods that have the `changed_in` attribute as they are not required for the
|
||||
// runtime anymore.
|
||||
decl.items = decl.items.iter_mut().filter_map(|i| match i {
|
||||
TraitItem::Method(ref mut method) => {
|
||||
if remove_supported_attributes(&mut method.attrs).contains_key(CHANGED_IN_ATTRIBUTE) {
|
||||
None
|
||||
} else {
|
||||
// Make sure we replace all the wild card parameter names.
|
||||
replace_wild_card_parameter_names(&mut method.sig);
|
||||
Some(TraitItem::Method(method.clone()))
|
||||
}
|
||||
}
|
||||
r => Some(r.clone()),
|
||||
}).collect();
|
||||
decl.items = decl
|
||||
.items
|
||||
.iter_mut()
|
||||
.filter_map(|i| match i {
|
||||
TraitItem::Method(ref mut method) => {
|
||||
if remove_supported_attributes(&mut method.attrs)
|
||||
.contains_key(CHANGED_IN_ATTRIBUTE)
|
||||
{
|
||||
None
|
||||
} else {
|
||||
// Make sure we replace all the wild card parameter names.
|
||||
replace_wild_card_parameter_names(&mut method.sig);
|
||||
Some(TraitItem::Method(method.clone()))
|
||||
}
|
||||
},
|
||||
r => Some(r.clone()),
|
||||
})
|
||||
.collect();
|
||||
|
||||
let native_call_generators = generate_native_call_generators(&decl)?;
|
||||
|
||||
@@ -533,8 +531,10 @@ impl<'a> ToClientSideDecl<'a> {
|
||||
result
|
||||
}
|
||||
|
||||
fn fold_trait_item_method(&mut self, method: TraitItemMethod)
|
||||
-> (TraitItemMethod, Option<TraitItemMethod>, TraitItemMethod) {
|
||||
fn fold_trait_item_method(
|
||||
&mut self,
|
||||
method: TraitItemMethod,
|
||||
) -> (TraitItemMethod, Option<TraitItemMethod>, TraitItemMethod) {
|
||||
let crate_ = self.crate_;
|
||||
let context = quote!( #crate_::ExecutionContext::OffchainCall(None) );
|
||||
let fn_impl = self.create_method_runtime_api_impl(method.clone());
|
||||
@@ -547,8 +547,9 @@ impl<'a> ToClientSideDecl<'a> {
|
||||
fn create_method_decl_with_context(&mut self, method: TraitItemMethod) -> TraitItemMethod {
|
||||
let crate_ = self.crate_;
|
||||
let context_arg: syn::FnArg = parse_quote!( context: #crate_::ExecutionContext );
|
||||
let mut fn_decl_ctx = self.create_method_decl(method, quote!( context ));
|
||||
fn_decl_ctx.sig.ident = Ident::new(&format!("{}_with_context", &fn_decl_ctx.sig.ident), Span::call_site());
|
||||
let mut fn_decl_ctx = self.create_method_decl(method, quote!(context));
|
||||
fn_decl_ctx.sig.ident =
|
||||
Ident::new(&format!("{}_with_context", &fn_decl_ctx.sig.ident), Span::call_site());
|
||||
fn_decl_ctx.sig.inputs.insert(2, context_arg);
|
||||
|
||||
fn_decl_ctx
|
||||
@@ -556,9 +557,12 @@ impl<'a> ToClientSideDecl<'a> {
|
||||
|
||||
/// Takes the given method and creates a `method_runtime_api_impl` method that will be
|
||||
/// implemented in the runtime for the client side.
|
||||
fn create_method_runtime_api_impl(&mut self, mut method: TraitItemMethod) -> Option<TraitItemMethod> {
|
||||
fn create_method_runtime_api_impl(
|
||||
&mut self,
|
||||
mut method: TraitItemMethod,
|
||||
) -> Option<TraitItemMethod> {
|
||||
if remove_supported_attributes(&mut method.attrs).contains_key(CHANGED_IN_ATTRIBUTE) {
|
||||
return None;
|
||||
return None
|
||||
}
|
||||
|
||||
let fn_sig = &method.sig;
|
||||
@@ -566,36 +570,35 @@ impl<'a> ToClientSideDecl<'a> {
|
||||
|
||||
// Get types and if the value is borrowed from all parameters.
|
||||
// If there is an error, we push it as the block to the user.
|
||||
let param_types = match extract_parameter_names_types_and_borrows(
|
||||
fn_sig,
|
||||
AllowSelfRefInParameters::No,
|
||||
) {
|
||||
Ok(res) => res.into_iter().map(|v| {
|
||||
let ty = v.1;
|
||||
let borrow = v.2;
|
||||
quote!( #borrow #ty )
|
||||
}).collect::<Vec<_>>(),
|
||||
Err(e) => {
|
||||
self.errors.push(e.to_compile_error());
|
||||
Vec::new()
|
||||
}
|
||||
};
|
||||
let param_types =
|
||||
match extract_parameter_names_types_and_borrows(fn_sig, AllowSelfRefInParameters::No) {
|
||||
Ok(res) => res
|
||||
.into_iter()
|
||||
.map(|v| {
|
||||
let ty = v.1;
|
||||
let borrow = v.2;
|
||||
quote!( #borrow #ty )
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
Err(e) => {
|
||||
self.errors.push(e.to_compile_error());
|
||||
Vec::new()
|
||||
},
|
||||
};
|
||||
let name = generate_method_runtime_api_impl_name(&self.trait_, &method.sig.ident);
|
||||
let block_id = self.block_id;
|
||||
let crate_ = self.crate_;
|
||||
|
||||
Some(
|
||||
parse_quote!{
|
||||
#[doc(hidden)]
|
||||
fn #name(
|
||||
&self,
|
||||
at: &#block_id,
|
||||
context: #crate_::ExecutionContext,
|
||||
params: Option<( #( #param_types ),* )>,
|
||||
params_encoded: Vec<u8>,
|
||||
) -> std::result::Result<#crate_::NativeOrEncoded<#ret_type>, #crate_::ApiError>;
|
||||
}
|
||||
)
|
||||
Some(parse_quote! {
|
||||
#[doc(hidden)]
|
||||
fn #name(
|
||||
&self,
|
||||
at: &#block_id,
|
||||
context: #crate_::ExecutionContext,
|
||||
params: Option<( #( #param_types ),* )>,
|
||||
params_encoded: Vec<u8>,
|
||||
) -> std::result::Result<#crate_::NativeOrEncoded<#ret_type>, #crate_::ApiError>;
|
||||
})
|
||||
}
|
||||
|
||||
/// Takes the method declared by the user and creates the declaration we require for the runtime
|
||||
@@ -614,7 +617,7 @@ impl<'a> ToClientSideDecl<'a> {
|
||||
Err(e) => {
|
||||
self.errors.push(e.to_compile_error());
|
||||
Vec::new()
|
||||
}
|
||||
},
|
||||
};
|
||||
let params2 = params.clone();
|
||||
let ret_type = return_type_extract_type(&method.sig.output);
|
||||
@@ -635,7 +638,8 @@ impl<'a> ToClientSideDecl<'a> {
|
||||
Error::new(
|
||||
method.span(),
|
||||
"`changed_in` version can not be greater than the `api_version`",
|
||||
).to_compile_error()
|
||||
)
|
||||
.to_compile_error(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -646,49 +650,48 @@ impl<'a> ToClientSideDecl<'a> {
|
||||
method.sig.ident = ident;
|
||||
method.attrs.push(parse_quote!( #[deprecated] ));
|
||||
|
||||
let panic = format!("Calling `{}` should not return a native value!", method.sig.ident);
|
||||
(quote!( panic!(#panic) ), quote!( None ))
|
||||
let panic =
|
||||
format!("Calling `{}` should not return a native value!", method.sig.ident);
|
||||
(quote!(panic!(#panic)), quote!(None))
|
||||
},
|
||||
Ok(None) => (quote!( Ok(n) ), quote!( Some(( #( #params2 ),* )) )),
|
||||
Ok(None) => (quote!(Ok(n)), quote!( Some(( #( #params2 ),* )) )),
|
||||
Err(e) => {
|
||||
self.errors.push(e.to_compile_error());
|
||||
(quote!( unimplemented!() ), quote!( None ))
|
||||
}
|
||||
(quote!(unimplemented!()), quote!(None))
|
||||
},
|
||||
};
|
||||
|
||||
let function_name = method.sig.ident.to_string();
|
||||
|
||||
// Generate the default implementation that calls the `method_runtime_api_impl` method.
|
||||
method.default = Some(
|
||||
parse_quote! {
|
||||
{
|
||||
let runtime_api_impl_params_encoded =
|
||||
#crate_::Encode::encode(&( #( &#params ),* ));
|
||||
method.default = Some(parse_quote! {
|
||||
{
|
||||
let runtime_api_impl_params_encoded =
|
||||
#crate_::Encode::encode(&( #( &#params ),* ));
|
||||
|
||||
self.#name_impl(
|
||||
__runtime_api_at_param__,
|
||||
#context,
|
||||
#param_tuple,
|
||||
runtime_api_impl_params_encoded,
|
||||
).and_then(|r|
|
||||
match r {
|
||||
#crate_::NativeOrEncoded::Native(n) => {
|
||||
#native_handling
|
||||
},
|
||||
#crate_::NativeOrEncoded::Encoded(r) => {
|
||||
<#ret_type as #crate_::Decode>::decode(&mut &r[..])
|
||||
.map_err(|err|
|
||||
#crate_::ApiError::FailedToDecodeReturnValue {
|
||||
function: #function_name,
|
||||
error: err,
|
||||
}
|
||||
)
|
||||
}
|
||||
self.#name_impl(
|
||||
__runtime_api_at_param__,
|
||||
#context,
|
||||
#param_tuple,
|
||||
runtime_api_impl_params_encoded,
|
||||
).and_then(|r|
|
||||
match r {
|
||||
#crate_::NativeOrEncoded::Native(n) => {
|
||||
#native_handling
|
||||
},
|
||||
#crate_::NativeOrEncoded::Encoded(r) => {
|
||||
<#ret_type as #crate_::Decode>::decode(&mut &r[..])
|
||||
.map_err(|err|
|
||||
#crate_::ApiError::FailedToDecodeReturnValue {
|
||||
function: #function_name,
|
||||
error: err,
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
method
|
||||
}
|
||||
@@ -705,11 +708,7 @@ impl<'a> Fold for ToClientSideDecl<'a> {
|
||||
|
||||
if is_core_trait {
|
||||
// Add all the supertraits we want to have for `Core`.
|
||||
input.supertraits = parse_quote!(
|
||||
'static
|
||||
+ Send
|
||||
+ Sync
|
||||
);
|
||||
input.supertraits = parse_quote!('static + Send + Sync);
|
||||
} else {
|
||||
// Add the `Core` runtime api as super trait.
|
||||
let crate_ = &self.crate_;
|
||||
@@ -729,24 +728,22 @@ fn parse_runtime_api_version(version: &Attribute) -> Result<u64> {
|
||||
let meta = version.parse_meta()?;
|
||||
|
||||
let err = Err(Error::new(
|
||||
meta.span(),
|
||||
&format!(
|
||||
"Unexpected `{api_version}` attribute. The supported format is `{api_version}(1)`",
|
||||
api_version = API_VERSION_ATTRIBUTE
|
||||
)
|
||||
)
|
||||
);
|
||||
meta.span(),
|
||||
&format!(
|
||||
"Unexpected `{api_version}` attribute. The supported format is `{api_version}(1)`",
|
||||
api_version = API_VERSION_ATTRIBUTE
|
||||
),
|
||||
));
|
||||
|
||||
match meta {
|
||||
Meta::List(list) => {
|
||||
Meta::List(list) =>
|
||||
if list.nested.len() != 1 {
|
||||
err
|
||||
} else if let Some(NestedMeta::Lit(Lit::Int(i))) = list.nested.first() {
|
||||
i.base10_parse()
|
||||
} else {
|
||||
err
|
||||
}
|
||||
},
|
||||
},
|
||||
_ => err,
|
||||
}
|
||||
}
|
||||
@@ -798,14 +795,18 @@ fn generate_runtime_info_impl(trait_: &ItemTrait, version: u64) -> TokenStream {
|
||||
|
||||
/// Get changed in version from the user given attribute or `Ok(None)`, if no attribute was given.
|
||||
fn get_changed_in(found_attributes: &HashMap<&'static str, Attribute>) -> Result<Option<u64>> {
|
||||
found_attributes.get(&CHANGED_IN_ATTRIBUTE)
|
||||
found_attributes
|
||||
.get(&CHANGED_IN_ATTRIBUTE)
|
||||
.map(|v| parse_runtime_api_version(v).map(Some))
|
||||
.unwrap_or(Ok(None))
|
||||
}
|
||||
|
||||
/// Get the api version from the user given attribute or `Ok(1)`, if no attribute was given.
|
||||
fn get_api_version(found_attributes: &HashMap<&'static str, Attribute>) -> Result<u64> {
|
||||
found_attributes.get(&API_VERSION_ATTRIBUTE).map(parse_runtime_api_version).unwrap_or(Ok(1))
|
||||
found_attributes
|
||||
.get(&API_VERSION_ATTRIBUTE)
|
||||
.map(parse_runtime_api_version)
|
||||
.unwrap_or(Ok(1))
|
||||
}
|
||||
|
||||
/// Generate the declaration of the trait for the client side.
|
||||
@@ -863,7 +864,10 @@ impl CheckTraitDecl {
|
||||
/// Check that the given method declarations are correct.
|
||||
///
|
||||
/// Any error is stored in `self.errors`.
|
||||
fn check_method_declarations<'a>(&mut self, methods: impl Iterator<Item = &'a TraitItemMethod>) {
|
||||
fn check_method_declarations<'a>(
|
||||
&mut self,
|
||||
methods: impl Iterator<Item = &'a TraitItemMethod>,
|
||||
) {
|
||||
let mut method_to_signature_changed = HashMap::<Ident, Vec<Option<u64>>>::new();
|
||||
|
||||
methods.into_iter().for_each(|method| {
|
||||
@@ -871,7 +875,10 @@ impl CheckTraitDecl {
|
||||
|
||||
let changed_in = match get_changed_in(&attributes) {
|
||||
Ok(r) => r,
|
||||
Err(e) => { self.errors.push(e); return; },
|
||||
Err(e) => {
|
||||
self.errors.push(e);
|
||||
return
|
||||
},
|
||||
};
|
||||
|
||||
method_to_signature_changed
|
||||
@@ -912,16 +919,13 @@ impl<'ast> Visit<'ast> for CheckTraitDecl {
|
||||
|
||||
fn visit_generic_param(&mut self, input: &'ast GenericParam) {
|
||||
match input {
|
||||
GenericParam::Type(ty) if ty.ident == BLOCK_GENERIC_IDENT => {
|
||||
self.errors.push(
|
||||
Error::new(
|
||||
input.span(),
|
||||
"`Block: BlockT` generic parameter will be added automatically by the \
|
||||
`decl_runtime_apis!` macro!"
|
||||
)
|
||||
)
|
||||
},
|
||||
_ => {}
|
||||
GenericParam::Type(ty) if ty.ident == BLOCK_GENERIC_IDENT =>
|
||||
self.errors.push(Error::new(
|
||||
input.span(),
|
||||
"`Block: BlockT` generic parameter will be added automatically by the \
|
||||
`decl_runtime_apis!` macro!",
|
||||
)),
|
||||
_ => {},
|
||||
}
|
||||
|
||||
visit::visit_generic_param(self, input);
|
||||
@@ -930,14 +934,12 @@ impl<'ast> Visit<'ast> for CheckTraitDecl {
|
||||
fn visit_trait_bound(&mut self, input: &'ast TraitBound) {
|
||||
if let Some(last_ident) = input.path.segments.last().map(|v| &v.ident) {
|
||||
if last_ident == "BlockT" || last_ident == BLOCK_GENERIC_IDENT {
|
||||
self.errors.push(
|
||||
Error::new(
|
||||
input.span(),
|
||||
"`Block: BlockT` generic parameter will be added automatically by the \
|
||||
self.errors.push(Error::new(
|
||||
input.span(),
|
||||
"`Block: BlockT` generic parameter will be added automatically by the \
|
||||
`decl_runtime_apis!` macro! If you try to use a different trait than the \
|
||||
substrate `Block` trait, please rename it locally."
|
||||
)
|
||||
)
|
||||
substrate `Block` trait, please rename it locally.",
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -965,7 +967,9 @@ pub fn decl_runtime_apis_impl(input: proc_macro::TokenStream) -> proc_macro::Tok
|
||||
// Parse all trait declarations
|
||||
let RuntimeApiDecls { decls: api_decls } = parse_macro_input!(input as RuntimeApiDecls);
|
||||
|
||||
decl_runtime_apis_impl_inner(&api_decls).unwrap_or_else(|e| e.to_compile_error()).into()
|
||||
decl_runtime_apis_impl_inner(&api_decls)
|
||||
.unwrap_or_else(|e| e.to_compile_error())
|
||||
.into()
|
||||
}
|
||||
|
||||
fn decl_runtime_apis_impl_inner(api_decls: &[ItemTrait]) -> Result<TokenStream> {
|
||||
@@ -975,13 +979,11 @@ fn decl_runtime_apis_impl_inner(api_decls: &[ItemTrait]) -> Result<TokenStream>
|
||||
let runtime_decls = generate_runtime_decls(api_decls)?;
|
||||
let client_side_decls = generate_client_side_decls(api_decls)?;
|
||||
|
||||
Ok(
|
||||
quote!(
|
||||
#hidden_includes
|
||||
Ok(quote!(
|
||||
#hidden_includes
|
||||
|
||||
#runtime_decls
|
||||
#runtime_decls
|
||||
|
||||
#client_side_decls
|
||||
)
|
||||
)
|
||||
#client_side_decls
|
||||
))
|
||||
}
|
||||
|
||||
@@ -16,12 +16,12 @@
|
||||
// limitations under the License.
|
||||
|
||||
use crate::utils::{
|
||||
generate_crate_access, generate_hidden_includes,
|
||||
generate_runtime_mod_name_for_trait, generate_method_runtime_api_impl_name,
|
||||
extract_parameter_names_types_and_borrows, generate_native_call_generator_fn_name,
|
||||
return_type_extract_type, generate_call_api_at_fn_name, prefix_function_with_trait,
|
||||
extract_all_signature_types, extract_block_type_from_trait_path, extract_impl_trait,
|
||||
AllowSelfRefInParameters, RequireQualifiedTraitPath,
|
||||
extract_parameter_names_types_and_borrows, generate_call_api_at_fn_name, generate_crate_access,
|
||||
generate_hidden_includes, generate_method_runtime_api_impl_name,
|
||||
generate_native_call_generator_fn_name, generate_runtime_mod_name_for_trait,
|
||||
prefix_function_with_trait, return_type_extract_type, AllowSelfRefInParameters,
|
||||
RequireQualifiedTraitPath,
|
||||
};
|
||||
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
@@ -29,9 +29,12 @@ use proc_macro2::{Span, TokenStream};
|
||||
use quote::quote;
|
||||
|
||||
use syn::{
|
||||
spanned::Spanned, parse_macro_input, Ident, Type, ItemImpl, Path, Signature, Attribute,
|
||||
ImplItem, parse::{Parse, ParseStream, Result, Error}, PathArguments, GenericArgument, TypePath,
|
||||
fold::{self, Fold}, parse_quote,
|
||||
fold::{self, Fold},
|
||||
parse::{Error, Parse, ParseStream, Result},
|
||||
parse_macro_input, parse_quote,
|
||||
spanned::Spanned,
|
||||
Attribute, GenericArgument, Ident, ImplItem, ItemImpl, Path, PathArguments, Signature, Type,
|
||||
TypePath,
|
||||
};
|
||||
|
||||
use std::collections::HashSet;
|
||||
@@ -66,9 +69,10 @@ fn generate_impl_call(
|
||||
signature: &Signature,
|
||||
runtime: &Type,
|
||||
input: &Ident,
|
||||
impl_trait: &Path
|
||||
impl_trait: &Path,
|
||||
) -> Result<TokenStream> {
|
||||
let params = extract_parameter_names_types_and_borrows(signature, AllowSelfRefInParameters::No)?;
|
||||
let params =
|
||||
extract_parameter_names_types_and_borrows(signature, AllowSelfRefInParameters::No)?;
|
||||
|
||||
let c = generate_crate_access(HIDDEN_INCLUDES_ID);
|
||||
let fn_name = &signature.ident;
|
||||
@@ -78,27 +82,25 @@ fn generate_impl_call(
|
||||
let ptypes = params.iter().map(|v| &v.1);
|
||||
let pborrow = params.iter().map(|v| &v.2);
|
||||
|
||||
Ok(
|
||||
quote!(
|
||||
let (#( #pnames ),*) : ( #( #ptypes ),* ) =
|
||||
match #c::DecodeLimit::decode_all_with_depth_limit(
|
||||
#c::MAX_EXTRINSIC_DEPTH,
|
||||
&#input,
|
||||
) {
|
||||
Ok(res) => res,
|
||||
Err(e) => panic!("Bad input data provided to {}: {}", #fn_name_str, e),
|
||||
};
|
||||
Ok(quote!(
|
||||
let (#( #pnames ),*) : ( #( #ptypes ),* ) =
|
||||
match #c::DecodeLimit::decode_all_with_depth_limit(
|
||||
#c::MAX_EXTRINSIC_DEPTH,
|
||||
&#input,
|
||||
) {
|
||||
Ok(res) => res,
|
||||
Err(e) => panic!("Bad input data provided to {}: {}", #fn_name_str, e),
|
||||
};
|
||||
|
||||
#[allow(deprecated)]
|
||||
<#runtime as #impl_trait>::#fn_name(#( #pborrow #pnames2 ),*)
|
||||
)
|
||||
)
|
||||
#[allow(deprecated)]
|
||||
<#runtime as #impl_trait>::#fn_name(#( #pborrow #pnames2 ),*)
|
||||
))
|
||||
}
|
||||
|
||||
/// Generate all the implementation calls for the given functions.
|
||||
fn generate_impl_calls(
|
||||
impls: &[ItemImpl],
|
||||
input: &Ident
|
||||
input: &Ident,
|
||||
) -> Result<Vec<(Ident, Ident, TokenStream, Vec<Attribute>)>> {
|
||||
let mut impl_calls = Vec::new();
|
||||
|
||||
@@ -113,12 +115,8 @@ fn generate_impl_calls(
|
||||
|
||||
for item in &impl_.items {
|
||||
if let ImplItem::Method(method) = item {
|
||||
let impl_call = generate_impl_call(
|
||||
&method.sig,
|
||||
&impl_.self_ty,
|
||||
input,
|
||||
&impl_trait
|
||||
)?;
|
||||
let impl_call =
|
||||
generate_impl_call(&method.sig, &impl_.self_ty, input, &impl_trait)?;
|
||||
|
||||
impl_calls.push((
|
||||
impl_trait_ident.clone(),
|
||||
@@ -137,15 +135,16 @@ fn generate_impl_calls(
|
||||
fn generate_dispatch_function(impls: &[ItemImpl]) -> Result<TokenStream> {
|
||||
let data = Ident::new("__sp_api__input_data", Span::call_site());
|
||||
let c = generate_crate_access(HIDDEN_INCLUDES_ID);
|
||||
let impl_calls = generate_impl_calls(impls, &data)?
|
||||
.into_iter()
|
||||
.map(|(trait_, fn_name, impl_, attrs)| {
|
||||
let name = prefix_function_with_trait(&trait_, &fn_name);
|
||||
quote!(
|
||||
#( #attrs )*
|
||||
#name => Some(#c::Encode::encode(&{ #impl_ })),
|
||||
)
|
||||
});
|
||||
let impl_calls =
|
||||
generate_impl_calls(impls, &data)?
|
||||
.into_iter()
|
||||
.map(|(trait_, fn_name, impl_, attrs)| {
|
||||
let name = prefix_function_with_trait(&trait_, &fn_name);
|
||||
quote!(
|
||||
#( #attrs )*
|
||||
#name => Some(#c::Encode::encode(&{ #impl_ })),
|
||||
)
|
||||
});
|
||||
|
||||
Ok(quote!(
|
||||
#[cfg(feature = "std")]
|
||||
@@ -163,34 +162,33 @@ fn generate_wasm_interface(impls: &[ItemImpl]) -> Result<TokenStream> {
|
||||
let input = Ident::new("input", Span::call_site());
|
||||
let c = generate_crate_access(HIDDEN_INCLUDES_ID);
|
||||
|
||||
let impl_calls = generate_impl_calls(impls, &input)?
|
||||
.into_iter()
|
||||
.map(|(trait_, fn_name, impl_, attrs)| {
|
||||
let fn_name = Ident::new(
|
||||
&prefix_function_with_trait(&trait_, &fn_name),
|
||||
Span::call_site()
|
||||
);
|
||||
let impl_calls =
|
||||
generate_impl_calls(impls, &input)?
|
||||
.into_iter()
|
||||
.map(|(trait_, fn_name, impl_, attrs)| {
|
||||
let fn_name =
|
||||
Ident::new(&prefix_function_with_trait(&trait_, &fn_name), Span::call_site());
|
||||
|
||||
quote!(
|
||||
#( #attrs )*
|
||||
#[cfg(not(feature = "std"))]
|
||||
#[no_mangle]
|
||||
pub unsafe fn #fn_name(input_data: *mut u8, input_len: usize) -> u64 {
|
||||
let mut #input = if input_len == 0 {
|
||||
&[0u8; 0]
|
||||
} else {
|
||||
unsafe {
|
||||
#c::slice::from_raw_parts(input_data, input_len)
|
||||
}
|
||||
};
|
||||
quote!(
|
||||
#( #attrs )*
|
||||
#[cfg(not(feature = "std"))]
|
||||
#[no_mangle]
|
||||
pub unsafe fn #fn_name(input_data: *mut u8, input_len: usize) -> u64 {
|
||||
let mut #input = if input_len == 0 {
|
||||
&[0u8; 0]
|
||||
} else {
|
||||
unsafe {
|
||||
#c::slice::from_raw_parts(input_data, input_len)
|
||||
}
|
||||
};
|
||||
|
||||
#c::init_runtime_logger();
|
||||
#c::init_runtime_logger();
|
||||
|
||||
let output = (move || { #impl_ })();
|
||||
#c::to_substrate_wasm_fn_return_value(&output)
|
||||
}
|
||||
)
|
||||
});
|
||||
let output = (move || { #impl_ })();
|
||||
#c::to_substrate_wasm_fn_return_value(&output)
|
||||
}
|
||||
)
|
||||
});
|
||||
|
||||
Ok(quote!( #( #impl_calls )* ))
|
||||
}
|
||||
@@ -414,7 +412,6 @@ fn generate_api_impl_for_runtime(impls: &[ItemImpl]) -> Result<TokenStream> {
|
||||
Ok(quote!( #( #impls_prepared )* ))
|
||||
}
|
||||
|
||||
|
||||
/// Auxiliary data structure that is used to convert `impl Api for Runtime` to
|
||||
/// `impl Api for RuntimeApi`.
|
||||
/// This requires us to replace the runtime `Block` with the node `Block`,
|
||||
@@ -430,11 +427,8 @@ struct ApiRuntimeImplToApiRuntimeApiImpl<'a> {
|
||||
|
||||
impl<'a> Fold for ApiRuntimeImplToApiRuntimeApiImpl<'a> {
|
||||
fn fold_type_path(&mut self, input: TypePath) -> TypePath {
|
||||
let new_ty_path = if input == *self.runtime_block {
|
||||
parse_quote!( __SR_API_BLOCK__ )
|
||||
} else {
|
||||
input
|
||||
};
|
||||
let new_ty_path =
|
||||
if input == *self.runtime_block { parse_quote!(__SR_API_BLOCK__) } else { input };
|
||||
|
||||
fold::fold_type_path(self, new_ty_path)
|
||||
}
|
||||
@@ -451,12 +445,18 @@ impl<'a> Fold for ApiRuntimeImplToApiRuntimeApiImpl<'a> {
|
||||
|
||||
// Generate the access to the native parameters
|
||||
let param_tuple_access = if input.sig.inputs.len() == 1 {
|
||||
vec![ quote!( p ) ]
|
||||
vec![quote!(p)]
|
||||
} else {
|
||||
input.sig.inputs.iter().enumerate().map(|(i, _)| {
|
||||
let i = syn::Index::from(i);
|
||||
quote!( p.#i )
|
||||
}).collect::<Vec<_>>()
|
||||
input
|
||||
.sig
|
||||
.inputs
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, _)| {
|
||||
let i = syn::Index::from(i);
|
||||
quote!( p.#i )
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
|
||||
let (param_types, error) = match extract_parameter_names_types_and_borrows(
|
||||
@@ -464,12 +464,14 @@ impl<'a> Fold for ApiRuntimeImplToApiRuntimeApiImpl<'a> {
|
||||
AllowSelfRefInParameters::No,
|
||||
) {
|
||||
Ok(res) => (
|
||||
res.into_iter().map(|v| {
|
||||
let ty = v.1;
|
||||
let borrow = v.2;
|
||||
quote!( #borrow #ty )
|
||||
}).collect::<Vec<_>>(),
|
||||
None
|
||||
res.into_iter()
|
||||
.map(|v| {
|
||||
let ty = v.1;
|
||||
let borrow = v.2;
|
||||
quote!( #borrow #ty )
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
None,
|
||||
),
|
||||
Err(e) => (Vec::new(), Some(e.to_compile_error())),
|
||||
};
|
||||
@@ -483,10 +485,8 @@ impl<'a> Fold for ApiRuntimeImplToApiRuntimeApiImpl<'a> {
|
||||
params_encoded: Vec<u8>,
|
||||
};
|
||||
|
||||
input.sig.ident = generate_method_runtime_api_impl_name(
|
||||
&self.impl_trait,
|
||||
&input.sig.ident,
|
||||
);
|
||||
input.sig.ident =
|
||||
generate_method_runtime_api_impl_name(&self.impl_trait, &input.sig.ident);
|
||||
let ret_type = return_type_extract_type(&input.sig.output);
|
||||
|
||||
// Generate the correct return type.
|
||||
@@ -544,43 +544,34 @@ impl<'a> Fold for ApiRuntimeImplToApiRuntimeApiImpl<'a> {
|
||||
let crate_ = generate_crate_access(HIDDEN_INCLUDES_ID);
|
||||
|
||||
// Implement the trait for the `RuntimeApiImpl`
|
||||
input.self_ty = Box::new(
|
||||
parse_quote!( RuntimeApiImpl<__SR_API_BLOCK__, RuntimeApiImplCall> )
|
||||
);
|
||||
input.self_ty =
|
||||
Box::new(parse_quote!( RuntimeApiImpl<__SR_API_BLOCK__, RuntimeApiImplCall> ));
|
||||
|
||||
input.generics.params.push(parse_quote!(
|
||||
__SR_API_BLOCK__: #crate_::BlockT + std::panic::UnwindSafe +
|
||||
std::panic::RefUnwindSafe
|
||||
));
|
||||
input.generics.params.push(
|
||||
parse_quote!(
|
||||
__SR_API_BLOCK__: #crate_::BlockT + std::panic::UnwindSafe +
|
||||
std::panic::RefUnwindSafe
|
||||
)
|
||||
);
|
||||
input.generics.params.push(
|
||||
parse_quote!( RuntimeApiImplCall: #crate_::CallApiAt<__SR_API_BLOCK__> + 'static )
|
||||
parse_quote!( RuntimeApiImplCall: #crate_::CallApiAt<__SR_API_BLOCK__> + 'static ),
|
||||
);
|
||||
|
||||
let where_clause = input.generics.make_where_clause();
|
||||
|
||||
where_clause.predicates.push(
|
||||
parse_quote! {
|
||||
RuntimeApiImplCall::StateBackend:
|
||||
#crate_::StateBackend<#crate_::HashFor<__SR_API_BLOCK__>>
|
||||
}
|
||||
);
|
||||
where_clause.predicates.push(parse_quote! {
|
||||
RuntimeApiImplCall::StateBackend:
|
||||
#crate_::StateBackend<#crate_::HashFor<__SR_API_BLOCK__>>
|
||||
});
|
||||
|
||||
// Require that all types used in the function signatures are unwind safe.
|
||||
extract_all_signature_types(&input.items).iter().for_each(|i| {
|
||||
where_clause.predicates.push(
|
||||
parse_quote! {
|
||||
#i: std::panic::UnwindSafe + std::panic::RefUnwindSafe
|
||||
}
|
||||
);
|
||||
where_clause.predicates.push(parse_quote! {
|
||||
#i: std::panic::UnwindSafe + std::panic::RefUnwindSafe
|
||||
});
|
||||
});
|
||||
|
||||
where_clause.predicates.push(
|
||||
parse_quote! {
|
||||
__SR_API_BLOCK__::Header: std::panic::UnwindSafe + std::panic::RefUnwindSafe
|
||||
}
|
||||
);
|
||||
where_clause.predicates.push(parse_quote! {
|
||||
__SR_API_BLOCK__::Header: std::panic::UnwindSafe + std::panic::RefUnwindSafe
|
||||
});
|
||||
|
||||
input.attrs = filter_cfg_attrs(&input.attrs);
|
||||
|
||||
@@ -650,14 +641,12 @@ fn generate_runtime_api_versions(impls: &[ItemImpl]) -> Result<TokenStream> {
|
||||
|
||||
let span = trait_.span();
|
||||
if !processed_traits.insert(trait_) {
|
||||
return Err(
|
||||
Error::new(
|
||||
span,
|
||||
"Two traits with the same name detected! \
|
||||
return Err(Error::new(
|
||||
span,
|
||||
"Two traits with the same name detected! \
|
||||
The trait name is used to generate its ID. \
|
||||
Please rename one trait at the declaration!"
|
||||
)
|
||||
)
|
||||
Please rename one trait at the declaration!",
|
||||
))
|
||||
}
|
||||
|
||||
let id: Path = parse_quote!( #path ID );
|
||||
@@ -692,7 +681,9 @@ pub fn impl_runtime_apis_impl(input: proc_macro::TokenStream) -> proc_macro::Tok
|
||||
// Parse all impl blocks
|
||||
let RuntimeApiImpls { impls: api_impls } = parse_macro_input!(input as RuntimeApiImpls);
|
||||
|
||||
impl_runtime_apis_impl_inner(&api_impls).unwrap_or_else(|e| e.to_compile_error()).into()
|
||||
impl_runtime_apis_impl_inner(&api_impls)
|
||||
.unwrap_or_else(|e| e.to_compile_error())
|
||||
.into()
|
||||
}
|
||||
|
||||
fn impl_runtime_apis_impl_inner(api_impls: &[ItemImpl]) -> Result<TokenStream> {
|
||||
@@ -704,27 +695,25 @@ fn impl_runtime_apis_impl_inner(api_impls: &[ItemImpl]) -> Result<TokenStream> {
|
||||
let wasm_interface = generate_wasm_interface(api_impls)?;
|
||||
let api_impls_for_runtime_api = generate_api_impl_for_runtime_api(api_impls)?;
|
||||
|
||||
Ok(
|
||||
quote!(
|
||||
#hidden_includes
|
||||
Ok(quote!(
|
||||
#hidden_includes
|
||||
|
||||
#base_runtime_api
|
||||
#base_runtime_api
|
||||
|
||||
#api_impls_for_runtime
|
||||
#api_impls_for_runtime
|
||||
|
||||
#api_impls_for_runtime_api
|
||||
#api_impls_for_runtime_api
|
||||
|
||||
#runtime_api_versions
|
||||
#runtime_api_versions
|
||||
|
||||
pub mod api {
|
||||
use super::*;
|
||||
pub mod api {
|
||||
use super::*;
|
||||
|
||||
#dispatch_impl
|
||||
#dispatch_impl
|
||||
|
||||
#wasm_interface
|
||||
}
|
||||
)
|
||||
)
|
||||
#wasm_interface
|
||||
}
|
||||
))
|
||||
}
|
||||
|
||||
// Filters all attributes except the cfg ones.
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
mod decl_runtime_apis;
|
||||
mod impl_runtime_apis;
|
||||
mod mock_impl_runtime_apis;
|
||||
mod decl_runtime_apis;
|
||||
mod utils;
|
||||
|
||||
#[proc_macro]
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
// limitations under the License.
|
||||
|
||||
use crate::utils::{
|
||||
generate_crate_access, generate_hidden_includes,
|
||||
generate_method_runtime_api_impl_name, extract_parameter_names_types_and_borrows,
|
||||
return_type_extract_type, extract_block_type_from_trait_path, extract_impl_trait,
|
||||
AllowSelfRefInParameters, RequireQualifiedTraitPath,
|
||||
extract_block_type_from_trait_path, extract_impl_trait,
|
||||
extract_parameter_names_types_and_borrows, generate_crate_access, generate_hidden_includes,
|
||||
generate_method_runtime_api_impl_name, return_type_extract_type, AllowSelfRefInParameters,
|
||||
RequireQualifiedTraitPath,
|
||||
};
|
||||
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
@@ -27,8 +27,11 @@ use proc_macro2::{Span, TokenStream};
|
||||
use quote::{quote, quote_spanned};
|
||||
|
||||
use syn::{
|
||||
spanned::Spanned, parse_macro_input, Ident, Type, ItemImpl, TypePath, parse_quote,
|
||||
parse::{Parse, ParseStream, Result, Error}, fold::{self, Fold}, Attribute, Pat,
|
||||
fold::{self, Fold},
|
||||
parse::{Error, Parse, ParseStream, Result},
|
||||
parse_macro_input, parse_quote,
|
||||
spanned::Spanned,
|
||||
Attribute, Ident, ItemImpl, Pat, Type, TypePath,
|
||||
};
|
||||
|
||||
/// Unique identifier used to make the hidden includes unique for this macro.
|
||||
@@ -62,10 +65,7 @@ impl Parse for RuntimeApiImpls {
|
||||
}
|
||||
|
||||
/// Implement the `ApiExt` trait and the `Core` runtime api.
|
||||
fn implement_common_api_traits(
|
||||
block_type: TypePath,
|
||||
self_ty: Type,
|
||||
) -> Result<TokenStream> {
|
||||
fn implement_common_api_traits(block_type: TypePath, self_ty: Type) -> Result<TokenStream> {
|
||||
let crate_ = generate_crate_access(HIDDEN_INCLUDES_ID);
|
||||
|
||||
Ok(quote!(
|
||||
@@ -168,11 +168,13 @@ fn implement_common_api_traits(
|
||||
/// If the attribute was found, it will be automatically removed from the vec.
|
||||
fn has_advanced_attribute(attributes: &mut Vec<Attribute>) -> bool {
|
||||
let mut found = false;
|
||||
attributes.retain(|attr| if attr.path.is_ident(ADVANCED_ATTRIBUTE) {
|
||||
found = true;
|
||||
false
|
||||
} else {
|
||||
true
|
||||
attributes.retain(|attr| {
|
||||
if attr.path.is_ident(ADVANCED_ATTRIBUTE) {
|
||||
found = true;
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
});
|
||||
|
||||
found
|
||||
@@ -214,7 +216,7 @@ fn get_at_param_name(
|
||||
let name = param_names.remove(0);
|
||||
Ok((quote!( #name ), ptype_and_borrows.0))
|
||||
} else {
|
||||
Ok((quote!( _ ), default_block_id_type.clone()))
|
||||
Ok((quote!(_), default_block_id_type.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,24 +237,27 @@ impl<'a> Fold for FoldRuntimeApiImpl<'a> {
|
||||
let is_advanced = has_advanced_attribute(&mut input.attrs);
|
||||
let mut errors = Vec::new();
|
||||
|
||||
let (mut param_names, mut param_types_and_borrows) = match extract_parameter_names_types_and_borrows(
|
||||
&input.sig,
|
||||
AllowSelfRefInParameters::YesButIgnore,
|
||||
) {
|
||||
Ok(res) => (
|
||||
res.iter().map(|v| v.0.clone()).collect::<Vec<_>>(),
|
||||
res.iter().map(|v| {
|
||||
let ty = &v.1;
|
||||
let borrow = &v.2;
|
||||
(quote_spanned!(ty.span() => #borrow #ty ), v.2.is_some())
|
||||
}).collect::<Vec<_>>(),
|
||||
),
|
||||
Err(e) => {
|
||||
errors.push(e.to_compile_error());
|
||||
let (mut param_names, mut param_types_and_borrows) =
|
||||
match extract_parameter_names_types_and_borrows(
|
||||
&input.sig,
|
||||
AllowSelfRefInParameters::YesButIgnore,
|
||||
) {
|
||||
Ok(res) => (
|
||||
res.iter().map(|v| v.0.clone()).collect::<Vec<_>>(),
|
||||
res.iter()
|
||||
.map(|v| {
|
||||
let ty = &v.1;
|
||||
let borrow = &v.2;
|
||||
(quote_spanned!(ty.span() => #borrow #ty ), v.2.is_some())
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
),
|
||||
Err(e) => {
|
||||
errors.push(e.to_compile_error());
|
||||
|
||||
(Default::default(), Default::default())
|
||||
}
|
||||
};
|
||||
(Default::default(), Default::default())
|
||||
},
|
||||
};
|
||||
|
||||
let block_type = &self.block_type;
|
||||
let block_id_type = quote!( &#crate_::BlockId<#block_type> );
|
||||
@@ -267,8 +272,8 @@ impl<'a> Fold for FoldRuntimeApiImpl<'a> {
|
||||
Ok(res) => res,
|
||||
Err(e) => {
|
||||
errors.push(e.to_compile_error());
|
||||
(quote!( _ ), block_id_type)
|
||||
}
|
||||
(quote!(_), block_id_type)
|
||||
},
|
||||
};
|
||||
|
||||
let param_types = param_types_and_borrows.iter().map(|v| &v.0);
|
||||
@@ -281,10 +286,8 @@ impl<'a> Fold for FoldRuntimeApiImpl<'a> {
|
||||
_: Vec<u8>,
|
||||
};
|
||||
|
||||
input.sig.ident = generate_method_runtime_api_impl_name(
|
||||
&self.impl_trait,
|
||||
&input.sig.ident,
|
||||
);
|
||||
input.sig.ident =
|
||||
generate_method_runtime_api_impl_name(&self.impl_trait, &input.sig.ident);
|
||||
|
||||
// When using advanced, the user needs to declare the correct return type on its own,
|
||||
// otherwise do it for the user.
|
||||
@@ -360,28 +363,24 @@ fn generate_runtime_api_impls(impls: &[ItemImpl]) -> Result<GeneratedRuntimeApiI
|
||||
let block_type = extract_block_type_from_trait_path(impl_trait_path)?;
|
||||
|
||||
self_ty = match self_ty.take() {
|
||||
Some(self_ty) => {
|
||||
Some(self_ty) =>
|
||||
if self_ty == impl_.self_ty {
|
||||
Some(self_ty)
|
||||
} else {
|
||||
let mut error =Error::new(
|
||||
let mut error = Error::new(
|
||||
impl_.self_ty.span(),
|
||||
"Self type should not change between runtime apis",
|
||||
);
|
||||
|
||||
error.combine(Error::new(
|
||||
self_ty.span(),
|
||||
"First self type found here",
|
||||
));
|
||||
error.combine(Error::new(self_ty.span(), "First self type found here"));
|
||||
|
||||
return Err(error)
|
||||
}
|
||||
},
|
||||
},
|
||||
None => Some(impl_.self_ty.clone()),
|
||||
};
|
||||
|
||||
global_block_type = match global_block_type.take() {
|
||||
Some(global_block_type) => {
|
||||
Some(global_block_type) =>
|
||||
if global_block_type == *block_type {
|
||||
Some(global_block_type)
|
||||
} else {
|
||||
@@ -396,15 +395,11 @@ fn generate_runtime_api_impls(impls: &[ItemImpl]) -> Result<GeneratedRuntimeApiI
|
||||
));
|
||||
|
||||
return Err(error)
|
||||
}
|
||||
},
|
||||
},
|
||||
None => Some(block_type.clone()),
|
||||
};
|
||||
|
||||
let mut visitor = FoldRuntimeApiImpl {
|
||||
block_type,
|
||||
impl_trait: &impl_trait.ident,
|
||||
};
|
||||
let mut visitor = FoldRuntimeApiImpl { block_type, impl_trait: &impl_trait.ident };
|
||||
|
||||
result.push(visitor.fold_item_impl(impl_.clone()));
|
||||
}
|
||||
@@ -421,7 +416,9 @@ pub fn mock_impl_runtime_apis_impl(input: proc_macro::TokenStream) -> proc_macro
|
||||
// Parse all impl blocks
|
||||
let RuntimeApiImpls { impls: api_impls } = parse_macro_input!(input as RuntimeApiImpls);
|
||||
|
||||
mock_impl_runtime_apis_impl_inner(&api_impls).unwrap_or_else(|e| e.to_compile_error()).into()
|
||||
mock_impl_runtime_apis_impl_inner(&api_impls)
|
||||
.unwrap_or_else(|e| e.to_compile_error())
|
||||
.into()
|
||||
}
|
||||
|
||||
fn mock_impl_runtime_apis_impl_inner(api_impls: &[ItemImpl]) -> Result<TokenStream> {
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use proc_macro2::{TokenStream, Span};
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
|
||||
use syn::{
|
||||
Result, Ident, Signature, parse_quote, Type, Pat, spanned::Spanned, FnArg, Error, token::And,
|
||||
ImplItem, ReturnType, PathArguments, Path, GenericArgument, TypePath, ItemImpl,
|
||||
parse_quote, spanned::Spanned, token::And, Error, FnArg, GenericArgument, Ident, ImplItem,
|
||||
ItemImpl, Pat, Path, PathArguments, Result, ReturnType, Signature, Type, TypePath,
|
||||
};
|
||||
|
||||
use quote::quote;
|
||||
@@ -49,18 +49,19 @@ pub fn generate_hidden_includes(unique_id: &'static str) -> TokenStream {
|
||||
Err(e) => {
|
||||
let err = Error::new(Span::call_site(), e).to_compile_error();
|
||||
quote!( #err )
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Generates the access to the `sc_client` crate.
|
||||
pub fn generate_crate_access(unique_id: &'static str) -> TokenStream {
|
||||
if env::var("CARGO_PKG_NAME").unwrap() == "sp-api" {
|
||||
quote!( sp_api )
|
||||
quote!(sp_api)
|
||||
} else {
|
||||
let mod_name = generate_hidden_includes_mod_name(unique_id);
|
||||
quote!( self::#mod_name::sp_api )
|
||||
}.into()
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
/// Generates the name of the module that contains the trait declaration for the runtime.
|
||||
@@ -76,7 +77,7 @@ pub fn generate_method_runtime_api_impl_name(trait_: &Ident, method: &Ident) ->
|
||||
/// Get the type of a `syn::ReturnType`.
|
||||
pub fn return_type_extract_type(rt: &ReturnType) -> Type {
|
||||
match rt {
|
||||
ReturnType::Default => parse_quote!( () ),
|
||||
ReturnType::Default => parse_quote!(()),
|
||||
ReturnType::Type(_, ref ty) => *ty.clone(),
|
||||
}
|
||||
}
|
||||
@@ -84,10 +85,13 @@ pub fn return_type_extract_type(rt: &ReturnType) -> Type {
|
||||
/// Replace the `_` (wild card) parameter names in the given signature with unique identifiers.
|
||||
pub fn replace_wild_card_parameter_names(input: &mut Signature) {
|
||||
let mut generated_pattern_counter = 0;
|
||||
input.inputs.iter_mut().for_each(|arg| if let FnArg::Typed(arg) = arg {
|
||||
arg.pat = Box::new(
|
||||
generate_unique_pattern((*arg.pat).clone(), &mut generated_pattern_counter),
|
||||
);
|
||||
input.inputs.iter_mut().for_each(|arg| {
|
||||
if let FnArg::Typed(arg) = arg {
|
||||
arg.pat = Box::new(generate_unique_pattern(
|
||||
(*arg.pat).clone(),
|
||||
&mut generated_pattern_counter,
|
||||
));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -101,7 +105,7 @@ pub fn fold_fn_decl_for_client_side(
|
||||
|
||||
// Add `&self, at:& BlockId` as parameters to each function at the beginning.
|
||||
input.inputs.insert(0, parse_quote!( __runtime_api_at_param__: &#block_id ));
|
||||
input.inputs.insert(0, parse_quote!( &self ));
|
||||
input.inputs.insert(0, parse_quote!(&self));
|
||||
|
||||
// Wrap the output in a `Result`
|
||||
input.output = {
|
||||
@@ -114,10 +118,8 @@ pub fn fold_fn_decl_for_client_side(
|
||||
pub fn generate_unique_pattern(pat: Pat, counter: &mut u32) -> Pat {
|
||||
match pat {
|
||||
Pat::Wild(_) => {
|
||||
let generated_name = Ident::new(
|
||||
&format!("__runtime_api_generated_name_{}__", counter),
|
||||
pat.span(),
|
||||
);
|
||||
let generated_name =
|
||||
Ident::new(&format!("__runtime_api_generated_name_{}__", counter), pat.span());
|
||||
*counter += 1;
|
||||
|
||||
parse_quote!( #generated_name )
|
||||
@@ -145,26 +147,20 @@ pub fn extract_parameter_names_types_and_borrows(
|
||||
match input {
|
||||
FnArg::Typed(arg) => {
|
||||
let (ty, borrow) = match &*arg.ty {
|
||||
Type::Reference(t) => {
|
||||
((*t.elem).clone(), Some(t.and_token))
|
||||
},
|
||||
t => { (t.clone(), None) },
|
||||
Type::Reference(t) => ((*t.elem).clone(), Some(t.and_token)),
|
||||
t => (t.clone(), None),
|
||||
};
|
||||
|
||||
let name = generate_unique_pattern(
|
||||
(*arg.pat).clone(),
|
||||
&mut generated_pattern_counter,
|
||||
);
|
||||
let name =
|
||||
generate_unique_pattern((*arg.pat).clone(), &mut generated_pattern_counter);
|
||||
result.push((name, ty, borrow));
|
||||
},
|
||||
FnArg::Receiver(_) if matches!(allow_self, AllowSelfRefInParameters::No) => {
|
||||
return Err(Error::new(input.span(), "`self` parameter not supported!"))
|
||||
},
|
||||
FnArg::Receiver(recv) => {
|
||||
FnArg::Receiver(_) if matches!(allow_self, AllowSelfRefInParameters::No) =>
|
||||
return Err(Error::new(input.span(), "`self` parameter not supported!")),
|
||||
FnArg::Receiver(recv) =>
|
||||
if recv.mutability.is_some() || recv.reference.is_none() {
|
||||
return Err(Error::new(recv.span(), "Only `&self` is supported!"))
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +186,8 @@ pub fn prefix_function_with_trait<F: ToString>(trait_: &Ident, function: &F) ->
|
||||
///
|
||||
/// If a type is a reference, the inner type is extracted (without the reference).
|
||||
pub fn extract_all_signature_types(items: &[ImplItem]) -> Vec<Type> {
|
||||
items.iter()
|
||||
items
|
||||
.iter()
|
||||
.filter_map(|i| match i {
|
||||
ImplItem::Method(method) => Some(&method.sig),
|
||||
_ => None,
|
||||
@@ -201,13 +198,17 @@ pub fn extract_all_signature_types(items: &[ImplItem]) -> Vec<Type> {
|
||||
ReturnType::Type(_, ty) => Some((**ty).clone()),
|
||||
};
|
||||
|
||||
sig.inputs.iter().filter_map(|i| match i {
|
||||
FnArg::Typed(arg) => Some(&arg.ty),
|
||||
_ => None,
|
||||
}).map(|ty| match &**ty {
|
||||
Type::Reference(t) => (*t.elem).clone(),
|
||||
_ => (**ty).clone(),
|
||||
}).chain(ret_ty)
|
||||
sig.inputs
|
||||
.iter()
|
||||
.filter_map(|i| match i {
|
||||
FnArg::Typed(arg) => Some(&arg.ty),
|
||||
_ => None,
|
||||
})
|
||||
.map(|ty| match &**ty {
|
||||
Type::Reference(t) => (*t.elem).clone(),
|
||||
_ => (**ty).clone(),
|
||||
})
|
||||
.chain(ret_ty)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
@@ -223,19 +224,20 @@ pub fn extract_block_type_from_trait_path(trait_: &Path) -> Result<&TypePath> {
|
||||
.ok_or_else(|| Error::new(span, "Empty path not supported"))?;
|
||||
|
||||
match &generics.arguments {
|
||||
PathArguments::AngleBracketed(ref args) => {
|
||||
args.args.first().and_then(|v| match v {
|
||||
PathArguments::AngleBracketed(ref args) => args
|
||||
.args
|
||||
.first()
|
||||
.and_then(|v| match v {
|
||||
GenericArgument::Type(Type::Path(ref block)) => Some(block),
|
||||
_ => None
|
||||
}).ok_or_else(|| Error::new(args.span(), "Missing `Block` generic parameter."))
|
||||
},
|
||||
_ => None,
|
||||
})
|
||||
.ok_or_else(|| Error::new(args.span(), "Missing `Block` generic parameter.")),
|
||||
PathArguments::None => {
|
||||
let span = trait_.segments.last().as_ref().unwrap().span();
|
||||
Err(Error::new(span, "Missing `Block` generic parameter."))
|
||||
},
|
||||
PathArguments::Parenthesized(_) => {
|
||||
Err(Error::new(generics.arguments.span(), "Unexpected parentheses in path!"))
|
||||
},
|
||||
PathArguments::Parenthesized(_) =>
|
||||
Err(Error::new(generics.arguments.span(), "Unexpected parentheses in path!")),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,19 +254,20 @@ pub fn extract_impl_trait<'a>(
|
||||
impl_: &'a ItemImpl,
|
||||
require: RequireQualifiedTraitPath,
|
||||
) -> Result<&'a Path> {
|
||||
impl_.trait_.as_ref().map(|v| &v.1).ok_or_else(
|
||||
|| Error::new(impl_.span(), "Only implementation of traits are supported!")
|
||||
).and_then(|p| {
|
||||
if p.segments.len() > 1 || matches!(require, RequireQualifiedTraitPath::No) {
|
||||
Ok(p)
|
||||
} else {
|
||||
Err(
|
||||
Error::new(
|
||||
impl_
|
||||
.trait_
|
||||
.as_ref()
|
||||
.map(|v| &v.1)
|
||||
.ok_or_else(|| Error::new(impl_.span(), "Only implementation of traits are supported!"))
|
||||
.and_then(|p| {
|
||||
if p.segments.len() > 1 || matches!(require, RequireQualifiedTraitPath::No) {
|
||||
Ok(p)
|
||||
} else {
|
||||
Err(Error::new(
|
||||
p.span(),
|
||||
"The implemented trait has to be referenced with a path, \
|
||||
e.g. `impl client::Core for Runtime`."
|
||||
)
|
||||
)
|
||||
}
|
||||
})
|
||||
e.g. `impl client::Core for Runtime`.",
|
||||
))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -70,13 +70,7 @@
|
||||
extern crate self as sp_api;
|
||||
|
||||
#[doc(hidden)]
|
||||
#[cfg(feature = "std")]
|
||||
pub use sp_state_machine::{
|
||||
OverlayedChanges, StorageProof, Backend as StateBackend, ChangesTrieState, InMemoryBackend,
|
||||
};
|
||||
#[doc(hidden)]
|
||||
#[cfg(feature = "std")]
|
||||
pub use sp_core::NativeOrEncoded;
|
||||
pub use codec::{self, Decode, DecodeLimit, Encode};
|
||||
#[doc(hidden)]
|
||||
#[cfg(feature = "std")]
|
||||
pub use hash_db::Hasher;
|
||||
@@ -84,27 +78,34 @@ pub use hash_db::Hasher;
|
||||
#[cfg(not(feature = "std"))]
|
||||
pub use sp_core::to_substrate_wasm_fn_return_value;
|
||||
#[doc(hidden)]
|
||||
pub use sp_runtime::{
|
||||
traits::{
|
||||
Block as BlockT, GetNodeBlockType, GetRuntimeBlockType, HashFor, NumberFor,
|
||||
Header as HeaderT, Hash as HashT,
|
||||
},
|
||||
generic::BlockId, transaction_validity::TransactionValidity, RuntimeString, TransactionOutcome,
|
||||
};
|
||||
#[cfg(feature = "std")]
|
||||
pub use sp_core::NativeOrEncoded;
|
||||
use sp_core::OpaqueMetadata;
|
||||
#[doc(hidden)]
|
||||
pub use sp_core::{offchain, ExecutionContext};
|
||||
#[doc(hidden)]
|
||||
pub use sp_version::{ApiId, RuntimeVersion, ApisVec, create_apis_vec};
|
||||
pub use sp_runtime::{
|
||||
generic::BlockId,
|
||||
traits::{
|
||||
Block as BlockT, GetNodeBlockType, GetRuntimeBlockType, Hash as HashT, HashFor,
|
||||
Header as HeaderT, NumberFor,
|
||||
},
|
||||
transaction_validity::TransactionValidity,
|
||||
RuntimeString, TransactionOutcome,
|
||||
};
|
||||
#[doc(hidden)]
|
||||
pub use sp_std::{slice, mem};
|
||||
#[cfg(feature = "std")]
|
||||
pub use sp_state_machine::{
|
||||
Backend as StateBackend, ChangesTrieState, InMemoryBackend, OverlayedChanges, StorageProof,
|
||||
};
|
||||
#[cfg(feature = "std")]
|
||||
use sp_std::result;
|
||||
#[doc(hidden)]
|
||||
pub use codec::{Encode, Decode, DecodeLimit, self};
|
||||
use sp_core::OpaqueMetadata;
|
||||
pub use sp_std::{mem, slice};
|
||||
#[doc(hidden)]
|
||||
pub use sp_version::{create_apis_vec, ApiId, ApisVec, RuntimeVersion};
|
||||
#[cfg(feature = "std")]
|
||||
use std::{panic::UnwindSafe, cell::RefCell};
|
||||
|
||||
use std::{cell::RefCell, panic::UnwindSafe};
|
||||
|
||||
/// Maximum nesting level for extrinsics.
|
||||
pub const MAX_EXTRINSIC_DEPTH: u32 = 256;
|
||||
@@ -386,18 +387,18 @@ pub type ProofRecorder<B> = sp_state_machine::ProofRecorder<<B as BlockT>::Hash>
|
||||
|
||||
/// A type that is used as cache for the storage transactions.
|
||||
#[cfg(feature = "std")]
|
||||
pub type StorageTransactionCache<Block, Backend> =
|
||||
sp_state_machine::StorageTransactionCache<
|
||||
<Backend as StateBackend<HashFor<Block>>>::Transaction, HashFor<Block>, NumberFor<Block>
|
||||
>;
|
||||
pub type StorageTransactionCache<Block, Backend> = sp_state_machine::StorageTransactionCache<
|
||||
<Backend as StateBackend<HashFor<Block>>>::Transaction,
|
||||
HashFor<Block>,
|
||||
NumberFor<Block>,
|
||||
>;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub type StorageChanges<SBackend, Block> =
|
||||
sp_state_machine::StorageChanges<
|
||||
<SBackend as StateBackend<HashFor<Block>>>::Transaction,
|
||||
HashFor<Block>,
|
||||
NumberFor<Block>
|
||||
>;
|
||||
pub type StorageChanges<SBackend, Block> = sp_state_machine::StorageChanges<
|
||||
<SBackend as StateBackend<HashFor<Block>>>::Transaction,
|
||||
HashFor<Block>,
|
||||
NumberFor<Block>,
|
||||
>;
|
||||
|
||||
/// Extract the state backend type for a type that implements `ProvideRuntimeApi`.
|
||||
#[cfg(feature = "std")]
|
||||
@@ -463,29 +464,31 @@ pub trait ApiExt<Block: BlockT> {
|
||||
/// Depending on the outcome of the closure, the transaction is committed or rolled-back.
|
||||
///
|
||||
/// The internal result of the closure is returned afterwards.
|
||||
fn execute_in_transaction<F: FnOnce(&Self) -> TransactionOutcome<R>, R>(
|
||||
&self,
|
||||
call: F,
|
||||
) -> R where Self: Sized;
|
||||
fn execute_in_transaction<F: FnOnce(&Self) -> TransactionOutcome<R>, R>(&self, call: F) -> R
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
/// Checks if the given api is implemented and versions match.
|
||||
fn has_api<A: RuntimeApiInfo + ?Sized>(
|
||||
&self,
|
||||
at: &BlockId<Block>,
|
||||
) -> Result<bool, ApiError> where Self: Sized;
|
||||
fn has_api<A: RuntimeApiInfo + ?Sized>(&self, at: &BlockId<Block>) -> Result<bool, ApiError>
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
/// Check if the given api is implemented and the version passes a predicate.
|
||||
fn has_api_with<A: RuntimeApiInfo + ?Sized, P: Fn(u32) -> bool>(
|
||||
&self,
|
||||
at: &BlockId<Block>,
|
||||
pred: P,
|
||||
) -> Result<bool, ApiError> where Self: Sized;
|
||||
) -> Result<bool, ApiError>
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
/// Returns the version of the given api.
|
||||
fn api_version<A: RuntimeApiInfo + ?Sized>(
|
||||
&self,
|
||||
at: &BlockId<Block>,
|
||||
) -> Result<Option<u32>, ApiError> where Self: Sized;
|
||||
) -> Result<Option<u32>, ApiError>
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
/// Start recording all accessed trie nodes for generating proofs.
|
||||
fn record_proof(&mut self);
|
||||
@@ -509,10 +512,9 @@ pub trait ApiExt<Block: BlockT> {
|
||||
backend: &Self::StateBackend,
|
||||
changes_trie_state: Option<&ChangesTrieState<HashFor<Block>, NumberFor<Block>>>,
|
||||
parent_hash: Block::Hash,
|
||||
) -> Result<
|
||||
StorageChanges<Self::StateBackend, Block>,
|
||||
String
|
||||
> where Self: Sized;
|
||||
) -> Result<StorageChanges<Self::StateBackend, Block>, String>
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
|
||||
/// Parameters for [`CallApiAt::call_api_at`].
|
||||
@@ -557,10 +559,7 @@ pub trait CallApiAt<Block: BlockT> {
|
||||
) -> Result<NativeOrEncoded<R>, ApiError>;
|
||||
|
||||
/// Returns the runtime version at the given block.
|
||||
fn runtime_version_at(
|
||||
&self,
|
||||
at: &BlockId<Block>,
|
||||
) -> Result<RuntimeVersion, ApiError>;
|
||||
fn runtime_version_at(&self, at: &BlockId<Block>) -> Result<RuntimeVersion, ApiError>;
|
||||
}
|
||||
|
||||
/// Auxiliary wrapper that holds an api instance and binds it to the given lifetime.
|
||||
|
||||
@@ -15,14 +15,13 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use criterion::{Criterion, criterion_group, criterion_main};
|
||||
use substrate_test_runtime_client::{
|
||||
DefaultTestClientBuilderExt, TestClientBuilder,
|
||||
TestClientBuilderExt, runtime::TestAPI,
|
||||
};
|
||||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
use sp_api::ProvideRuntimeApi;
|
||||
use sp_runtime::generic::BlockId;
|
||||
use sp_state_machine::ExecutionStrategy;
|
||||
use sp_api::ProvideRuntimeApi;
|
||||
use substrate_test_runtime_client::{
|
||||
runtime::TestAPI, DefaultTestClientBuilderExt, TestClientBuilder, TestClientBuilderExt,
|
||||
};
|
||||
|
||||
fn sp_api_benchmark(c: &mut Criterion) {
|
||||
c.bench_function("add one with same runtime api", |b| {
|
||||
@@ -58,13 +57,17 @@ fn sp_api_benchmark(c: &mut Criterion) {
|
||||
});
|
||||
|
||||
c.bench_function("calling function by function pointer in wasm", |b| {
|
||||
let client = TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::AlwaysWasm).build();
|
||||
let client = TestClientBuilder::new()
|
||||
.set_execution_strategy(ExecutionStrategy::AlwaysWasm)
|
||||
.build();
|
||||
let block_id = BlockId::Number(client.chain_info().best_number);
|
||||
b.iter(|| client.runtime_api().benchmark_indirect_call(&block_id).unwrap())
|
||||
});
|
||||
|
||||
c.bench_function("calling function in wasm", |b| {
|
||||
let client = TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::AlwaysWasm).build();
|
||||
let client = TestClientBuilder::new()
|
||||
.set_execution_strategy(ExecutionStrategy::AlwaysWasm)
|
||||
.build();
|
||||
let block_id = BlockId::Number(client.chain_info().best_number);
|
||||
b.iter(|| client.runtime_api().benchmark_direct_call(&block_id).unwrap())
|
||||
});
|
||||
|
||||
@@ -16,12 +16,13 @@
|
||||
// limitations under the License.
|
||||
|
||||
use sp_api::{
|
||||
RuntimeApiInfo, decl_runtime_apis, impl_runtime_apis, mock_impl_runtime_apis,
|
||||
ApiError,
|
||||
ApiExt,
|
||||
decl_runtime_apis, impl_runtime_apis, mock_impl_runtime_apis, ApiError, ApiExt, RuntimeApiInfo,
|
||||
};
|
||||
use sp_runtime::{traits::{GetNodeBlockType, Block as BlockT}, generic::BlockId};
|
||||
use sp_core::NativeOrEncoded;
|
||||
use sp_runtime::{
|
||||
generic::BlockId,
|
||||
traits::{Block as BlockT, GetNodeBlockType},
|
||||
};
|
||||
use substrate_test_runtime_client::runtime::Block;
|
||||
|
||||
/// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType`
|
||||
@@ -142,16 +143,22 @@ type TestClient = substrate_test_runtime_client::client::Client<
|
||||
|
||||
#[test]
|
||||
fn test_client_side_function_signature() {
|
||||
let _test: fn(&RuntimeApiImpl<Block, TestClient>, &BlockId<Block>, u64) -> Result<(), ApiError> =
|
||||
RuntimeApiImpl::<Block, TestClient>::test;
|
||||
let _something_with_block:
|
||||
fn(&RuntimeApiImpl<Block, TestClient>, &BlockId<Block>, Block) -> Result<Block, ApiError> =
|
||||
RuntimeApiImpl::<Block, TestClient>::something_with_block;
|
||||
let _test: fn(
|
||||
&RuntimeApiImpl<Block, TestClient>,
|
||||
&BlockId<Block>,
|
||||
u64,
|
||||
) -> Result<(), ApiError> = RuntimeApiImpl::<Block, TestClient>::test;
|
||||
let _something_with_block: fn(
|
||||
&RuntimeApiImpl<Block, TestClient>,
|
||||
&BlockId<Block>,
|
||||
Block,
|
||||
) -> Result<Block, ApiError> = RuntimeApiImpl::<Block, TestClient>::something_with_block;
|
||||
|
||||
#[allow(deprecated)]
|
||||
let _same_name_before_version_2:
|
||||
fn(&RuntimeApiImpl<Block, TestClient>, &BlockId<Block>) -> Result<String, ApiError> =
|
||||
RuntimeApiImpl::<Block, TestClient>::same_name_before_version_2;
|
||||
let _same_name_before_version_2: fn(
|
||||
&RuntimeApiImpl<Block, TestClient>,
|
||||
&BlockId<Block>,
|
||||
) -> Result<String, ApiError> = RuntimeApiImpl::<Block, TestClient>::same_name_before_version_2;
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -186,9 +193,7 @@ fn check_runtime_api_versions() {
|
||||
fn mock_runtime_api_has_api() {
|
||||
let mock = MockApi { block: None };
|
||||
|
||||
assert!(
|
||||
mock.has_api::<dyn ApiWithCustomVersion<Block>>(&BlockId::Number(0)).unwrap(),
|
||||
);
|
||||
assert!(mock.has_api::<dyn ApiWithCustomVersion<Block>>(&BlockId::Number(0)).unwrap(),);
|
||||
assert!(mock.has_api::<dyn Api<Block>>(&BlockId::Number(0)).unwrap());
|
||||
}
|
||||
|
||||
|
||||
@@ -15,21 +15,23 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use sp_api::{ProvideRuntimeApi, Core};
|
||||
use sp_api::{Core, ProvideRuntimeApi};
|
||||
use sp_runtime::{
|
||||
generic::BlockId,
|
||||
traits::{HashFor, Header as HeaderT},
|
||||
};
|
||||
use sp_state_machine::{
|
||||
create_proof_check_backend, execution_proof_check_on_trie_backend, ExecutionStrategy,
|
||||
};
|
||||
use substrate_test_runtime_client::{
|
||||
prelude::*,
|
||||
runtime::{Block, DecodeFails, Header, TestAPI, Transfer},
|
||||
DefaultTestClientBuilderExt, TestClientBuilder,
|
||||
runtime::{TestAPI, DecodeFails, Transfer, Block, Header},
|
||||
};
|
||||
use sp_runtime::{generic::BlockId, traits::{Header as HeaderT, HashFor}};
|
||||
use sp_state_machine::{
|
||||
ExecutionStrategy, create_proof_check_backend,
|
||||
execution_proof_check_on_trie_backend,
|
||||
};
|
||||
|
||||
use sp_consensus::SelectChain;
|
||||
use codec::Encode;
|
||||
use sc_block_builder::BlockBuilderProvider;
|
||||
use sp_consensus::SelectChain;
|
||||
|
||||
fn calling_function_with_strat(strat: ExecutionStrategy) {
|
||||
let client = TestClientBuilder::new().set_execution_strategy(strat).build();
|
||||
@@ -52,7 +54,9 @@ fn calling_wasm_runtime_function() {
|
||||
#[test]
|
||||
#[should_panic(expected = "FailedToConvertParameter { function: \"fail_convert_parameter\"")]
|
||||
fn calling_native_runtime_function_with_non_decodable_parameter() {
|
||||
let client = TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::NativeWhenPossible).build();
|
||||
let client = TestClientBuilder::new()
|
||||
.set_execution_strategy(ExecutionStrategy::NativeWhenPossible)
|
||||
.build();
|
||||
let runtime_api = client.runtime_api();
|
||||
let block_id = BlockId::Number(client.chain_info().best_number);
|
||||
runtime_api.fail_convert_parameter(&block_id, DecodeFails::new()).unwrap();
|
||||
@@ -61,7 +65,9 @@ fn calling_native_runtime_function_with_non_decodable_parameter() {
|
||||
#[test]
|
||||
#[should_panic(expected = "FailedToConvertReturnValue { function: \"fail_convert_return_value\"")]
|
||||
fn calling_native_runtime_function_with_non_decodable_return_value() {
|
||||
let client = TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::NativeWhenPossible).build();
|
||||
let client = TestClientBuilder::new()
|
||||
.set_execution_strategy(ExecutionStrategy::NativeWhenPossible)
|
||||
.build();
|
||||
let runtime_api = client.runtime_api();
|
||||
let block_id = BlockId::Number(client.chain_info().best_number);
|
||||
runtime_api.fail_convert_return_value(&block_id).unwrap();
|
||||
@@ -69,7 +75,9 @@ fn calling_native_runtime_function_with_non_decodable_return_value() {
|
||||
|
||||
#[test]
|
||||
fn calling_native_runtime_signature_changed_function() {
|
||||
let client = TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::NativeWhenPossible).build();
|
||||
let client = TestClientBuilder::new()
|
||||
.set_execution_strategy(ExecutionStrategy::NativeWhenPossible)
|
||||
.build();
|
||||
let runtime_api = client.runtime_api();
|
||||
let block_id = BlockId::Number(client.chain_info().best_number);
|
||||
|
||||
@@ -78,7 +86,9 @@ fn calling_native_runtime_signature_changed_function() {
|
||||
|
||||
#[test]
|
||||
fn calling_wasm_runtime_signature_changed_old_function() {
|
||||
let client = TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::AlwaysWasm).build();
|
||||
let client = TestClientBuilder::new()
|
||||
.set_execution_strategy(ExecutionStrategy::AlwaysWasm)
|
||||
.build();
|
||||
let runtime_api = client.runtime_api();
|
||||
let block_id = BlockId::Number(client.chain_info().best_number);
|
||||
|
||||
@@ -103,10 +113,11 @@ fn calling_with_both_strategy_and_fail_on_native_should_work() {
|
||||
assert_eq!(runtime_api.fail_on_native(&block_id).unwrap(), 1);
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn calling_with_native_else_wasm_and_fail_on_wasm_should_work() {
|
||||
let client = TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::NativeElseWasm).build();
|
||||
let client = TestClientBuilder::new()
|
||||
.set_execution_strategy(ExecutionStrategy::NativeElseWasm)
|
||||
.build();
|
||||
let runtime_api = client.runtime_api();
|
||||
let block_id = BlockId::Number(client.chain_info().best_number);
|
||||
assert_eq!(runtime_api.fail_on_wasm(&block_id).unwrap(), 1);
|
||||
@@ -114,7 +125,9 @@ fn calling_with_native_else_wasm_and_fail_on_wasm_should_work() {
|
||||
|
||||
#[test]
|
||||
fn calling_with_native_else_wasm_and_fail_on_native_should_work() {
|
||||
let client = TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::NativeElseWasm).build();
|
||||
let client = TestClientBuilder::new()
|
||||
.set_execution_strategy(ExecutionStrategy::NativeElseWasm)
|
||||
.build();
|
||||
let runtime_api = client.runtime_api();
|
||||
let block_id = BlockId::Number(client.chain_info().best_number);
|
||||
assert_eq!(runtime_api.fail_on_native(&block_id).unwrap(), 1);
|
||||
@@ -122,7 +135,9 @@ fn calling_with_native_else_wasm_and_fail_on_native_should_work() {
|
||||
|
||||
#[test]
|
||||
fn use_trie_function() {
|
||||
let client = TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::AlwaysWasm).build();
|
||||
let client = TestClientBuilder::new()
|
||||
.set_execution_strategy(ExecutionStrategy::AlwaysWasm)
|
||||
.build();
|
||||
let runtime_api = client.runtime_api();
|
||||
let block_id = BlockId::Number(client.chain_info().best_number);
|
||||
assert_eq!(runtime_api.use_trie(&block_id).unwrap(), 2);
|
||||
@@ -133,10 +148,18 @@ fn initialize_block_works() {
|
||||
let client = TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::Both).build();
|
||||
let runtime_api = client.runtime_api();
|
||||
let block_id = BlockId::Number(client.chain_info().best_number);
|
||||
runtime_api.initialize_block(
|
||||
&block_id,
|
||||
&Header::new(1, Default::default(), Default::default(), Default::default(), Default::default()),
|
||||
).unwrap();
|
||||
runtime_api
|
||||
.initialize_block(
|
||||
&block_id,
|
||||
&Header::new(
|
||||
1,
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(runtime_api.get_block_number(&block_id).unwrap(), 1);
|
||||
}
|
||||
|
||||
@@ -165,7 +188,8 @@ fn record_proof_works() {
|
||||
nonce: 0,
|
||||
from: AccountKeyring::Alice.into(),
|
||||
to: Default::default(),
|
||||
}.into_signed_tx();
|
||||
}
|
||||
.into_signed_tx();
|
||||
|
||||
// Build the block and record proof
|
||||
let mut builder = client
|
||||
@@ -177,15 +201,12 @@ fn record_proof_works() {
|
||||
let backend = create_proof_check_backend::<HashFor<Block>>(
|
||||
storage_root,
|
||||
proof.expect("Proof was generated"),
|
||||
).expect("Creates proof backend.");
|
||||
)
|
||||
.expect("Creates proof backend.");
|
||||
|
||||
// Use the proof backend to execute `execute_block`.
|
||||
let mut overlay = Default::default();
|
||||
let executor = NativeExecutor::<LocalExecutor>::new(
|
||||
WasmExecutionMethod::Interpreted,
|
||||
None,
|
||||
8,
|
||||
);
|
||||
let executor = NativeExecutor::<LocalExecutor>::new(WasmExecutionMethod::Interpreted, None, 8);
|
||||
execution_proof_check_on_trie_backend::<_, u64, _, _>(
|
||||
&backend,
|
||||
&mut overlay,
|
||||
@@ -194,7 +215,8 @@ fn record_proof_works() {
|
||||
"Core_execute_block",
|
||||
&block.encode(),
|
||||
&runtime_code,
|
||||
).expect("Executes block while using the proof backend");
|
||||
)
|
||||
.expect("Executes block while using the proof backend");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -203,7 +225,8 @@ fn call_runtime_api_with_multiple_arguments() {
|
||||
|
||||
let data = vec![1, 2, 4, 5, 6, 7, 8, 8, 10, 12];
|
||||
let block_id = BlockId::Number(client.chain_info().best_number);
|
||||
client.runtime_api()
|
||||
client
|
||||
.runtime_api()
|
||||
.test_multiple_arguments(&block_id, data.clone(), data.clone(), data.len() as u32)
|
||||
.unwrap();
|
||||
}
|
||||
@@ -213,8 +236,8 @@ fn disable_logging_works() {
|
||||
if std::env::var("RUN_TEST").is_ok() {
|
||||
sp_tracing::try_init_simple();
|
||||
|
||||
let mut builder = TestClientBuilder::new()
|
||||
.set_execution_strategy(ExecutionStrategy::AlwaysWasm);
|
||||
let mut builder =
|
||||
TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::AlwaysWasm);
|
||||
builder.genesis_init_mut().set_wasm_code(
|
||||
substrate_test_runtime_client::runtime::wasm_binary_logging_disabled_unwrap().to_vec(),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user