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:
Bastian Köcher
2019-04-02 10:05:35 +02:00
committed by Gav Wood
parent e89ce263bd
commit 345145326b
13 changed files with 288 additions and 81 deletions
@@ -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>;
+14 -6
View File
@@ -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<
+7
View File
@@ -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.
+9 -3
View File
@@ -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.
+15 -6
View File
@@ -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,
+1 -1
View File
@@ -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()));
+12 -2
View File
@@ -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!()
}
}
}
+8
View File
@@ -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 {
+5 -1
View File
@@ -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 {