diff --git a/substrate/core/client/src/block_builder/api.rs b/substrate/core/client/src/block_builder/api.rs index 48abb38024..44663a7094 100644 --- a/substrate/core/client/src/block_builder/api.rs +++ b/substrate/core/client/src/block_builder/api.rs @@ -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: ::Extrinsic) -> ApplyResult; /// Finish the current block. + #[renamed("finalise_block", 3)] fn finalize_block() -> ::Header; /// Generate inherent extrinsics. The inherent data will vary from chain to chain. fn inherent_extrinsics(inherent: InherentData) -> Vec<::Extrinsic>; diff --git a/substrate/core/client/src/call_executor.rs b/substrate/core/client/src/call_executor.rs index 20460f72ad..b0bf9b4c2c 100644 --- a/substrate/core/client/src/call_executor.rs +++ b/substrate/core/client/src/call_executor.rs @@ -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 @@ -220,7 +221,15 @@ where mut side_effects_handler: Option<&mut O>, ) -> Result, error::Error> where ExecutionManager: 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::::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< diff --git a/substrate/core/client/src/runtime_api.rs b/substrate/core/client/src/runtime_api.rs index 6bc43ab270..68eed3b73c 100644 --- a/substrate/core/client/src/runtime_api.rs +++ b/substrate/core/client/src/runtime_api.rs @@ -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 { 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: &::Header); + /// Returns the authorities. + #[deprecated(since = "1.0", note = "Please switch to `AuthoritiesApi`.")] + fn authorities() -> Vec>; } /// The `Metadata` api trait that returns metadata for the runtime. diff --git a/substrate/core/consensus/aura/src/lib.rs b/substrate/core/consensus/aura/src/lib.rs index eb785e6162..803395b596 100644 --- a/substrate/core/consensus/aura/src/lib.rs +++ b/substrate/core/consensus/aura/src/lib.rs @@ -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 Authorities for AuraVerifier where } } +#[allow(deprecated)] fn authorities(client: &C, at: &BlockId) -> Result>, ConsensusError> where B: Block, C: ProvideRuntimeApi + ProvideCache, @@ -694,8 +695,13 @@ fn authorities(client: &C, at: &BlockId) -> Result>(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. diff --git a/substrate/core/finality-grandpa/src/tests.rs b/substrate/core/finality-grandpa/src/tests.rs index f0d5894bb6..2fd9da8944 100644 --- a/substrate/core/finality-grandpa/src/tests.rs +++ b/substrate/core/finality-grandpa/src/tests.rs @@ -267,7 +267,7 @@ impl ProvideRuntimeApi for TestApi { } impl Core for RuntimeApi { - fn version_runtime_api_impl( + fn Core_version_runtime_api_impl( &self, _: &BlockId, _: ExecutionContext, @@ -277,7 +277,7 @@ impl Core for RuntimeApi { unimplemented!("Not required for testing!") } - fn execute_block_runtime_api_impl( + fn Core_execute_block_runtime_api_impl( &self, _: &BlockId, _: ExecutionContext, @@ -287,7 +287,7 @@ impl Core for RuntimeApi { unimplemented!("Not required for testing!") } - fn initialize_block_runtime_api_impl( + fn Core_initialize_block_runtime_api_impl( &self, _: &BlockId, _: ExecutionContext, @@ -296,6 +296,15 @@ impl Core for RuntimeApi { ) -> Result> { unimplemented!("Not required for testing!") } + fn Core_authorities_runtime_api_impl( + &self, + _: &BlockId, + _: ExecutionContext, + _: Option<()>, + _: Vec, + ) -> Result>> { + unimplemented!("Not required for testing!") + } } impl ApiExt for RuntimeApi { @@ -312,7 +321,7 @@ impl ApiExt for RuntimeApi { } impl GrandpaApi for RuntimeApi { - fn grandpa_authorities_runtime_api_impl( + fn GrandpaApi_grandpa_authorities_runtime_api_impl( &self, at: &BlockId, _: ExecutionContext, @@ -326,7 +335,7 @@ impl GrandpaApi for RuntimeApi { } } - fn grandpa_pending_change_runtime_api_impl( + fn GrandpaApi_grandpa_pending_change_runtime_api_impl( &self, at: &BlockId, _: ExecutionContext, @@ -343,7 +352,7 @@ impl GrandpaApi 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, _: ExecutionContext, diff --git a/substrate/core/rpc/src/state/tests.rs b/substrate/core/rpc/src/state/tests.rs index 6746685d36..a63b8489eb 100644 --- a/substrate/core/rpc/src/state/tests.rs +++ b/substrate/core/rpc/src/state/tests.rs @@ -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]]}"# ); } diff --git a/substrate/core/sr-api-macros/src/decl_runtime_apis.rs b/substrate/core/sr-api-macros/src/decl_runtime_apis.rs index 9e4c38f087..8ec35bc5c6 100644 --- a/substrate/core/sr-api-macros/src/decl_runtime_apis.rs +++ b/substrate/core/sr-api-macros/src/decl_runtime_apis.rs @@ -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) -> 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 { 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 { .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 { 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 { 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 { + 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 + ::std::panic::UnwindSafe, + Block: #crate_::runtime_api::BlockT, + T: #crate_::runtime_api::CallRuntimeAt, + >( + call_runtime_at: &T, + at: &#crate_::runtime_api::BlockId, + args: Vec, + changes: &mut #crate_::runtime_api::OverlayedChanges, + initialized_block: &mut Option<#crate_::runtime_api::BlockId>, + native_call: Option, + context: #crate_::runtime_api::ExecutionContext, + ) -> #crate_::error::Result<#crate_::runtime_api::NativeOrEncoded> { + 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:: _>( + 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, + 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 ); 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(), diff --git a/substrate/core/sr-api-macros/src/impl_runtime_apis.rs b/substrate/core/sr-api-macros/src/impl_runtime_apis.rs index b5dd3f21c5..903f3e4028 100644 --- a/substrate/core/sr-api-macros/src/impl_runtime_apis.rs +++ b/substrate/core/sr-api-macros/src/impl_runtime_apis.rs @@ -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 { let data = Ident::new("data", Span::call_site()); @@ -196,7 +189,7 @@ fn generate_dispatch_function(impls: &[ItemImpl]) -> Result { _ => 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> RuntimeApiImpl { fn call_api_at< R: #crate_::runtime_api::Encode + #crate_::runtime_api::Decode + PartialEq, - NC: FnOnce() -> ::std::result::Result + ::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> >( &self, - at: &#block_id, - function: &'static str, - args: Vec, - native_call: Option, - context: #crate_::runtime_api::ExecutionContext + call_api_at: F, ) -> #crate_::error::Result<#crate_::runtime_api::NativeOrEncoded> { 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 }; - 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 .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 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())); diff --git a/substrate/core/sr-api-macros/src/utils.rs b/substrate/core/sr-api-macros/src/utils.rs index e593e41ebe..21000f431b 100644 --- a/substrate/core/sr-api-macros/src/utils.rs +++ b/substrate/core/sr-api-macros/src/utils.rs @@ -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(trait_: &Ident, function: &F) -> String { + format!("{}_{}", trait_.to_string(), function.to_string()) +} diff --git a/substrate/core/sr-api-macros/tests/decl_and_impl.rs b/substrate/core/sr-api-macros/tests/decl_and_impl.rs index a8b3156123..51f95d51b1 100644 --- a/substrate/core/sr-api-macros/tests/decl_and_impl.rs +++ b/substrate/core/sr-api-macros/tests/decl_and_impl.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -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(_: &::Header) { unimplemented!() } + fn authorities() -> Vec> { + unimplemented!() + } } } diff --git a/substrate/core/test-runtime/src/lib.rs b/substrate/core/test-runtime/src/lib.rs index 028bb7ba52..3d403800a7 100644 --- a/substrate/core/test-runtime/src/lib.rs +++ b/substrate/core/test-runtime/src/lib.rs @@ -296,6 +296,10 @@ cfg_if! { fn initialize_block(header: &::Header) { system::initialize_block(header) } + + fn authorities() -> Vec { + panic!("Deprecated, please use `AuthoritiesApi`.") + } } impl client_api::Metadata for Runtime { @@ -403,6 +407,10 @@ cfg_if! { fn initialize_block(header: &::Header) { system::initialize_block(header) } + + fn authorities() -> Vec { + panic!("Deprecated, please use `AuthoritiesApi`.") + } } impl client_api::Metadata for Runtime { diff --git a/substrate/node-template/runtime/src/lib.rs b/substrate/node-template/runtime/src/lib.rs index 5299831ea5..a6aa01bc87 100644 --- a/substrate/node-template/runtime/src/lib.rs +++ b/substrate/node-template/runtime/src/lib.rs @@ -241,6 +241,10 @@ impl_runtime_apis! { fn initialize_block(header: &::Header) { Executive::initialize_block(header) } + + fn authorities() -> Vec { + panic!("Deprecated, please use `AuthoritiesApi`.") + } } impl runtime_api::Metadata for Runtime { diff --git a/substrate/node/runtime/src/lib.rs b/substrate/node/runtime/src/lib.rs index 24db6e7419..816e337326 100644 --- a/substrate/node/runtime/src/lib.rs +++ b/substrate/node/runtime/src/lib.rs @@ -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: &::Header) { Executive::initialize_block(header) } + + fn authorities() -> Vec> { + panic!("Deprecated, please use `AuthoritiesApi`.") + } } impl client_api::Metadata for Runtime {