mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-09 20:11:09 +00:00
Implement support for renaming runtime api functions (#2160)
* Implement support for renaming runtime api functions * Redelete the wasm files * FIxes test * Fix test correctly... * Bring back old `authorities` * Tag as deprecated * Fixes compilation on WASM * Add missing method implementations * Fixes tests * Increase `spec_version`
This commit is contained in:
@@ -23,11 +23,12 @@ pub use inherents::{InherentData, CheckInherentsResult};
|
||||
|
||||
decl_runtime_apis! {
|
||||
/// The `BlockBuilder` api trait that provides required functions for building a block for a runtime.
|
||||
#[api_version(2)]
|
||||
#[api_version(3)]
|
||||
pub trait BlockBuilder {
|
||||
/// Apply the given extrinsics.
|
||||
fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyResult;
|
||||
/// Finish the current block.
|
||||
#[renamed("finalise_block", 3)]
|
||||
fn finalize_block() -> <Block as BlockT>::Header;
|
||||
/// Generate inherent extrinsics. The inherent data will vary from chain to chain.
|
||||
fn inherent_extrinsics(inherent: InherentData) -> Vec<<Block as BlockT>::Extrinsic>;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
use std::{sync::Arc, cmp::Ord, panic::UnwindSafe, result};
|
||||
use parity_codec::{Encode, Decode};
|
||||
use runtime_primitives::generic::BlockId;
|
||||
use runtime_primitives::traits::Block as BlockT;
|
||||
use runtime_primitives::traits::{Block as BlockT, RuntimeApiInfo};
|
||||
use state_machine::{
|
||||
self, OverlayedChanges, Ext, CodeExecutor, ExecutionManager, ExecutionStrategy, NeverOffchainExt,
|
||||
};
|
||||
@@ -28,6 +28,7 @@ use primitives::{H256, Blake2Hasher, NativeOrEncoded, NeverNativeValue, Offchain
|
||||
|
||||
use crate::backend;
|
||||
use crate::error;
|
||||
use crate::runtime_api::Core as CoreApi;
|
||||
|
||||
/// Method call executor.
|
||||
pub trait CallExecutor<B, H>
|
||||
@@ -220,7 +221,15 @@ where
|
||||
mut side_effects_handler: Option<&mut O>,
|
||||
) -> Result<NativeOrEncoded<R>, error::Error> where ExecutionManager<EM>: Clone {
|
||||
let state = self.backend.state_at(*at)?;
|
||||
if method != "Core_initialize_block" && initialized_block.map(|id| id != *at).unwrap_or(true) {
|
||||
|
||||
let core_version = self.runtime_version(at)?.apis.iter().find(|a| a.0 == CoreApi::<Block>::ID).map(|a| a.1);
|
||||
let init_block_function = if core_version < Some(2) {
|
||||
"Core_initialise_block"
|
||||
} else {
|
||||
"Core_initialize_block"
|
||||
};
|
||||
|
||||
if method != init_block_function && initialized_block.map(|id| id != *at).unwrap_or(true) {
|
||||
let header = prepare_environment_block()?;
|
||||
state_machine::new(
|
||||
&state,
|
||||
@@ -228,7 +237,7 @@ where
|
||||
side_effects_handler.as_mut().map(|x| &mut **x),
|
||||
changes,
|
||||
&self.executor,
|
||||
"Core_initialize_block",
|
||||
init_block_function,
|
||||
&header.encode(),
|
||||
).execute_using_consensus_failure_handler::<_, R, fn() -> _>(
|
||||
execution_manager.clone(),
|
||||
@@ -253,7 +262,7 @@ where
|
||||
).map(|(result, _, _)| result)?;
|
||||
|
||||
// If the method is `initialize_block` we need to set the `initialized_block`
|
||||
if method == "Core_initialize_block" {
|
||||
if method == init_block_function {
|
||||
*initialized_block = Some(*at);
|
||||
}
|
||||
|
||||
@@ -265,8 +274,7 @@ where
|
||||
let mut overlay = OverlayedChanges::default();
|
||||
let state = self.backend.state_at(*id)?;
|
||||
let mut ext = Ext::new(&mut overlay, &state, self.backend.changes_trie_storage(), NeverOffchainExt::new());
|
||||
self.executor.runtime_version(&mut ext)
|
||||
.ok_or(error::ErrorKind::VersionInvalid.into())
|
||||
self.executor.runtime_version(&mut ext).ok_or(error::ErrorKind::VersionInvalid.into())
|
||||
}
|
||||
|
||||
fn call_at_state<
|
||||
|
||||
@@ -35,6 +35,7 @@ pub use runtime_version::{ApiId, RuntimeVersion, ApisVec, create_apis_vec};
|
||||
pub use rstd::{slice, mem};
|
||||
#[cfg(feature = "std")]
|
||||
use rstd::result;
|
||||
#[doc(hidden)]
|
||||
pub use parity_codec::{Encode, Decode};
|
||||
#[cfg(feature = "std")]
|
||||
use crate::error;
|
||||
@@ -42,6 +43,7 @@ use sr_api_macros::decl_runtime_apis;
|
||||
use primitives::OpaqueMetadata;
|
||||
#[cfg(feature = "std")]
|
||||
use std::panic::UnwindSafe;
|
||||
use rstd::vec::Vec;
|
||||
|
||||
/// Something that can be constructed to a runtime api.
|
||||
#[cfg(feature = "std")]
|
||||
@@ -113,13 +115,18 @@ pub trait CallRuntimeAt<Block: BlockT> {
|
||||
decl_runtime_apis! {
|
||||
/// The `Core` api trait that is mandatory for each runtime.
|
||||
#[core_trait]
|
||||
#[api_version(2)]
|
||||
pub trait Core {
|
||||
/// Returns the version of the runtime.
|
||||
fn version() -> RuntimeVersion;
|
||||
/// Execute the given block.
|
||||
fn execute_block(block: Block);
|
||||
/// Initialize a block with the given header.
|
||||
#[renamed("initialise_block", 2)]
|
||||
fn initialize_block(header: &<Block as BlockT>::Header);
|
||||
/// Returns the authorities.
|
||||
#[deprecated(since = "1.0", note = "Please switch to `AuthoritiesApi`.")]
|
||||
fn authorities() -> Vec<AuthorityIdFor<Block>>;
|
||||
}
|
||||
|
||||
/// The `Metadata` api trait that returns metadata for the runtime.
|
||||
|
||||
@@ -37,7 +37,7 @@ use consensus_common::import_queue::{Verifier, BasicQueue, SharedBlockImport, Sh
|
||||
use client::ChainHead;
|
||||
use client::block_builder::api::BlockBuilder as BlockBuilderApi;
|
||||
use client::blockchain::ProvideCache;
|
||||
use client::runtime_api::ApiExt;
|
||||
use client::runtime_api::{ApiExt, Core as CoreApi};
|
||||
use aura_primitives::AURA_ENGINE_ID;
|
||||
use runtime_primitives::{generic, generic::BlockId, Justification};
|
||||
use runtime_primitives::traits::{
|
||||
@@ -685,6 +685,7 @@ impl<B, C, E, P> Authorities<B> for AuraVerifier<C, E, P> where
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
fn authorities<B, C>(client: &C, at: &BlockId<B>) -> Result<Vec<AuthorityIdFor<B>>, ConsensusError> where
|
||||
B: Block,
|
||||
C: ProvideRuntimeApi + ProvideCache<B>,
|
||||
@@ -694,8 +695,13 @@ fn authorities<B, C>(client: &C, at: &BlockId<B>) -> Result<Vec<AuthorityIdFor<B
|
||||
.cache()
|
||||
.and_then(|cache| cache.get_at(&well_known_cache_keys::AUTHORITIES, at)
|
||||
.and_then(|v| Decode::decode(&mut &v[..])))
|
||||
.or_else(|| client.runtime_api().authorities(at).ok())
|
||||
.ok_or_else(|| consensus_common::ErrorKind::InvalidAuthoritiesSet.into())
|
||||
.or_else(|| {
|
||||
if client.runtime_api().has_api::<AuthoritiesApi<B>>(at).unwrap_or(false) {
|
||||
AuthoritiesApi::authorities(&*client.runtime_api(), at).ok()
|
||||
} else {
|
||||
CoreApi::authorities(&*client.runtime_api(), at).ok()
|
||||
}
|
||||
}).ok_or_else(|| consensus_common::ErrorKind::InvalidAuthoritiesSet.into())
|
||||
}
|
||||
|
||||
/// The Aura import queue type.
|
||||
|
||||
@@ -267,7 +267,7 @@ impl ProvideRuntimeApi for TestApi {
|
||||
}
|
||||
|
||||
impl Core<Block> for RuntimeApi {
|
||||
fn version_runtime_api_impl(
|
||||
fn Core_version_runtime_api_impl(
|
||||
&self,
|
||||
_: &BlockId<Block>,
|
||||
_: ExecutionContext,
|
||||
@@ -277,7 +277,7 @@ impl Core<Block> for RuntimeApi {
|
||||
unimplemented!("Not required for testing!")
|
||||
}
|
||||
|
||||
fn execute_block_runtime_api_impl(
|
||||
fn Core_execute_block_runtime_api_impl(
|
||||
&self,
|
||||
_: &BlockId<Block>,
|
||||
_: ExecutionContext,
|
||||
@@ -287,7 +287,7 @@ impl Core<Block> for RuntimeApi {
|
||||
unimplemented!("Not required for testing!")
|
||||
}
|
||||
|
||||
fn initialize_block_runtime_api_impl(
|
||||
fn Core_initialize_block_runtime_api_impl(
|
||||
&self,
|
||||
_: &BlockId<Block>,
|
||||
_: ExecutionContext,
|
||||
@@ -296,6 +296,15 @@ impl Core<Block> for RuntimeApi {
|
||||
) -> Result<NativeOrEncoded<()>> {
|
||||
unimplemented!("Not required for testing!")
|
||||
}
|
||||
fn Core_authorities_runtime_api_impl(
|
||||
&self,
|
||||
_: &BlockId<Block>,
|
||||
_: ExecutionContext,
|
||||
_: Option<()>,
|
||||
_: Vec<u8>,
|
||||
) -> Result<NativeOrEncoded<Vec<AuthorityId>>> {
|
||||
unimplemented!("Not required for testing!")
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiExt<Block> for RuntimeApi {
|
||||
@@ -312,7 +321,7 @@ impl ApiExt<Block> for RuntimeApi {
|
||||
}
|
||||
|
||||
impl GrandpaApi<Block> for RuntimeApi {
|
||||
fn grandpa_authorities_runtime_api_impl(
|
||||
fn GrandpaApi_grandpa_authorities_runtime_api_impl(
|
||||
&self,
|
||||
at: &BlockId<Block>,
|
||||
_: ExecutionContext,
|
||||
@@ -326,7 +335,7 @@ impl GrandpaApi<Block> for RuntimeApi {
|
||||
}
|
||||
}
|
||||
|
||||
fn grandpa_pending_change_runtime_api_impl(
|
||||
fn GrandpaApi_grandpa_pending_change_runtime_api_impl(
|
||||
&self,
|
||||
at: &BlockId<Block>,
|
||||
_: ExecutionContext,
|
||||
@@ -343,7 +352,7 @@ impl GrandpaApi<Block> for RuntimeApi {
|
||||
Ok(self.inner.scheduled_changes.lock().get(&parent_hash).map(|c| c.clone())).map(NativeOrEncoded::Native)
|
||||
}
|
||||
|
||||
fn grandpa_forced_change_runtime_api_impl(
|
||||
fn GrandpaApi_grandpa_forced_change_runtime_api_impl(
|
||||
&self,
|
||||
at: &BlockId<Block>,
|
||||
_: ExecutionContext,
|
||||
|
||||
@@ -221,7 +221,7 @@ fn should_return_runtime_version() {
|
||||
|
||||
assert_eq!(
|
||||
::serde_json::to_string(&api.runtime_version(None.into()).unwrap()).unwrap(),
|
||||
r#"{"specName":"test","implName":"parity-test","authoringVersion":1,"specVersion":1,"implVersion":1,"apis":[["0xdf6acb689907609b",1],["0x37e397fc7c91f5e4",1],["0xd2bc9897eed08f15",1],["0x40fe3ad401f8959a",2],["0xc6e9a76309f39b09",1],["0xdd718d5cc53262d4",1],["0xf78b278be53f454c",1],["0x7801759919ee83e5",1]]}"#
|
||||
r#"{"specName":"test","implName":"parity-test","authoringVersion":1,"specVersion":1,"implVersion":1,"apis":[["0xdf6acb689907609b",2],["0x37e397fc7c91f5e4",1],["0xd2bc9897eed08f15",1],["0x40fe3ad401f8959a",3],["0xc6e9a76309f39b09",1],["0xdd718d5cc53262d4",1],["0xf78b278be53f454c",1],["0x7801759919ee83e5",1]]}"#
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ use crate::utils::{
|
||||
generate_crate_access, generate_hidden_includes, generate_runtime_mod_name_for_trait,
|
||||
fold_fn_decl_for_client_side, unwrap_or_error, extract_parameter_names_types_and_borrows,
|
||||
generate_native_call_generator_fn_name, return_type_extract_type,
|
||||
generate_method_runtime_api_impl_name
|
||||
generate_method_runtime_api_impl_name, generate_call_api_at_fn_name, prefix_function_with_trait,
|
||||
};
|
||||
|
||||
use proc_macro2::{TokenStream, Span};
|
||||
@@ -45,15 +45,21 @@ const HIDDEN_INCLUDES_ID: &str = "DECL_RUNTIME_APIS";
|
||||
/// The `core_trait` attribute.
|
||||
const CORE_TRAIT_ATTRIBUTE: &str = "core_trait";
|
||||
/// The `api_version` attribute.
|
||||
///
|
||||
/// Is used to set the current version of the trait.
|
||||
const API_VERSION_ATTRIBUTE: &str = "api_version";
|
||||
/// The `changed_in` attribute.
|
||||
///
|
||||
/// Is used when the function signature changed between different versions of a trait.
|
||||
/// This attribute should be placed on the old signature of the function.
|
||||
const CHANGED_IN_ATTRIBUTE: &str = "changed_in";
|
||||
/// The `renamed` attribute.
|
||||
///
|
||||
/// 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
|
||||
CORE_TRAIT_ATTRIBUTE, API_VERSION_ATTRIBUTE, CHANGED_IN_ATTRIBUTE, RENAMED_ATTRIBUTE
|
||||
];
|
||||
|
||||
/// The structure used for parsing the runtime api declarations.
|
||||
@@ -88,7 +94,7 @@ fn extend_generics_with_block(generics: &mut Generics) {
|
||||
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().filter(|a| v.path.is_ident(a)).next() {
|
||||
match SUPPORTED_ATTRIBUTE_NAMES.iter().find(|a| v.path.is_ident(a)) {
|
||||
Some(attribute) => {
|
||||
result.insert(*attribute, v.clone());
|
||||
false
|
||||
@@ -152,6 +158,7 @@ fn return_type_replace_block_with_node_block(return_type: ReturnType) -> ReturnT
|
||||
fold::fold_return_type(&mut replace, return_type)
|
||||
}
|
||||
|
||||
/// Generate the functions that generate the native call closure for each trait method.
|
||||
fn generate_native_call_generators(decl: &ItemTrait) -> Result<TokenStream> {
|
||||
let fns = decl.items.iter().filter_map(|i| match i {
|
||||
TraitItem::Method(ref m) => Some(&m.sig),
|
||||
@@ -227,11 +234,8 @@ fn generate_native_call_generators(decl: &ItemTrait) -> Result<TokenStream> {
|
||||
.map(|v| match v {
|
||||
FnArg::Captured(ref arg) => {
|
||||
let mut arg = arg.clone();
|
||||
match arg.ty {
|
||||
Type::Reference(ref mut r) => {
|
||||
r.lifetime = Some(parse_quote!( 'a ));
|
||||
},
|
||||
_ => {}
|
||||
if let Type::Reference(ref mut r) = arg.ty {
|
||||
r.lifetime = Some(parse_quote!( 'a ));
|
||||
}
|
||||
FnArg::Captured(arg)
|
||||
},
|
||||
@@ -240,7 +244,7 @@ fn generate_native_call_generators(decl: &ItemTrait) -> Result<TokenStream> {
|
||||
|
||||
let (impl_generics, ty_generics, where_clause) = decl.generics.split_for_impl();
|
||||
// We need to parse them again, to get an easy access to the actual parameters.
|
||||
let impl_generics: Generics = parse_quote!(#impl_generics);
|
||||
let impl_generics: Generics = parse_quote!( #impl_generics );
|
||||
let impl_generics_params = impl_generics.params.iter().map(|p| {
|
||||
match p {
|
||||
GenericParam::Type(ref ty) => {
|
||||
@@ -274,6 +278,147 @@ fn generate_native_call_generators(decl: &ItemTrait) -> Result<TokenStream> {
|
||||
Ok(quote!( #( #result )* ))
|
||||
}
|
||||
|
||||
/// Try to parse the given `Attribute` as `renamed` attribute.
|
||||
fn parse_renamed_attribute(renamed: &Attribute) -> Result<(String, u32)> {
|
||||
let meta = renamed.parse_meta()?;
|
||||
|
||||
let err = Err(Error::new(
|
||||
meta.span(),
|
||||
&format!(
|
||||
"Unexpected `{renamed}` attribute. The supported format is `{renamed}(\"old_name\", version_it_was_renamed)`",
|
||||
renamed = RENAMED_ATTRIBUTE,
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
match meta {
|
||||
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::Literal(Lit::Str(i))) => {
|
||||
i.value()
|
||||
},
|
||||
_ => return err,
|
||||
};
|
||||
|
||||
let version = match itr.next() {
|
||||
Some(NestedMeta::Literal(Lit::Int(i))) => {
|
||||
i.value() as u32
|
||||
},
|
||||
_ => return err,
|
||||
};
|
||||
|
||||
Ok((old_name, version))
|
||||
}
|
||||
},
|
||||
_ => err,
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate the functions that call the api at a given block for a given trait method.
|
||||
fn generate_call_api_at_calls(decl: &ItemTrait) -> Result<TokenStream> {
|
||||
let fns = decl.items.iter().filter_map(|i| match i {
|
||||
TraitItem::Method(ref m) => Some((&m.attrs, &m.sig)),
|
||||
_ => None,
|
||||
});
|
||||
|
||||
let mut result = Vec::new();
|
||||
let crate_ = generate_crate_access(HIDDEN_INCLUDES_ID);
|
||||
|
||||
// Generate a native call generator for each function of the given trait.
|
||||
for (attrs, fn_) in fns {
|
||||
let trait_name = &decl.ident;
|
||||
let trait_fn_name = prefix_function_with_trait(&trait_name, &fn_.ident);
|
||||
let fn_name = generate_call_api_at_fn_name(&fn_.ident);
|
||||
|
||||
let attrs = remove_supported_attributes(&mut attrs.clone());
|
||||
|
||||
if attrs.contains_key(RENAMED_ATTRIBUTE) && attrs.contains_key(CHANGED_IN_ATTRIBUTE) {
|
||||
return Err(Error::new(
|
||||
fn_.span(), format!("`{}` and `{}` are not supported at once.", 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;
|
||||
}
|
||||
|
||||
// Parse the renamed attributes.
|
||||
let mut renames = Vec::new();
|
||||
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)));
|
||||
}
|
||||
|
||||
renames.sort_unstable_by(|l, r| r.cmp(l));
|
||||
let (versions, old_names) = renames.into_iter().fold(
|
||||
(Vec::new(), Vec::new()),
|
||||
|(mut versions, mut old_names), (version, old_name)| {
|
||||
versions.push(version);
|
||||
old_names.push(old_name);
|
||||
(versions, old_names)
|
||||
}
|
||||
);
|
||||
|
||||
// Generate the generator function
|
||||
result.push(quote!(
|
||||
#[cfg(any(feature = "std", test))]
|
||||
pub fn #fn_name<
|
||||
R: #crate_::runtime_api::Encode + #crate_::runtime_api::Decode + PartialEq,
|
||||
NC: FnOnce() -> ::std::result::Result<R, &'static str> + ::std::panic::UnwindSafe,
|
||||
Block: #crate_::runtime_api::BlockT,
|
||||
T: #crate_::runtime_api::CallRuntimeAt<Block>,
|
||||
>(
|
||||
call_runtime_at: &T,
|
||||
at: &#crate_::runtime_api::BlockId<Block>,
|
||||
args: Vec<u8>,
|
||||
changes: &mut #crate_::runtime_api::OverlayedChanges,
|
||||
initialized_block: &mut Option<#crate_::runtime_api::BlockId<Block>>,
|
||||
native_call: Option<NC>,
|
||||
context: #crate_::runtime_api::ExecutionContext,
|
||||
) -> #crate_::error::Result<#crate_::runtime_api::NativeOrEncoded<R>> {
|
||||
let version = call_runtime_at.runtime_version_at(at)?;
|
||||
|
||||
#(
|
||||
// Check if we need to call the function by an old name.
|
||||
if version.apis.iter().any(|(s, v)| {
|
||||
s == &ID && #versions < *v
|
||||
}) {
|
||||
return call_runtime_at.call_api_at::<R, fn() -> _>(
|
||||
at,
|
||||
#old_names,
|
||||
args,
|
||||
changes,
|
||||
initialized_block,
|
||||
None,
|
||||
context
|
||||
);
|
||||
}
|
||||
)*
|
||||
|
||||
call_runtime_at.call_api_at(
|
||||
at,
|
||||
#trait_fn_name,
|
||||
args,
|
||||
changes,
|
||||
initialized_block,
|
||||
native_call,
|
||||
context
|
||||
)
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
Ok(quote!( #( #result )* ))
|
||||
}
|
||||
|
||||
/// Generate the declaration of the trait for the runtime.
|
||||
fn generate_runtime_decls(decls: &[ItemTrait]) -> TokenStream {
|
||||
let mut result = Vec::new();
|
||||
@@ -288,6 +433,8 @@ fn generate_runtime_decls(decls: &[ItemTrait]) -> TokenStream {
|
||||
}));
|
||||
let id = generate_runtime_api_id(&decl.ident.to_string());
|
||||
|
||||
let call_api_at_calls = unwrap_or_error(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 {
|
||||
@@ -306,6 +453,7 @@ fn generate_runtime_decls(decls: &[ItemTrait]) -> TokenStream {
|
||||
result.push(quote!(
|
||||
#[doc(hidden)]
|
||||
#[allow(dead_code)]
|
||||
#[allow(deprecated)]
|
||||
pub mod #mod_name {
|
||||
use super::*;
|
||||
|
||||
@@ -316,6 +464,8 @@ fn generate_runtime_decls(decls: &[ItemTrait]) -> TokenStream {
|
||||
pub #id
|
||||
|
||||
#native_call_generators
|
||||
|
||||
#call_api_at_calls
|
||||
}
|
||||
));
|
||||
}
|
||||
@@ -330,6 +480,7 @@ struct ToClientSideDecl<'a> {
|
||||
found_attributes: &'a mut HashMap<&'static str, Attribute>,
|
||||
/// Any error that we found while converting this declaration.
|
||||
errors: &'a mut Vec<TokenStream>,
|
||||
trait_: &'a Ident,
|
||||
}
|
||||
|
||||
impl<'a> ToClientSideDecl<'a> {
|
||||
@@ -396,7 +547,7 @@ impl<'a> ToClientSideDecl<'a> {
|
||||
Vec::new()
|
||||
}
|
||||
};
|
||||
let name = generate_method_runtime_api_impl_name(&method.sig.ident);
|
||||
let name = generate_method_runtime_api_impl_name(&self.trait_, &method.sig.ident);
|
||||
let block_id = self.block_id;
|
||||
let crate_ = self.crate_;
|
||||
|
||||
@@ -433,7 +584,7 @@ impl<'a> ToClientSideDecl<'a> {
|
||||
&self.block_id,
|
||||
&self.crate_
|
||||
);
|
||||
let name_impl = generate_method_runtime_api_impl_name(&method.sig.ident);
|
||||
let name_impl = generate_method_runtime_api_impl_name(&self.trait_, &method.sig.ident);
|
||||
let crate_ = self.crate_;
|
||||
|
||||
let found_attributes = remove_supported_attributes(&mut method.attrs);
|
||||
@@ -619,6 +770,7 @@ fn generate_client_side_decls(decls: &[ItemTrait]) -> TokenStream {
|
||||
let block_id = quote!( #crate_::runtime_api::BlockId<Block> );
|
||||
let mut found_attributes = HashMap::new();
|
||||
let mut errors = Vec::new();
|
||||
let trait_ = decl.ident.clone();
|
||||
|
||||
let decl = {
|
||||
let mut to_client_side = ToClientSideDecl {
|
||||
@@ -626,6 +778,7 @@ fn generate_client_side_decls(decls: &[ItemTrait]) -> TokenStream {
|
||||
block_id: &block_id,
|
||||
found_attributes: &mut found_attributes,
|
||||
errors: &mut errors,
|
||||
trait_: &trait_,
|
||||
};
|
||||
to_client_side.fold_item_trait(decl)
|
||||
};
|
||||
@@ -682,7 +835,7 @@ 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 => {
|
||||
GenericParam::Type(ty) if ty.ident == BLOCK_GENERIC_IDENT => {
|
||||
self.errors.push(
|
||||
Error::new(
|
||||
input.span(),
|
||||
|
||||
@@ -18,7 +18,7 @@ use crate::utils::{
|
||||
unwrap_or_error, 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
|
||||
return_type_extract_type, generate_call_api_at_fn_name, prefix_function_with_trait,
|
||||
};
|
||||
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
@@ -84,7 +84,7 @@ fn generate_impl_call(
|
||||
|
||||
let output = <#runtime as #impl_trait>::#fn_name(#( #pborrow #pnames2 ),*);
|
||||
#c::runtime_api::Encode::encode(&output)
|
||||
).into()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -153,20 +153,17 @@ fn generate_impl_calls(
|
||||
.ident;
|
||||
|
||||
for item in &impl_.items {
|
||||
match item {
|
||||
ImplItem::Method(method) => {
|
||||
let impl_call = generate_impl_call(
|
||||
&method.sig,
|
||||
&impl_.self_ty,
|
||||
input,
|
||||
&impl_trait
|
||||
)?;
|
||||
if let ImplItem::Method(method) = item {
|
||||
let impl_call = generate_impl_call(
|
||||
&method.sig,
|
||||
&impl_.self_ty,
|
||||
input,
|
||||
&impl_trait
|
||||
)?;
|
||||
|
||||
impl_calls.push(
|
||||
(impl_trait_ident.clone(), method.sig.ident.clone(), impl_call)
|
||||
);
|
||||
},
|
||||
_ => {},
|
||||
impl_calls.push(
|
||||
(impl_trait_ident.clone(), method.sig.ident.clone(), impl_call)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -174,10 +171,6 @@ fn generate_impl_calls(
|
||||
Ok(impl_calls)
|
||||
}
|
||||
|
||||
fn prefix_function_with_trait(trait_: &Ident, function: &Ident) -> String {
|
||||
format!("{}_{}", trait_.to_string(), function.to_string())
|
||||
}
|
||||
|
||||
/// Generate the dispatch function that is used in native to call into the runtime.
|
||||
fn generate_dispatch_function(impls: &[ItemImpl]) -> Result<TokenStream> {
|
||||
let data = Ident::new("data", Span::call_site());
|
||||
@@ -196,7 +189,7 @@ fn generate_dispatch_function(impls: &[ItemImpl]) -> Result<TokenStream> {
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
).into())
|
||||
))
|
||||
}
|
||||
|
||||
/// Generate the interface functions that are used to call into the runtime in wasm.
|
||||
@@ -330,24 +323,20 @@ fn generate_runtime_api_base_structures(impls: &[ItemImpl]) -> Result<TokenStrea
|
||||
impl<C: #crate_::runtime_api::CallRuntimeAt<#block>> RuntimeApiImpl<C> {
|
||||
fn call_api_at<
|
||||
R: #crate_::runtime_api::Encode + #crate_::runtime_api::Decode + PartialEq,
|
||||
NC: FnOnce() -> ::std::result::Result<R, &'static str> + ::std::panic::UnwindSafe,
|
||||
F: FnOnce(
|
||||
&C,
|
||||
&mut #crate_::runtime_api::OverlayedChanges,
|
||||
&mut Option<#crate_::runtime_api::BlockId<#block>>,
|
||||
) -> #crate_::error::Result<#crate_::runtime_api::NativeOrEncoded<R>>
|
||||
>(
|
||||
&self,
|
||||
at: &#block_id,
|
||||
function: &'static str,
|
||||
args: Vec<u8>,
|
||||
native_call: Option<NC>,
|
||||
context: #crate_::runtime_api::ExecutionContext
|
||||
call_api_at: F,
|
||||
) -> #crate_::error::Result<#crate_::runtime_api::NativeOrEncoded<R>> {
|
||||
let res = unsafe {
|
||||
self.call.call_api_at(
|
||||
at,
|
||||
function,
|
||||
args,
|
||||
call_api_at(
|
||||
&self.call,
|
||||
&mut *self.changes.borrow_mut(),
|
||||
&mut *self.initialized_block.borrow_mut(),
|
||||
native_call,
|
||||
context
|
||||
&mut *self.initialized_block.borrow_mut()
|
||||
)
|
||||
};
|
||||
|
||||
@@ -416,10 +405,10 @@ struct ApiRuntimeImplToApiRuntimeApiImpl<'a> {
|
||||
node_block: &'a TokenStream,
|
||||
runtime_block: &'a TypePath,
|
||||
node_block_id: &'a TokenStream,
|
||||
impl_trait_ident: &'a Ident,
|
||||
runtime_mod_path: &'a Path,
|
||||
runtime_type: &'a Type,
|
||||
trait_generic_arguments: &'a [GenericArgument]
|
||||
trait_generic_arguments: &'a [GenericArgument],
|
||||
impl_trait: &'a Ident,
|
||||
}
|
||||
|
||||
impl<'a> Fold for ApiRuntimeImplToApiRuntimeApiImpl<'a> {
|
||||
@@ -438,9 +427,9 @@ impl<'a> Fold for ApiRuntimeImplToApiRuntimeApiImpl<'a> {
|
||||
let block = {
|
||||
let runtime_mod_path = self.runtime_mod_path;
|
||||
let runtime = self.runtime_type;
|
||||
let fn_name = prefix_function_with_trait(self.impl_trait_ident, &input.sig.ident);
|
||||
let native_call_generator_ident =
|
||||
generate_native_call_generator_fn_name(&input.sig.ident);
|
||||
let call_api_at_call = generate_call_api_at_fn_name(&input.sig.ident);
|
||||
let trait_generic_arguments = self.trait_generic_arguments;
|
||||
let node_block = self.node_block;
|
||||
let crate_ = generate_crate_access(HIDDEN_INCLUDES_ID);
|
||||
@@ -475,7 +464,7 @@ impl<'a> Fold for ApiRuntimeImplToApiRuntimeApiImpl<'a> {
|
||||
&self, at: &#block_id, #context_arg, params: Option<( #( #param_types ),* )>, params_encoded: Vec<u8>
|
||||
};
|
||||
|
||||
input.sig.ident = generate_method_runtime_api_impl_name(&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.decl.output);
|
||||
|
||||
// Generate the correct return type.
|
||||
@@ -490,16 +479,22 @@ impl<'a> Fold for ApiRuntimeImplToApiRuntimeApiImpl<'a> {
|
||||
#( #error )*
|
||||
|
||||
self.call_api_at(
|
||||
at,
|
||||
#fn_name,
|
||||
params_encoded,
|
||||
params.map(|p| {
|
||||
#runtime_mod_path #native_call_generator_ident ::
|
||||
<#runtime, #node_block #(, #trait_generic_arguments )*> (
|
||||
#( #param_tuple_access ),*
|
||||
|call_runtime_at, changes, initialized_block| {
|
||||
#runtime_mod_path #call_api_at_call(
|
||||
call_runtime_at,
|
||||
at,
|
||||
params_encoded,
|
||||
changes,
|
||||
initialized_block,
|
||||
params.map(|p| {
|
||||
#runtime_mod_path #native_call_generator_ident ::
|
||||
<#runtime, #node_block #(, #trait_generic_arguments )*> (
|
||||
#( #param_tuple_access ),*
|
||||
)
|
||||
}),
|
||||
context,
|
||||
)
|
||||
}),
|
||||
context,
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
@@ -541,7 +536,6 @@ fn generate_api_impl_for_runtime_api(impls: &[ItemImpl]) -> Result<TokenStream>
|
||||
.last()
|
||||
.ok_or_else(|| Error::new(impl_trait_path.span(), "Empty trait path not possible!"))?
|
||||
.into_value();
|
||||
let impl_trait_ident = &impl_trait.ident;
|
||||
let runtime_block = extract_runtime_block_ident(impl_trait_path)?;
|
||||
let (node_block, node_block_id) = generate_node_block_and_block_id_ty(&impl_.self_ty);
|
||||
let runtime_type = &impl_.self_ty;
|
||||
@@ -558,10 +552,10 @@ fn generate_api_impl_for_runtime_api(impls: &[ItemImpl]) -> Result<TokenStream>
|
||||
runtime_block,
|
||||
node_block: &node_block,
|
||||
node_block_id: &node_block_id,
|
||||
impl_trait_ident: &impl_trait_ident,
|
||||
runtime_mod_path: &runtime_mod_path,
|
||||
runtime_type: &*runtime_type,
|
||||
trait_generic_arguments: &trait_generic_arguments,
|
||||
impl_trait: &impl_trait.ident,
|
||||
};
|
||||
|
||||
result.push(visitor.fold_item_impl(impl_.clone()));
|
||||
|
||||
@@ -70,8 +70,8 @@ pub fn generate_runtime_mod_name_for_trait(trait_: &Ident) -> Ident {
|
||||
}
|
||||
|
||||
/// Generates a name for a method that needs to be implemented in the runtime for the client side.
|
||||
pub fn generate_method_runtime_api_impl_name(method: &Ident) -> Ident {
|
||||
Ident::new(&format!("{}_runtime_api_impl", method.to_string()), Span::call_site())
|
||||
pub fn generate_method_runtime_api_impl_name(trait_: &Ident, method: &Ident) -> Ident {
|
||||
Ident::new(&format!("{}_{}_runtime_api_impl", trait_, method), Span::call_site())
|
||||
}
|
||||
|
||||
/// Get the type of a `syn::ReturnType`.
|
||||
@@ -158,3 +158,13 @@ pub fn extract_parameter_names_types_and_borrows(fn_decl: &FnDecl)
|
||||
pub fn generate_native_call_generator_fn_name(fn_name: &Ident) -> Ident {
|
||||
Ident::new(&format!("{}_native_call_generator", fn_name.to_string()), Span::call_site())
|
||||
}
|
||||
|
||||
/// Generates the name for the call api at function.
|
||||
pub fn generate_call_api_at_fn_name(fn_name: &Ident) -> Ident {
|
||||
Ident::new(&format!("{}_call_api_at", fn_name.to_string()), Span::call_site())
|
||||
}
|
||||
|
||||
/// Prefix the given function with the trait name.
|
||||
pub fn prefix_function_with_trait<F: ToString>(trait_: &Ident, function: &F) -> String {
|
||||
format!("{}_{}", trait_.to_string(), function.to_string())
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use runtime_primitives::traits::{GetNodeBlockType, Block as BlockT};
|
||||
use runtime_primitives::traits::{GetNodeBlockType, Block as BlockT, AuthorityIdFor};
|
||||
use runtime_primitives::generic::BlockId;
|
||||
use client::runtime_api::{self, RuntimeApiInfo};
|
||||
use client::{error::Result, decl_runtime_apis, impl_runtime_apis};
|
||||
@@ -74,6 +74,9 @@ impl_runtime_apis! {
|
||||
fn initialize_block(_: &<Block as BlockT>::Header) {
|
||||
unimplemented!()
|
||||
}
|
||||
fn authorities() -> Vec<AuthorityIdFor<Block>> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -296,6 +296,10 @@ cfg_if! {
|
||||
fn initialize_block(header: &<Block as BlockT>::Header) {
|
||||
system::initialize_block(header)
|
||||
}
|
||||
|
||||
fn authorities() -> Vec<AuthorityId> {
|
||||
panic!("Deprecated, please use `AuthoritiesApi`.")
|
||||
}
|
||||
}
|
||||
|
||||
impl client_api::Metadata<Block> for Runtime {
|
||||
@@ -403,6 +407,10 @@ cfg_if! {
|
||||
fn initialize_block(header: &<Block as BlockT>::Header) {
|
||||
system::initialize_block(header)
|
||||
}
|
||||
|
||||
fn authorities() -> Vec<AuthorityId> {
|
||||
panic!("Deprecated, please use `AuthoritiesApi`.")
|
||||
}
|
||||
}
|
||||
|
||||
impl client_api::Metadata<Block> for Runtime {
|
||||
|
||||
@@ -241,6 +241,10 @@ impl_runtime_apis! {
|
||||
fn initialize_block(header: &<Block as BlockT>::Header) {
|
||||
Executive::initialize_block(header)
|
||||
}
|
||||
|
||||
fn authorities() -> Vec<AuthorityId> {
|
||||
panic!("Deprecated, please use `AuthoritiesApi`.")
|
||||
}
|
||||
}
|
||||
|
||||
impl runtime_api::Metadata<Block> for Runtime {
|
||||
|
||||
@@ -59,7 +59,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
|
||||
spec_name: create_runtime_str!("node"),
|
||||
impl_name: create_runtime_str!("substrate-node"),
|
||||
authoring_version: 10,
|
||||
spec_version: 55,
|
||||
spec_version: 56,
|
||||
impl_version: 56,
|
||||
apis: RUNTIME_API_VERSIONS,
|
||||
};
|
||||
@@ -251,6 +251,10 @@ impl_runtime_apis! {
|
||||
fn initialize_block(header: &<Block as BlockT>::Header) {
|
||||
Executive::initialize_block(header)
|
||||
}
|
||||
|
||||
fn authorities() -> Vec<AuthorityIdFor<Block>> {
|
||||
panic!("Deprecated, please use `AuthoritiesApi`.")
|
||||
}
|
||||
}
|
||||
|
||||
impl client_api::Metadata<Block> for Runtime {
|
||||
|
||||
Reference in New Issue
Block a user