diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index 63c707c02b..c2d4a9eca0 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -2710,14 +2710,14 @@ dependencies = [ name = "sr-api-macros" version = "0.1.0" dependencies = [ - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 0.1.0", + "sr-version 0.1.0", "substrate-client 0.1.0", "substrate-primitives 0.1.0", + "substrate-test-client 0.1.0", "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/substrate/core/client/src/client.rs b/substrate/core/client/src/client.rs index 40bf6aa3d8..c555b95ad8 100644 --- a/substrate/core/client/src/client.rs +++ b/substrate/core/client/src/client.rs @@ -32,7 +32,7 @@ use runtime_primitives::traits::{ ApiRef, ProvideRuntimeApi, Digest, DigestItem, }; use runtime_primitives::BuildStorage; -use runtime_api::{Core as CoreAPI, CallApiAt, TaggedTransactionQueue, ConstructRuntimeApi}; +use runtime_api::{Core as CoreAPI, CallRuntimeAt, TaggedTransactionQueue, ConstructRuntimeApi}; use primitives::{Blake2Hasher, H256, ChangesTrieConfiguration, convert_hash}; use primitives::storage::{StorageKey, StorageData}; use primitives::storage::well_known_keys; @@ -288,7 +288,7 @@ impl Client where pub fn authorities_at(&self, id: &BlockId) -> error::Result> { match self.backend.blockchain().cache().and_then(|cache| cache.authorities_at(*id)) { Some(cached_value) => Ok(cached_value), - None => self.executor.call(id, "authorities",&[]) + None => self.executor.call(id, "Core_authorities",&[]) .and_then(|r| Vec::::decode(&mut &r.return_data[..]) .ok_or(error::ErrorKind::InvalidAuthoritiesSet.into())) } @@ -635,7 +635,7 @@ impl Client where let mut r = self.executor.call_at_state( transaction_state, &mut overlay, - "execute_block", + "Core_execute_block", &::new(import_headers.pre().clone(), body.clone().unwrap_or_default()).encode(), match (origin, self.block_execution_strategy) { (BlockOrigin::NetworkInitialSync, _) | (_, ExecutionStrategy::NativeWhenPossible) => @@ -1034,7 +1034,7 @@ impl ProvideRuntimeApi for Client where } } -impl CallApiAt for Client where +impl CallRuntimeAt for Client where B: backend::Backend, E: CallExecutor + Clone + Send + Sync, Block: BlockT, @@ -1050,7 +1050,8 @@ impl CallApiAt for Client where initialised_block: &mut Option>, ) -> error::Result> { //TODO: Find a better way to prevent double block initialization - if function != "initialise_block" && initialised_block.map(|id| id != *at).unwrap_or(true) { + if function != "Core_initialise_block" + && initialised_block.map(|id| id != *at).unwrap_or(true) { let parent = at; let header = <::Header as HeaderT>::new( self.block_number_from_id(parent)? @@ -1062,12 +1063,16 @@ impl CallApiAt for Client where .ok_or_else(|| error::ErrorKind::UnknownBlock(format!("{:?}", parent)))?, Default::default() ); - self.call_at_state(at, "initialise_block", header.encode(), changes)?; + self.call_at_state(at, "Core_initialise_block", header.encode(), changes)?; *initialised_block = Some(*at); } self.call_at_state(at, function, args, changes) } + + fn runtime_version_at(&self, at: &BlockId) -> error::Result { + self.runtime_version_at(at) + } } @@ -1238,7 +1243,7 @@ pub(crate) mod tests { use runtime_primitives::generic::DigestItem; use test_client::{self, TestClient}; use consensus::BlockOrigin; - use test_client::client::backend::Backend as TestBackend; + use test_client::client::{backend::Backend as TestBackend, runtime_api::ApiExt}; use test_client::BlockBuilderExt; use test_client::runtime::{self, Block, Transfer, RuntimeApi, test_api::TestAPI}; @@ -1335,6 +1340,17 @@ pub(crate) mod tests { ); } + #[test] + fn runtime_api_has_test_api() { + let client = test_client::new(); + + assert!( + client.runtime_api().has_api::>( + &BlockId::Number(client.info().unwrap().chain.best_number), + ).unwrap() + ); + } + #[test] fn authorities_call_works() { let client = test_client::new(); diff --git a/substrate/core/client/src/genesis.rs b/substrate/core/client/src/genesis.rs index 83c4338b8b..d7d398a4e9 100644 --- a/substrate/core/client/src/genesis.rs +++ b/substrate/core/client/src/genesis.rs @@ -91,7 +91,7 @@ mod tests { Some(&InMemoryChangesTrieStorage::new()), &mut overlay, &executor(), - "initialise_block", + "Core_initialise_block", &header.encode(), ExecutionStrategy::NativeWhenPossible, ).unwrap(); @@ -102,7 +102,7 @@ mod tests { Some(&InMemoryChangesTrieStorage::new()), &mut overlay, &executor(), - "apply_extrinsic", + "BlockBuilder_apply_extrinsic", &tx.encode(), ExecutionStrategy::NativeWhenPossible, ).unwrap(); @@ -113,7 +113,7 @@ mod tests { Some(&InMemoryChangesTrieStorage::new()), &mut overlay, &executor(), - "finalise_block", + "BlockBuilder_finalise_block", &[], ExecutionStrategy::NativeWhenPossible, ).unwrap(); @@ -157,7 +157,7 @@ mod tests { Some(&InMemoryChangesTrieStorage::new()), &mut overlay, &executor(), - "execute_block", + "Core_execute_block", &b1data, ExecutionStrategy::NativeWhenPossible, ).unwrap(); @@ -182,7 +182,7 @@ mod tests { Some(&InMemoryChangesTrieStorage::new()), &mut overlay, &executor(), - "execute_block", + "Core_execute_block", &b1data, ExecutionStrategy::AlwaysWasm, ).unwrap(); @@ -208,7 +208,7 @@ mod tests { Some(&InMemoryChangesTrieStorage::new()), &mut overlay, &Executor::new(), - "execute_block", + "Core_execute_block", &b1data, ExecutionStrategy::NativeWhenPossible, ).unwrap(); diff --git a/substrate/core/client/src/light/call_executor.rs b/substrate/core/client/src/light/call_executor.rs index 732b783b73..e77bf3309b 100644 --- a/substrate/core/client/src/light/call_executor.rs +++ b/substrate/core/client/src/light/call_executor.rs @@ -166,7 +166,7 @@ mod tests { .unwrap().storage_root(::std::iter::empty()).0; // 'fetch' execution proof from remote node - let remote_execution_proof = remote_client.execution_proof(&remote_block_id, "authorities", &[]).unwrap().1; + let remote_execution_proof = remote_client.execution_proof(&remote_block_id, "Core_authorities", &[]).unwrap().1; // check remote execution proof locally let local_executor = test_client::LocalExecutor::new(); @@ -179,7 +179,7 @@ mod tests { extrinsics_root: Default::default(), digest: Default::default(), }, - method: "authorities".into(), + method: "Core_authorities".into(), call_data: vec![], retry_count: None, }, remote_execution_proof).unwrap(); diff --git a/substrate/core/client/src/runtime_api.rs b/substrate/core/client/src/runtime_api.rs index 2e5c5e38ca..9ad92fb493 100644 --- a/substrate/core/client/src/runtime_api.rs +++ b/substrate/core/client/src/runtime_api.rs @@ -21,12 +21,13 @@ pub use state_machine::OverlayedChanges; #[doc(hidden)] pub use runtime_primitives::{ - traits::{Block as BlockT, GetNodeBlockType, GetRuntimeBlockType, ApiRef}, generic::BlockId, - transaction_validity::TransactionValidity + traits::{Block as BlockT, GetNodeBlockType, GetRuntimeBlockType, ApiRef, RuntimeApiInfo}, + generic::BlockId, transaction_validity::TransactionValidity }; -pub use runtime_version::{ApiId, RuntimeVersion}; #[doc(hidden)] -pub use rstd::slice; +pub use runtime_version::{ApiId, RuntimeVersion, ApisVec, create_apis_vec}; +#[doc(hidden)] +pub use rstd::{slice, mem}; #[cfg(feature = "std")] use rstd::result; pub use codec::{Encode, Decode}; @@ -38,14 +39,16 @@ use primitives::{AuthorityId, OpaqueMetadata}; /// Something that can be constructed to a runtime api. #[cfg(feature = "std")] -pub trait ConstructRuntimeApi: Sized { +pub trait ConstructRuntimeApi { /// Construct an instance of the runtime api. - fn construct_runtime_api<'a, T: CallApiAt>(call: &'a T) -> ApiRef<'a, Self>; + fn construct_runtime_api<'a, T: CallRuntimeAt>( + call: &'a T + ) -> ApiRef<'a, Self> where Self: Sized; } /// An extension for the `RuntimeApi`. #[cfg(feature = "std")] -pub trait ApiExt { +pub trait ApiExt { /// The given closure will be called with api instance. Inside the closure any api call is /// allowed. After doing the api call, the closure is allowed to map the `Result` to a /// different `Result` type. This can be important, as the internal data structure that keeps @@ -54,12 +57,18 @@ pub trait ApiExt { fn map_api_result result::Result, R, E>( &self, map_call: F - ) -> result::Result; + ) -> result::Result where Self: Sized; + + /// Checks if the given api is implemented and versions match. + fn has_api( + &self, + at: &BlockId + ) -> error::Result where Self: Sized; } -/// Something that can call the runtime api at a given block. +/// Something that can call into the runtime at a given block. #[cfg(feature = "std")] -pub trait CallApiAt { +pub trait CallRuntimeAt { /// Calls the given api function with the given encoded arguments at the given block /// and returns the encoded result. fn call_api_at( @@ -71,43 +80,8 @@ pub trait CallApiAt { initialised_block: &mut Option>, ) -> error::Result>; - /// Call the given api function with strong arguments at the given block - /// and returns the decoded result. - fn call_api_at_strong( - &self, - at: &BlockId, - function: &'static str, - args: &In, - changes: &mut OverlayedChanges, - initialised_block: &mut Option>, - ) -> error::Result where Self: Sized { - let raw = self.call_api_at( - at, - function, - args.encode(), - changes, - initialised_block, - )?; - - match Out::decode(&mut &raw[..]) { - Some(out) => Ok(out), - None => bail!(error::ErrorKind::CallResultDecode(function)), - } - } -} - -/// The ApiIds for the various standard runtime APIs. -pub mod id { - use super::ApiId; - - /// ApiId for the BlockBuilder trait. - pub const BLOCK_BUILDER: ApiId = *b"blkbuild"; - - /// ApiId for the TaggedTransactionQueue trait. - pub const TAGGED_TRANSACTION_QUEUE: ApiId = *b"validatx"; - - /// ApiId for the Metadata trait. - pub const METADATA: ApiId = *b"metadata"; + /// Returns the runtime version at the given block. + fn runtime_version_at(&self, at: &BlockId) -> error::Result; } decl_runtime_apis! { diff --git a/substrate/core/executor/src/native_executor.rs b/substrate/core/executor/src/native_executor.rs index b51b43e14d..15cc8abac3 100644 --- a/substrate/core/executor/src/native_executor.rs +++ b/substrate/core/executor/src/native_executor.rs @@ -61,7 +61,7 @@ fn fetch_cached_runtime_version<'a, E: Externalities>( let maybe_runtime_preproc = cache.entry(gen_cache_key(code)) .or_insert_with(|| match WasmModule::from_buffer(code) { Ok(module) => { - let version = wasm_executor.call_in_wasm_module(ext, heap_pages, &module, "version", &[]) + let version = wasm_executor.call_in_wasm_module(ext, heap_pages, &module, "Core_version", &[]) .ok() .and_then(|v| RuntimeVersion::decode(&mut v.as_slice())); RuntimePreproc::ValidCode(module, version) diff --git a/substrate/core/finality-grandpa/src/tests.rs b/substrate/core/finality-grandpa/src/tests.rs index d35ec84632..424e771b81 100644 --- a/substrate/core/finality-grandpa/src/tests.rs +++ b/substrate/core/finality-grandpa/src/tests.rs @@ -24,14 +24,14 @@ use parking_lot::Mutex; use tokio::runtime::current_thread; use keyring::Keyring; use client::{ - BlockchainEvents, runtime_api::{Core, RuntimeVersion, ApiExt, ConstructRuntimeApi, CallApiAt}, - error::Result + BlockchainEvents, error::Result, + runtime_api::{Core, RuntimeVersion, ApiExt, ConstructRuntimeApi, CallRuntimeAt}, }; use test_client::{self, runtime::BlockNumber}; use codec::Decode; use consensus_common::BlockOrigin; use std::{collections::HashSet, result}; -use runtime_primitives::traits::{ApiRef, ProvideRuntimeApi}; +use runtime_primitives::traits::{ApiRef, ProvideRuntimeApi, RuntimeApiInfo}; use runtime_primitives::generic::BlockId; use authorities::AuthoritySet; @@ -277,17 +277,21 @@ impl Core for RuntimeApi { } } -impl ApiExt for RuntimeApi { +impl ApiExt for RuntimeApi { fn map_api_result result::Result, R, E>( &self, _: F ) -> result::Result { unimplemented!("Not required for testing!") } + + fn has_api(&self, _: &BlockId) -> Result { + unimplemented!("Not required for testing!") + } } impl ConstructRuntimeApi for RuntimeApi { - fn construct_runtime_api<'a, T: CallApiAt>(_: &'a T) -> ApiRef<'a, Self> { + fn construct_runtime_api<'a, T: CallRuntimeAt>(_: &'a T) -> ApiRef<'a, Self> { unimplemented!("Not required for testing!") } } diff --git a/substrate/core/rpc/src/chain/tests.rs b/substrate/core/rpc/src/chain/tests.rs index a90d210a19..44e59b08f9 100644 --- a/substrate/core/rpc/src/chain/tests.rs +++ b/substrate/core/rpc/src/chain/tests.rs @@ -17,7 +17,7 @@ use super::*; use jsonrpc_macros::pubsub; use test_client::{self, TestClient}; -use test_client::runtime::{Block, Header}; +use test_client::runtime::{Block, Header, VERSION}; use consensus::BlockOrigin; #[test] @@ -259,13 +259,6 @@ fn should_return_runtime_version() { assert_matches!( client.runtime_version(None.into()), - Ok(ref ver) if ver == &RuntimeVersion { - spec_name: "test".into(), - impl_name: "parity-test".into(), - authoring_version: 1, - spec_version: 1, - impl_version: 1, - apis: (&[][..]).into() - } + Ok(ref ver) if ver == &VERSION ); } diff --git a/substrate/core/service/src/consensus.rs b/substrate/core/service/src/consensus.rs index 2a7b96f199..a879324403 100644 --- a/substrate/core/service/src/consensus.rs +++ b/substrate/core/service/src/consensus.rs @@ -23,7 +23,7 @@ use std::time::{self, Duration, Instant}; use std; use client::{self, error, Client as SubstrateClient, CallExecutor}; -use client::{block_builder::api::BlockBuilder as BlockBuilderApi, runtime_api::{id::BLOCK_BUILDER, Core}}; +use client::{block_builder::api::BlockBuilder as BlockBuilderApi, runtime_api::Core}; use codec::{Decode, Encode}; use consensus_common::{self, evaluation, offline_tracker::OfflineTracker}; use primitives::{H256, AuthorityId, ed25519, Blake2Hasher}; @@ -93,11 +93,11 @@ impl AuthoringApi for SubstrateClient where inherent_data: BasicInherentData, mut build_ctx: F, ) -> Result { - let runtime_version = self.runtime_version_at(at)?; - let mut block_builder = self.new_block_at(at)?; - if runtime_version.has_api(BLOCK_BUILDER, 1) { - self.runtime_api().inherent_extrinsics(at, &inherent_data)? + + let runtime_api = self.runtime_api(); + if runtime_api.has_api::>(at)? { + runtime_api.inherent_extrinsics(at, &inherent_data)? .into_iter().try_for_each(|i| block_builder.push(i))?; } diff --git a/substrate/core/sr-api-macros/Cargo.toml b/substrate/core/sr-api-macros/Cargo.toml index 7981281b27..5e6140df9d 100644 --- a/substrate/core/sr-api-macros/Cargo.toml +++ b/substrate/core/sr-api-macros/Cargo.toml @@ -10,11 +10,11 @@ proc-macro = true quote = "0.6" syn = { version = "^0.15.22", features = [ "full", "fold", "extra-traits", "visit" ] } proc-macro2 = "0.4" +blake2-rfc = "0.2" [dev-dependencies] substrate-client = { path = "../client" } +substrate-test-client = { path = "../test-client" } sr-primitives = { path = "../sr-primitives" } +sr-version = { path = "../sr-version" } substrate-primitives = { path = "../primitives" } -parity-codec = "2.1" -parity-codec-derive = "2.1" -serde = "1.0" diff --git a/substrate/core/sr-api-macros/src/compile_fail_tests.rs b/substrate/core/sr-api-macros/src/compile_fail_tests.rs index 14d77d003c..ec2c2387bd 100644 --- a/substrate/core/sr-api-macros/src/compile_fail_tests.rs +++ b/substrate/core/sr-api-macros/src/compile_fail_tests.rs @@ -110,40 +110,74 @@ mod adding_parameter_with_type_reference { */ } -mod missing_block_generic_parameter { +mod invalid_api_version { /*! ```compile_fail #[macro_use] extern crate substrate_client; extern crate sr_primitives as runtime_primitives; - extern crate substrate_primitives as primitives; + + decl_runtime_apis! { + #[api_version] + pub trait Api { + fn test(data: u64); + } + } + + fn main() {} + ``` + */ +} + +mod invalid_api_version_2 { + /*! + ```compile_fail #[macro_use] - extern crate parity_codec_derive; - extern crate serde; - extern crate core; + extern crate substrate_client; + extern crate sr_primitives as runtime_primitives; - use primitives::hash::H256; - use runtime_primitives::traits::{BlakeTwo256, GetNodeBlockType, Extrinsic as ExtrinsicT}; - - // All the stuff we need to declare our `Block` - pub type BlockNumber = u64; - pub type DigestItem = runtime_primitives::generic::DigestItem; - pub type Digest = runtime_primitives::generic::Digest; - #[derive(Clone, PartialEq, Eq, Encode, Decode, Debug)] - pub struct Extrinsic {} - - impl serde::Serialize for Extrinsic { - fn serialize(&self, seq: S) -> Result where S: ::serde::Serializer { - unimplemented!() + decl_runtime_apis! { + #[api_version("1")] + pub trait Api { + fn test(data: u64); } } - impl ExtrinsicT for Extrinsic { - fn is_signed(&self) -> Option { - unimplemented!() + + fn main() {} + ``` + */ +} + +mod invalid_api_version_3 { + /*! + ```compile_fail + #[macro_use] + extern crate substrate_client; + extern crate sr_primitives as runtime_primitives; + + decl_runtime_apis! { + #[api_version()] + pub trait Api { + fn test(data: u64); } } - pub type Header = runtime_primitives::generic::Header; - pub type Block = runtime_primitives::generic::Block; + + fn main() {} + ``` + */ +} + +mod missing_block_generic_parameter { + /*! + ```compile_fail + #[macro_use] + extern crate substrate_client; + extern crate substrate_test_client as test_client; + extern crate sr_primitives as runtime_primitives; + extern crate substrate_primitives as primitives; + + use runtime_primitives::traits::GetNodeBlockType; + use test_client::runtime::Block; /// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType` /// trait are done by the `construct_runtime!` macro in a real runtime. @@ -176,35 +210,12 @@ mod missing_path_for_trait { ```compile_fail #[macro_use] extern crate substrate_client; + extern crate substrate_test_client as test_client; extern crate sr_primitives as runtime_primitives; extern crate substrate_primitives as primitives; - #[macro_use] - extern crate parity_codec_derive; - extern crate serde; - extern crate core; - use primitives::hash::H256; - use runtime_primitives::traits::{BlakeTwo256, GetNodeBlockType, Extrinsic as ExtrinsicT}; - - // All the stuff we need to declare our `Block` - pub type BlockNumber = u64; - pub type DigestItem = runtime_primitives::generic::DigestItem; - pub type Digest = runtime_primitives::generic::Digest; - #[derive(Clone, PartialEq, Eq, Encode, Decode, Debug)] - pub struct Extrinsic {} - impl serde::Serialize for Extrinsic - { - fn serialize(&self, seq: S) -> Result where S: ::serde::Serializer { - unimplemented!() - } - } - impl ExtrinsicT for Extrinsic { - fn is_signed(&self) -> Option { - unimplemented!() - } - } - pub type Header = runtime_primitives::generic::Header; - pub type Block = runtime_primitives::generic::Block; + use runtime_primitives::traits::GetNodeBlockType; + use test_client::runtime::Block; /// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType` /// trait are done by the `construct_runtime!` macro in a real runtime. @@ -237,35 +248,12 @@ mod empty_impl_runtime_apis_call { ```compile_fail #[macro_use] extern crate substrate_client; + extern crate substrate_test_client as test_client; extern crate sr_primitives as runtime_primitives; extern crate substrate_primitives as primitives; - #[macro_use] - extern crate parity_codec_derive; - extern crate serde; - extern crate core; - use primitives::hash::H256; - use runtime_primitives::traits::{BlakeTwo256, GetNodeBlockType, Extrinsic as ExtrinsicT}; - - // All the stuff we need to declare our `Block` - pub type BlockNumber = u64; - pub type DigestItem = runtime_primitives::generic::DigestItem; - pub type Digest = runtime_primitives::generic::Digest; - #[derive(Clone, PartialEq, Eq, Encode, Decode, Debug)] - pub struct Extrinsic {} - impl serde::Serialize for Extrinsic - { - fn serialize(&self, seq: S) -> Result where S: ::serde::Serializer { - unimplemented!() - } - } - impl ExtrinsicT for Extrinsic { - fn is_signed(&self) -> Option { - unimplemented!() - } - } - pub type Header = runtime_primitives::generic::Header; - pub type Block = runtime_primitives::generic::Block; + use runtime_primitives::traits::GetNodeBlockType; + use test_client::runtime::Block; /// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType` /// trait are done by the `construct_runtime!` macro in a real runtime. @@ -292,35 +280,12 @@ mod type_reference_in_impl_runtime_apis_call { ```compile_fail #[macro_use] extern crate substrate_client; + extern crate substrate_test_client as test_client; extern crate sr_primitives as runtime_primitives; extern crate substrate_primitives as primitives; - #[macro_use] - extern crate parity_codec_derive; - extern crate serde; - extern crate core; - use primitives::hash::H256; - use runtime_primitives::traits::{BlakeTwo256, GetNodeBlockType, Extrinsic as ExtrinsicT}; - - // All the stuff we need to declare our `Block` - pub type BlockNumber = u64; - pub type DigestItem = runtime_primitives::generic::DigestItem; - pub type Digest = runtime_primitives::generic::Digest; - #[derive(Clone, PartialEq, Eq, Encode, Decode, Debug)] - pub struct Extrinsic {} - impl serde::Serialize for Extrinsic - { - fn serialize(&self, seq: S) -> Result where S: ::serde::Serializer { - unimplemented!() - } - } - impl ExtrinsicT for Extrinsic { - fn is_signed(&self) -> Option { - unimplemented!() - } - } - pub type Header = runtime_primitives::generic::Header; - pub type Block = runtime_primitives::generic::Block; + use runtime_primitives::traits::GetNodeBlockType; + use test_client::runtime::Block; /// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType` /// trait are done by the `construct_runtime!` macro in a real runtime. @@ -353,35 +318,12 @@ mod impl_incorrect_method_signature { ```compile_fail #[macro_use] extern crate substrate_client; + extern crate substrate_test_client as test_client; extern crate sr_primitives as runtime_primitives; extern crate substrate_primitives as primitives; - #[macro_use] - extern crate parity_codec_derive; - extern crate serde; - extern crate core; - use primitives::hash::H256; - use runtime_primitives::traits::{BlakeTwo256, GetNodeBlockType, Extrinsic as ExtrinsicT}; - - // All the stuff we need to declare our `Block` - pub type BlockNumber = u64; - pub type DigestItem = runtime_primitives::generic::DigestItem; - pub type Digest = runtime_primitives::generic::Digest; - #[derive(Clone, PartialEq, Eq, Encode, Decode, Debug)] - pub struct Extrinsic {} - impl serde::Serialize for Extrinsic - { - fn serialize(&self, seq: S) -> Result where S: ::serde::Serializer { - unimplemented!() - } - } - impl ExtrinsicT for Extrinsic { - fn is_signed(&self) -> Option { - unimplemented!() - } - } - pub type Header = runtime_primitives::generic::Header; - pub type Block = runtime_primitives::generic::Block; + use runtime_primitives::traits::GetNodeBlockType; + use test_client::runtime::Block; /// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType` /// trait are done by the `construct_runtime!` macro in a real runtime. @@ -406,3 +348,51 @@ mod impl_incorrect_method_signature { ``` */ } + +mod impl_two_traits_with_same_name { + /*! + ```compile_fail + #[macro_use] + extern crate substrate_client; + extern crate substrate_test_client as test_client; + extern crate sr_primitives as runtime_primitives; + extern crate substrate_primitives as primitives; + + use runtime_primitives::traits::GetNodeBlockType; + use test_client::runtime::Block; + + /// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType` + /// trait are done by the `construct_runtime!` macro in a real runtime. + struct Runtime {} + impl GetNodeBlockType for Runtime { + type NodeBlock = Block; + } + + decl_runtime_apis! { + pub trait Api { + fn test(data: u64); + } + } + + mod second { + decl_runtime_apis! { + pub trait Api { + fn test2(data: u64); + } + } + } + + impl_runtime_apis! { + impl self::Api for Runtime { + fn test(data: u64) {} + } + + impl second::Api for Runtime { + fn test2(data: u64) {} + } + } + + fn main() {} + ``` + */ +} 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 1f723519e1..376949a628 100644 --- a/substrate/core/sr-api-macros/src/decl_runtime_apis.rs +++ b/substrate/core/sr-api-macros/src/decl_runtime_apis.rs @@ -16,7 +16,7 @@ use utils::{ generate_crate_access, generate_hidden_includes, generate_runtime_mod_name_for_trait, - fold_fn_decl_for_client_side + fold_fn_decl_for_client_side, unwrap_or_error }; use proc_macro; @@ -27,12 +27,23 @@ use quote::quote; use syn::{ spanned::Spanned, parse_macro_input, parse::{Parse, ParseStream, Result, Error}, fold::{self, Fold}, FnDecl, parse_quote, ItemTrait, Generics, GenericParam, Attribute, - visit::{Visit, self}, FnArg, Pat, TraitBound, Type + visit::{Visit, self}, FnArg, Pat, TraitBound, Type, Meta, NestedMeta, Lit }; +use std::collections::HashMap; + +use blake2_rfc; + /// Unique identifier used to make the hidden includes unique for this macro. const HIDDEN_INCLUDES_ID: &str = "DECL_RUNTIME_APIS"; +/// The `core_trait` attribute. +const CORE_TRAIT_ATTRIBUTE: &str = "core_trait"; +/// The `api_version` attribute. +const API_VERSION_ATTRIBUTE: &str = "api_version"; +/// All attributes that we support in the declaratio of a runtime api trait. +const SUPPORTED_ATTRIBUTE_NAMES: &[&str] = &[CORE_TRAIT_ATTRIBUTE, API_VERSION_ATTRIBUTE]; + /// The structure used for parsing the runtime api declarations. struct RuntimeApiDecls { decls: Vec, @@ -59,15 +70,22 @@ fn extend_generics_with_block(generics: &mut Generics) { generics.gt_token = Some(parse_quote!(>)); } -// Check if `core_trait` attribute is present and remove it. Returns if the attribute was found. -fn remove_core_trait_attribute(attrs: &mut Vec) -> bool { - let mut found = false; +/// Remove all attributes from the vector that are supported by us in the declaration of a runtime +/// api trait. The returned hashmap contains all found attribute names as keys and the rest of the +/// attribute body as `TokenStream`. +fn remove_supported_attributes(attrs: &mut Vec) -> HashMap<&'static str, Attribute> { + let mut result = HashMap::new(); attrs.retain(|v| { - let res = v.path.is_ident("core_trait"); - found |= res; - !res + match SUPPORTED_ATTRIBUTE_NAMES.iter().filter(|a| v.path.is_ident(a)).next() { + Some(attribute) => { + result.insert(*attribute, v.clone()); + false + }, + None => true, + } }); - found + + result } /// Generate the decleration of the trait for the runtime. @@ -78,7 +96,11 @@ fn generate_runtime_decls(decls: &[ItemTrait]) -> TokenStream { let mut decl = decl.clone(); extend_generics_with_block(&mut decl.generics); let mod_name = generate_runtime_mod_name_for_trait(&decl.ident); - remove_core_trait_attribute(&mut decl.attrs); + let found_attributes = remove_supported_attributes(&mut decl.attrs); + let api_version = unwrap_or_error(get_api_version(&found_attributes).map(|v| { + generate_runtime_api_version(v as u32) + })); + let id = generate_runtime_api_id(&decl.ident.to_string()); result.push(quote!( #[doc(hidden)] @@ -86,6 +108,10 @@ fn generate_runtime_decls(decls: &[ItemTrait]) -> TokenStream { use super::*; #decl + + pub #api_version + + pub #id } )); } @@ -97,6 +123,7 @@ fn generate_runtime_decls(decls: &[ItemTrait]) -> TokenStream { struct ToClientSideDecl<'a> { block_id: &'a TokenStream, crate_: &'a TokenStream, + found_attributes: &'a mut HashMap<&'static str, Attribute>, } impl<'a> Fold for ToClientSideDecl<'a> { @@ -113,8 +140,9 @@ impl<'a> Fold for ToClientSideDecl<'a> { fn fold_item_trait(&mut self, mut input: ItemTrait) -> ItemTrait { extend_generics_with_block(&mut input.generics); + *self.found_attributes = remove_supported_attributes(&mut input.attrs); // Check if this is the `Core` runtime api trait. - let is_core_trait = remove_core_trait_attribute(&mut input.attrs); + let is_core_trait = self.found_attributes.contains_key(CORE_TRAIT_ATTRIBUTE); if is_core_trait { // Add all the supertraits we want to have for `Core`. @@ -124,7 +152,7 @@ impl<'a> Fold for ToClientSideDecl<'a> { + Send + Sync + #crate_::runtime_api::ConstructRuntimeApi - + #crate_::runtime_api::ApiExt + + #crate_::runtime_api::ApiExt ); } else { // Add the `Core` runtime api as super trait. @@ -139,6 +167,77 @@ impl<'a> Fold for ToClientSideDecl<'a> { } } +/// Parse the given attribute as `API_VERSION_ATTRIBUTE`. +fn parse_runtime_api_version(version: &Attribute) -> Result { + 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 + ) + ) + ); + + match meta { + Meta::List(list) => { + if list.nested.len() > 1 && list.nested.is_empty() { + err + } else { + match list.nested.first().as_ref().map(|v| v.value()) { + Some(NestedMeta::Literal(Lit::Int(i))) => { + Ok(i.value()) + }, + _ => err, + } + } + }, + _ => err, + } +} + +/// Generates the identifier as const variable for the given `trait_name` +/// by hashing the `trait_name`. +fn generate_runtime_api_id(trait_name: &str) -> TokenStream { + let mut res = [0; 8]; + res.copy_from_slice(blake2_rfc::blake2b::blake2b(8, &[], trait_name.as_bytes()).as_bytes()); + + quote!( const ID: [u8; 8] = [ #( #res ),* ]; ) +} + +/// Generates the const variable that holds the runtime api version. +fn generate_runtime_api_version(version: u32) -> TokenStream { + quote!( const VERSION: u32 = #version; ) +} + +/// Generates the implementation of `RuntimeApiInfo` for the given trait. +fn generate_runtime_info_impl(trait_: &ItemTrait, version: u64) -> TokenStream { + let trait_name = &trait_.ident; + let crate_ = generate_crate_access(HIDDEN_INCLUDES_ID); + let id = generate_runtime_api_id(&trait_name.to_string()); + let version = generate_runtime_api_version(version as u32); + let (impl_generics, ty_generics, where_clause) = trait_.generics.split_for_impl(); + + quote!( + #[cfg(any(feature = "std", test))] + impl #impl_generics #crate_::runtime_api::RuntimeApiInfo + for #trait_name #ty_generics #where_clause + { + #id + #version + } + ) +} + +/// 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 { + match found_attributes.get(&API_VERSION_ATTRIBUTE) { + Some(attr) => parse_runtime_api_version(attr), + None => Ok(1), + } +} + /// Generate the decleration of the trait for the client side. fn generate_client_side_decls(decls: &[ItemTrait]) -> TokenStream { let mut result = Vec::new(); @@ -148,9 +247,24 @@ fn generate_client_side_decls(decls: &[ItemTrait]) -> TokenStream { let crate_ = generate_crate_access(HIDDEN_INCLUDES_ID); let block_id = quote!( #crate_::runtime_api::BlockId ); - let mut to_client_side = ToClientSideDecl { crate_: &crate_, block_id: &block_id }; + let mut found_attributes = HashMap::new(); - result.push(to_client_side.fold_item_trait(decl)); + let decl = { + let mut to_client_side = ToClientSideDecl { + crate_: &crate_, + block_id: &block_id, + found_attributes: &mut found_attributes + }; + to_client_side.fold_item_trait(decl) + }; + + let api_version = get_api_version(&found_attributes); + + let runtime_info = unwrap_or_error( + api_version.map(|v| generate_runtime_info_impl(&decl, v)) + ); + + result.push(quote!( #decl #runtime_info )); } quote!( #( #result )* ) 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 6817366def..a6aa4b82a5 100644 --- a/substrate/core/sr-api-macros/src/impl_runtime_apis.rs +++ b/substrate/core/sr-api-macros/src/impl_runtime_apis.rs @@ -30,7 +30,7 @@ use syn::{ fold::{self, Fold}, FnDecl, parse_quote, Pat }; -use std::iter; +use std::{collections::HashSet, iter}; /// Unique identifier used to make the hidden includes unique for this macro. const HIDDEN_INCLUDES_ID: &str = "IMPL_RUNTIME_APIS"; @@ -165,11 +165,21 @@ fn extract_runtime_block_ident(trait_: &Path) -> Result<&TypePath> { } /// Generate all the implementation calls for the given functions. -fn generate_impl_calls(impls: &[ItemImpl], input: &Ident) -> Result> { +fn generate_impl_calls( + impls: &[ItemImpl], + input: &Ident +) -> Result> { let mut impl_calls = Vec::new(); for impl_ in impls { - let impl_trait = extend_with_runtime_decl_path(extract_impl_trait(impl_)?.clone()); + let impl_trait_path = extract_impl_trait(impl_)?; + let impl_trait = extend_with_runtime_decl_path(impl_trait_path.clone()); + let impl_trait_ident = &impl_trait_path + .segments + .last() + .ok_or_else(|| Error::new(impl_trait_path.span(), "Empty trait path not possible!"))? + .value() + .ident; for item in &impl_.items { match item { @@ -181,7 +191,9 @@ fn generate_impl_calls(impls: &[ItemImpl], input: &Ident) -> Result {}, } @@ -191,13 +203,19 @@ fn generate_impl_calls(impls: &[ItemImpl], input: &Ident) -> Result 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()); - let impl_calls = generate_impl_calls(impls, &data)?.into_iter().map(|(fn_name, impl_)| { - let fn_name = fn_name.to_string(); - quote!( #fn_name => Some({ #impl_ }), ) - }); + let impl_calls = generate_impl_calls(impls, &data)? + .into_iter() + .map(|(trait_, fn_name, impl_)| { + let name = prefix_function_with_trait(&trait_, &fn_name); + quote!( #name => Some({ #impl_ }), ) + }); Ok(quote!( #[cfg(feature = "std")] @@ -214,30 +232,37 @@ fn generate_dispatch_function(impls: &[ItemImpl]) -> Result { fn generate_wasm_interface(impls: &[ItemImpl]) -> Result { 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(|(fn_name, impl_)| { - quote!( - #[cfg(not(feature = "std"))] - #[no_mangle] - pub fn #fn_name(input_data: *mut u8, input_len: usize) -> u64 { - let mut #input = if input_len == 0 { - &[0u8; 0] - } else { - unsafe { - #c::runtime_api::slice::from_raw_parts(input_data, input_len) - } - }; + let impl_calls = generate_impl_calls(impls, &input)? + .into_iter() + .map(|(trait_, fn_name, impl_)| { + let fn_name = Ident::new( + &prefix_function_with_trait(&trait_, &fn_name), + Span::call_site() + ); - let output = { #impl_ }; - let res = output.as_ptr() as u64 + ((output.len() as u64) << 32); + quote!( + #[cfg(not(feature = "std"))] + #[no_mangle] + pub fn #fn_name(input_data: *mut u8, input_len: usize) -> u64 { + let mut #input = if input_len == 0 { + &[0u8; 0] + } else { + unsafe { + #c::runtime_api::slice::from_raw_parts(input_data, input_len) + } + }; - // Leak the output vector to avoid it being freed. - // This is fine in a WASM context since the heap - // will be discarded after the call. - ::core::mem::forget(output); - res - } - ) - }); + let output = { #impl_ }; + let res = output.as_ptr() as u64 + ((output.len() as u64) << 32); + + // Leak the output vector to avoid it being freed. + // This is fine in a WASM context since the heap + // will be discarded after the call. + #c::runtime_api::mem::forget(output); + res + } + ) + }); Ok(quote!( #( #impl_calls )* )) } @@ -272,7 +297,7 @@ fn generate_runtime_api_base_structures(impls: &[ItemImpl]) -> Result>, + call: ::std::ptr::NonNull<#crate_::runtime_api::CallRuntimeAt<#block>>, commit_on_success: ::std::cell::RefCell, initialised_block: ::std::cell::RefCell>, changes: ::std::cell::RefCell<#crate_::runtime_api::OverlayedChanges>, @@ -287,11 +312,11 @@ fn generate_runtime_api_base_structures(impls: &[ItemImpl]) -> Result for RuntimeApi { fn map_api_result ::std::result::Result, R, E>( &self, map_call: F - ) -> ::std::result::Result { + ) -> ::std::result::Result where Self: Sized { *self.commit_on_success.borrow_mut() = false; let res = map_call(self); *self.commit_on_success.borrow_mut() = true; @@ -300,17 +325,25 @@ fn generate_runtime_api_base_structures(impls: &[ItemImpl]) -> Result( + &self, + at: &#block_id + ) -> #crate_::error::Result where Self: Sized { + unsafe { self.call.as_ref().runtime_version_at(at) }.map(|r| r.has_api::()) + } } #[cfg(any(feature = "std", test))] impl #crate_::runtime_api::ConstructRuntimeApi<#block> for RuntimeApi { - fn construct_runtime_api<'a, T: #crate_::runtime_api::CallApiAt<#block>>( + fn construct_runtime_api<'a, T: #crate_::runtime_api::CallRuntimeAt<#block>>( call: &'a T - ) -> #crate_::runtime_api::ApiRef<'a, Self> { + ) -> #crate_::runtime_api::ApiRef<'a, Self> where Self: Sized { RuntimeApi { call: unsafe { ::std::ptr::NonNull::new_unchecked( - call as &#crate_::runtime_api::CallApiAt<#block> as *const _ as *mut _ + call as + &#crate_::runtime_api::CallRuntimeAt<#block> as *const _ as *mut _ ) }, commit_on_success: true.into(), @@ -423,6 +456,7 @@ struct ApiRuntimeImplToApiRuntimeApiImpl<'a> { node_block: &'a TokenStream, runtime_block: &'a TypePath, node_block_id: &'a TokenStream, + impl_trait_ident: &'a Ident, } impl<'a> Fold for ApiRuntimeImplToApiRuntimeApiImpl<'a> { @@ -457,7 +491,7 @@ impl<'a> Fold for ApiRuntimeImplToApiRuntimeApiImpl<'a> { *p = generate_unique_pattern(p.clone(), &mut generated_name_counter); p }); - let name = input.sig.ident.to_string(); + let name = prefix_function_with_trait(self.impl_trait_ident, &input.sig.ident); // Generate the new method implementation that calls into the runime. input.block = parse_quote!( { self.call_api_at(at, #name, &( #( #arg_names ),* )) } ); @@ -478,17 +512,26 @@ impl<'a> Fold for ApiRuntimeImplToApiRuntimeApiImpl<'a> { } } +/// Generate the implementations of the runtime apis for the `RuntimeApi` type. fn generate_api_impl_for_runtime_api(impls: &[ItemImpl]) -> Result { let mut result = Vec::with_capacity(impls.len()); for impl_ in impls { - let runtime_block = extract_runtime_block_ident(extract_impl_trait(&impl_)?)?; + let impl_trait = extract_impl_trait(&impl_)?; + let impl_trait_ident = &impl_trait + .segments + .last() + .ok_or_else(|| Error::new(impl_trait.span(), "Empty trait path not possible!"))? + .value() + .ident; + let runtime_block = extract_runtime_block_ident(impl_trait)?; let (node_block, node_block_id) = generate_node_block_and_block_id_ty(&impl_.self_ty); let mut visitor = ApiRuntimeImplToApiRuntimeApiImpl { runtime_block, node_block: &node_block, node_block_id: &node_block_id, + impl_trait_ident: &impl_trait_ident, }; result.push(visitor.fold_item_impl(impl_.clone())); @@ -497,6 +540,48 @@ fn generate_api_impl_for_runtime_api(impls: &[ItemImpl]) -> Result Ok(quote!( #( #result )* )) } +/// Generates `RUNTIME_API_VERSIONS` that holds all version information about the implemented +/// runtime apis. +fn generate_runtime_api_versions(impls: &[ItemImpl]) -> Result { + let mut result = Vec::with_capacity(impls.len()); + let mut processed_traits = HashSet::new(); + + for impl_ in impls { + let mut path = extend_with_runtime_decl_path(extract_impl_trait(&impl_)?.clone()); + // Remove the trait + let trait_ = path + .segments + .pop() + .expect("extract_impl_trait already checks that this is valid; qed") + .into_value() + .ident; + + let span = trait_.span(); + if !processed_traits.insert(trait_) { + 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!" + ) + ) + } + + let id: Path = parse_quote!( #path ID ); + let version: Path = parse_quote!( #path VERSION ); + + result.push(quote!( (#id, #version) )); + } + + let c = generate_crate_access(HIDDEN_INCLUDES_ID); + + Ok(quote!( + const RUNTIME_API_VERSIONS: #c::runtime_api::ApisVec = + #c::runtime_api::create_apis_vec!([ #( #result ),* ]); + )) +} + /// The implementation of the `impl_runtime_apis!` macro. pub fn impl_runtime_apis_impl(input: proc_macro::TokenStream) -> proc_macro::TokenStream { // Parse all impl blocks @@ -507,6 +592,7 @@ pub fn impl_runtime_apis_impl(input: proc_macro::TokenStream) -> proc_macro::Tok let base_runtime_api = unwrap_or_error(generate_runtime_api_base_structures(&api_impls)); let api_impls_for_runtime = unwrap_or_error(generate_api_impl_for_runtime(&api_impls)); let api_impls_for_runtime_api = unwrap_or_error(generate_api_impl_for_runtime_api(&api_impls)); + let runtime_api_versions = unwrap_or_error(generate_runtime_api_versions(&api_impls)); quote!( #hidden_includes @@ -517,6 +603,8 @@ pub fn impl_runtime_apis_impl(input: proc_macro::TokenStream) -> proc_macro::Tok #api_impls_for_runtime_api + #runtime_api_versions + pub mod api { use super::*; diff --git a/substrate/core/sr-api-macros/src/lib.rs b/substrate/core/sr-api-macros/src/lib.rs index 371cbbef6f..3dfc26c442 100644 --- a/substrate/core/sr-api-macros/src/lib.rs +++ b/substrate/core/sr-api-macros/src/lib.rs @@ -16,11 +16,12 @@ //! Macros for declaring and implementing runtime apis. -#![recursion_limit = "128"] +#![recursion_limit = "256"] extern crate proc_macro; extern crate proc_macro2; extern crate quote; extern crate syn; +extern crate blake2_rfc; use proc_macro::TokenStream; @@ -38,43 +39,27 @@ mod compile_fail_tests; /// by a path, e.g. `impl my_trait::MyTrait for Runtime`. The macro will use this path to access /// the declaration of the trait for the runtime side. /// -/// The macro also generates the implementation of the apis for the client side by generating the -/// `RuntimeApi` type. The `RuntimeApi` is hidden behind a `feature` called `std`. +/// The macro also generates the api implementations for the client side and provides it through +/// the `RuntimeApi` type. The `RuntimeApi` is hidden behind a `feature` called `std`. +/// +/// To expose version information about all implemented api traits, the constant +/// `RUNTIME_API_VERSIONS` is generated. This constant should be used to instantiate the `apis` +/// field of `RuntimeVersion`. /// /// # Example /// /// ```rust /// #[macro_use] /// extern crate substrate_client; +/// extern crate sr_version as version; +/// +/// use version::create_runtime_str; +/// # extern crate substrate_test_client as test_client; /// # extern crate sr_primitives as runtime_primitives; /// # extern crate substrate_primitives as primitives; -/// # #[macro_use] -/// # extern crate parity_codec_derive; -/// # extern crate serde; -/// # extern crate core; /// # -/// # use primitives::hash::H256; -/// # use runtime_primitives::traits::{BlakeTwo256, GetNodeBlockType, Extrinsic as ExtrinsicT}; -/// # -/// # // All the stuff we need to declare our `Block` -/// # pub type BlockNumber = u64; -/// # pub type DigestItem = runtime_primitives::generic::DigestItem; -/// # pub type Digest = runtime_primitives::generic::Digest; -/// # #[derive(Clone, PartialEq, Eq, Encode, Decode, Debug)] -/// # pub struct Extrinsic {} -/// # -/// # impl serde::Serialize for Extrinsic { -/// # fn serialize(&self, seq: S) -> Result where S: ::serde::Serializer { -/// # unimplemented!() -/// # } -/// # } -/// # impl ExtrinsicT for Extrinsic { -/// # fn is_signed(&self) -> Option { -/// # unimplemented!() -/// # } -/// # } -/// # pub type Header = runtime_primitives::generic::Header; -/// # pub type Block = runtime_primitives::generic::Block; +/// # use runtime_primitives::traits::GetNodeBlockType; +/// # use test_client::runtime::Block; /// # /// # /// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType` /// # /// trait are done by the `construct_runtime!` macro in a real runtime. @@ -114,6 +99,17 @@ mod compile_fail_tests; /// } /// } /// +/// /// Runtime version. This needs to be declared for each runtime. +/// pub const VERSION: version::RuntimeVersion = version::RuntimeVersion { +/// spec_name: create_runtime_str!("node"), +/// impl_name: create_runtime_str!("test-node"), +/// authoring_version: 1, +/// spec_version: 1, +/// impl_version: 0, +/// // Here we are exposing the runtime api versions. +/// apis: RUNTIME_API_VERSIONS, +/// }; +/// /// # fn main() {} /// ``` #[proc_macro] @@ -158,6 +154,36 @@ pub fn impl_runtime_apis(input: TokenStream) -> TokenStream { /// /// # fn main() {} /// ``` +/// +/// # Runtime api trait versioning +/// +/// To support versioning of the traits, the macro supports the attribute `#[api_version(1)]`. +/// The attribute supports any `u32` as version. By default, each trait is at version `1`, if no +/// version is provided. +/// +/// ```rust +/// #[macro_use] +/// extern crate substrate_client; +/// +/// decl_runtime_apis! { +/// /// Declare the api trait. +/// #[api_version(2)] +/// pub trait Balance { +/// /// Get the balance. +/// fn get_balance() -> u64; +/// /// Set the balance. +/// fn set_balance(val: u64); +/// /// In version 2, we added this new function. +/// fn increase_balance(val: u64); +/// } +/// } +/// +/// # fn main() {} +/// ``` +/// +/// To check if a given runtime implements a runtime api trait, the `RuntimeVersion` has the +/// function `has_api()`. Also the `ApiExt` provides a function `has_api(at: &BlockId)` to +/// check if the runtime at the given block id implements the requested runtime api trait. #[proc_macro] pub fn decl_runtime_apis(input: TokenStream) -> TokenStream { decl_runtime_apis::decl_runtime_apis_impl(input) 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 97dc2f9189..47822e538b 100644 --- a/substrate/core/sr-api-macros/tests/decl_and_impl.rs +++ b/substrate/core/sr-api-macros/tests/decl_and_impl.rs @@ -2,42 +2,14 @@ extern crate substrate_client; extern crate sr_primitives as runtime_primitives; extern crate substrate_primitives as primitives; -#[macro_use] -extern crate parity_codec_derive; -extern crate serde; -extern crate core; +extern crate substrate_test_client as test_client; -use primitives::hash::H256; -use runtime_primitives::traits::{ - BlakeTwo256, GetNodeBlockType, Extrinsic as ExtrinsicT, Block as BlockT -}; +use runtime_primitives::traits::{GetNodeBlockType, Block as BlockT}; use runtime_primitives::generic::BlockId; -use substrate_client::runtime_api; use primitives::AuthorityId; +use substrate_client::runtime_api::{self, RuntimeApiInfo}; use substrate_client::error::Result; - -// All the stuff we need to declare our `Block` -pub type BlockNumber = u64; -pub type DigestItem = runtime_primitives::generic::DigestItem; -pub type Digest = runtime_primitives::generic::Digest; -#[derive(Clone, PartialEq, Eq, Encode, Decode, Debug)] -pub struct Extrinsic {} - -impl serde::Serialize for Extrinsic { - fn serialize( - &self, - _: S - ) -> ::std::result::Result where S: ::serde::Serializer { - unimplemented!() - } -} -impl ExtrinsicT for Extrinsic { - fn is_signed(&self) -> Option { - unimplemented!() - } -} -pub type Header = runtime_primitives::generic::Header; -pub type Block = runtime_primitives::generic::Block; +use test_client::runtime::Block; /// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType` /// trait are done by the `construct_runtime!` macro in a real runtime. @@ -51,6 +23,12 @@ decl_runtime_apis! { fn test(data: u64); fn something_with_block(block: Block) -> Block; fn function_with_two_args(data: u64, block: Block); + fn same_name(); + } + + #[api_version(2)] + pub trait ApiWithCustomVersion { + fn same_name(); } } @@ -67,6 +45,12 @@ impl_runtime_apis! { fn function_with_two_args(_: u64, _: Block) { unimplemented!() } + + fn same_name() {} + } + + impl self::ApiWithCustomVersion for Runtime { + fn same_name() {} } impl runtime_api::Core for Runtime { @@ -91,3 +75,34 @@ fn test_client_side_function_signature() { let _something_with_block: fn(&RuntimeApi, &BlockId, &Block) -> Result = RuntimeApi::something_with_block; } + +#[test] +fn test_runtime_side_function_signature() { + let _api_same_name: fn(input_data: *mut u8, input_len: usize) -> u64 = api::Api_same_name; + let _api_with_version_same_name: fn(input_data: *mut u8, input_len: usize) -> u64 = + api::ApiWithCustomVersion_same_name; +} + +#[test] +fn check_runtime_api_info() { + assert_eq!(&Api::::ID, &runtime_decl_for_Api::ID); + assert_eq!(Api::::VERSION, runtime_decl_for_Api::VERSION); + assert_eq!(Api::::VERSION, 1); + + assert_eq!( + ApiWithCustomVersion::::VERSION, runtime_decl_for_ApiWithCustomVersion::VERSION + ); + assert_eq!(&ApiWithCustomVersion::::ID, &runtime_decl_for_ApiWithCustomVersion::ID); + assert_eq!(ApiWithCustomVersion::::VERSION, 2); +} + +fn check_runtime_api_versions_contains() { + assert!(RUNTIME_API_VERSIONS.iter().any(|v| v == &(T::ID, T::VERSION))); +} + +#[test] +fn check_runtime_api_versions() { + check_runtime_api_versions_contains::>(); + check_runtime_api_versions_contains::>(); + check_runtime_api_versions_contains::>(); +} diff --git a/substrate/core/sr-primitives/src/lib.rs b/substrate/core/sr-primitives/src/lib.rs index 1e61ac0545..95f13b1e74 100644 --- a/substrate/core/sr-primitives/src/lib.rs +++ b/substrate/core/sr-primitives/src/lib.rs @@ -64,11 +64,23 @@ pub type Justification = Vec; use traits::{Verify, Lazy}; -/// A String that is a `&'static str` on `no_std` and a `String` on `std`. -#[cfg(not(feature = "std"))] -pub type RuntimeString = &'static str; +/// A String that is a `&'static str` on `no_std` and a `Cow<'static, str>` on `std`. #[cfg(feature = "std")] pub type RuntimeString = ::std::borrow::Cow<'static, str>; +#[cfg(not(feature = "std"))] +pub type RuntimeString = &'static str; + +/// Create a const [RuntimeString]. +#[cfg(feature = "std")] +#[macro_export] +macro_rules! create_runtime_str { + ( $y:expr ) => {{ ::std::borrow::Cow::Borrowed($y) }} +} +#[cfg(not(feature = "std"))] +#[macro_export] +macro_rules! create_runtime_str { + ( $y:expr ) => {{ $y }} +} #[cfg(feature = "std")] pub use serde::{Serialize, de::DeserializeOwned}; diff --git a/substrate/core/sr-primitives/src/traits.rs b/substrate/core/sr-primitives/src/traits.rs index 0d33d7859f..7c9692cad3 100644 --- a/substrate/core/sr-primitives/src/traits.rs +++ b/substrate/core/sr-primitives/src/traits.rs @@ -639,3 +639,11 @@ pub trait GetNodeBlockType { /// The `NodeBlock` type. type NodeBlock: self::Block; } + +/// Something that provides information about a runtime api. +pub trait RuntimeApiInfo { + /// The identifier of the runtime api. + const ID: [u8; 8]; + /// The version of the runtime api. + const VERSION: u32; +} diff --git a/substrate/core/sr-version/src/lib.rs b/substrate/core/sr-version/src/lib.rs index b34abe901b..b24347baa8 100644 --- a/substrate/core/sr-version/src/lib.rs +++ b/substrate/core/sr-version/src/lib.rs @@ -35,8 +35,11 @@ extern crate sr_primitives as runtime_primitives; use std::fmt; #[cfg(feature = "std")] use std::collections::HashSet; +#[cfg(feature = "std")] +use runtime_primitives::traits::RuntimeApiInfo; use runtime_primitives::RuntimeString; +pub use runtime_primitives::create_runtime_str; /// The identity of a particular API interface that the runtime might provide. pub type ApiId = [u8; 8]; @@ -50,22 +53,16 @@ pub type ApisVec = ::std::borrow::Cow<'static, [(ApiId, u32)]>; #[cfg(not(feature = "std"))] pub type ApisVec = &'static [(ApiId, u32)]; -#[cfg(feature = "std")] -#[macro_export] -macro_rules! ver_str { - ( $y:expr ) => {{ ::std::borrow::Cow::Borrowed($y) }} -} - -#[cfg(not(feature = "std"))] -#[macro_export] -macro_rules! ver_str { - ( $y:expr ) => {{ $y }} -} - /// Create a vector of Api declarations. #[macro_export] -macro_rules! apis_vec { - ( $y:expr ) => { ver_str!(& $y) } +#[cfg(feature = "std")] +macro_rules! create_apis_vec { + ( $y:expr ) => { ::std::borrow::Cow::Borrowed(& $y) } +} +#[macro_export] +#[cfg(not(feature = "std"))] +macro_rules! create_apis_vec { + ( $y:expr ) => { & $y } } /// Runtime version. @@ -112,7 +109,13 @@ pub struct RuntimeVersion { #[cfg(feature = "std")] impl fmt::Display for RuntimeVersion { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}-{}:{}({}-{})", self.spec_name, self.spec_version, self.authoring_version, self.impl_name, self.impl_version) + write!(f, "{}-{}:{}({}-{})", + self.spec_name, + self.spec_version, + self.authoring_version, + self.impl_name, + self.impl_version + ) } } @@ -126,8 +129,10 @@ impl RuntimeVersion { } /// Check if this version supports a particular API. - pub fn has_api(&self, api: ApiId, version: u32) -> bool { - self.apis.iter().any(|&(ref s, v)| &api == s && version == v) + pub fn has_api(&self) -> bool { + self.apis.iter().any(|(s, v)| { + s == &A::ID && *v == A::VERSION + }) } } diff --git a/substrate/core/test-runtime/src/lib.rs b/substrate/core/test-runtime/src/lib.rs index e3228cae3c..469a44c195 100644 --- a/substrate/core/test-runtime/src/lib.rs +++ b/substrate/core/test-runtime/src/lib.rs @@ -67,12 +67,12 @@ use runtime_version::NativeVersion; /// Test runtime version. pub const VERSION: RuntimeVersion = RuntimeVersion { - spec_name: ver_str!("test"), - impl_name: ver_str!("parity-test"), + spec_name: create_runtime_str!("test"), + impl_name: create_runtime_str!("parity-test"), authoring_version: 1, spec_version: 1, impl_version: 1, - apis: apis_vec!([]), + apis: RUNTIME_API_VERSIONS, }; fn version() -> RuntimeVersion { diff --git a/substrate/core/test-runtime/wasm/Cargo.lock b/substrate/core/test-runtime/wasm/Cargo.lock index 0516c56241..38b82aff68 100644 --- a/substrate/core/test-runtime/wasm/Cargo.lock +++ b/substrate/core/test-runtime/wasm/Cargo.lock @@ -766,8 +766,8 @@ name = "serde_derive" version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -839,8 +839,9 @@ dependencies = [ name = "sr-api-macros" version = "0.1.0" dependencies = [ - "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -927,6 +928,7 @@ version = "0.1.0" dependencies = [ "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-api-macros 0.1.0", "srml-support-procedural-tools 0.1.0", "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/substrate/core/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm b/substrate/core/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm index 8f8477b0c0..5ca74bfa6b 100644 Binary files a/substrate/core/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm and b/substrate/core/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm differ diff --git a/substrate/node/executor/src/lib.rs b/substrate/node/executor/src/lib.rs index e76474f28d..f4dba9d013 100644 --- a/substrate/node/executor/src/lib.rs +++ b/substrate/node/executor/src/lib.rs @@ -134,9 +134,9 @@ mod tests { twox_128(&>::key_for(0)).to_vec() => vec![0u8; 32] ]); - let r = executor().call(&mut t, 8, BLOATY_CODE, "initialise_block", &vec![].and(&from_block_number(1u64)), true).0; + let r = executor().call(&mut t, 8, BLOATY_CODE, "Core_initialise_block", &vec![].and(&from_block_number(1u64)), true).0; assert!(r.is_ok()); - let v = executor().call(&mut t, 8, BLOATY_CODE, "apply_extrinsic", &vec![].and(&xt()), true).0.unwrap(); + let v = executor().call(&mut t, 8, BLOATY_CODE, "BlockBuilder_apply_extrinsic", &vec![].and(&xt()), true).0.unwrap(); let r = ApplyResult::decode(&mut &v[..]).unwrap(); assert_eq!(r, Err(ApplyError::CantPay)); } @@ -155,9 +155,9 @@ mod tests { twox_128(&>::key_for(0)).to_vec() => vec![0u8; 32] ]); - let r = executor().call(&mut t, 8, COMPACT_CODE, "initialise_block", &vec![].and(&from_block_number(1u64)), true).0; + let r = executor().call(&mut t, 8, COMPACT_CODE, "Core_initialise_block", &vec![].and(&from_block_number(1u64)), true).0; assert!(r.is_ok()); - let v = executor().call(&mut t, 8, COMPACT_CODE, "apply_extrinsic", &vec![].and(&xt()), true).0.unwrap(); + let v = executor().call(&mut t, 8, COMPACT_CODE, "BlockBuilder_apply_extrinsic", &vec![].and(&xt()), true).0.unwrap(); let r = ApplyResult::decode(&mut &v[..]).unwrap(); assert_eq!(r, Err(ApplyError::CantPay)); } @@ -176,9 +176,9 @@ mod tests { twox_128(&>::key_for(0)).to_vec() => vec![0u8; 32] ]); - let r = executor().call(&mut t, 8, COMPACT_CODE, "initialise_block", &vec![].and(&from_block_number(1u64)), true).0; + let r = executor().call(&mut t, 8, COMPACT_CODE, "Core_initialise_block", &vec![].and(&from_block_number(1u64)), true).0; assert!(r.is_ok()); - let r = executor().call(&mut t, 8, COMPACT_CODE, "apply_extrinsic", &vec![].and(&xt()), true).0; + let r = executor().call(&mut t, 8, COMPACT_CODE, "BlockBuilder_apply_extrinsic", &vec![].and(&xt()), true).0; assert!(r.is_ok()); runtime_io::with_externalities(&mut t, || { @@ -201,9 +201,9 @@ mod tests { twox_128(&>::key_for(0)).to_vec() => vec![0u8; 32] ]); - let r = executor().call(&mut t, 8, BLOATY_CODE, "initialise_block", &vec![].and(&from_block_number(1u64)), true).0; + let r = executor().call(&mut t, 8, BLOATY_CODE, "Core_initialise_block", &vec![].and(&from_block_number(1u64)), true).0; assert!(r.is_ok()); - let r = executor().call(&mut t, 8, BLOATY_CODE, "apply_extrinsic", &vec![].and(&xt()), true).0; + let r = executor().call(&mut t, 8, BLOATY_CODE, "BlockBuilder_apply_extrinsic", &vec![].and(&xt()), true).0; assert!(r.is_ok()); runtime_io::with_externalities(&mut t, || { @@ -387,7 +387,7 @@ mod tests { fn full_native_block_import_works() { let mut t = new_test_ext(false); - executor().call(&mut t, 8, COMPACT_CODE, "execute_block", &block1(false).0, true).0.unwrap(); + executor().call(&mut t, 8, COMPACT_CODE, "Core_execute_block", &block1(false).0, true).0.unwrap(); runtime_io::with_externalities(&mut t, || { assert_eq!(Balances::total_balance(&alice()), 41); @@ -429,7 +429,7 @@ mod tests { ]); }); - executor().call(&mut t, 8, COMPACT_CODE, "execute_block", &block2().0, true).0.unwrap(); + executor().call(&mut t, 8, COMPACT_CODE, "Core_execute_block", &block2().0, true).0.unwrap(); runtime_io::with_externalities(&mut t, || { assert_eq!(Balances::total_balance(&alice()), 30); @@ -505,14 +505,14 @@ mod tests { fn full_wasm_block_import_works() { let mut t = new_test_ext(false); - WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "execute_block", &block1(false).0).unwrap(); + WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "Core_execute_block", &block1(false).0).unwrap(); runtime_io::with_externalities(&mut t, || { assert_eq!(Balances::total_balance(&alice()), 41); assert_eq!(Balances::total_balance(&bob()), 69); }); - WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "execute_block", &block2().0).unwrap(); + WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "Core_execute_block", &block2().0).unwrap(); runtime_io::with_externalities(&mut t, || { assert_eq!(Balances::total_balance(&alice()), 30); @@ -680,7 +680,7 @@ mod tests { ] ); - WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "execute_block", &b.0).unwrap(); + WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "Core_execute_block", &b.0).unwrap(); runtime_io::with_externalities(&mut t, || { // Verify that the contract constructor worked well and code of TRANSFER contract is actually deployed. @@ -692,24 +692,45 @@ mod tests { fn wasm_big_block_import_fails() { let mut t = new_test_ext(false); - let r = WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "execute_block", &block1big().0); - assert!(!r.is_ok()); + assert!( + WasmExecutor::new().call( + &mut t, + 8, + COMPACT_CODE, + "Core_execute_block", + &block1big().0 + ).is_err() + ); } #[test] fn native_big_block_import_succeeds() { let mut t = new_test_ext(false); - let r = Executor::new().call(&mut t, 8, COMPACT_CODE, "execute_block", &block1big().0, true).0; - assert!(r.is_ok()); + Executor::new().call( + &mut t, + 8, + COMPACT_CODE, + "Core_execute_block", + &block1big().0, + true + ).0.unwrap(); } #[test] fn native_big_block_import_fails_on_fallback() { let mut t = new_test_ext(false); - let r = Executor::new().call(&mut t, 8, COMPACT_CODE, "execute_block", &block1big().0, false).0; - assert!(!r.is_ok()); + assert!( + Executor::new().call( + &mut t, + 8, + COMPACT_CODE, + "Core_execute_block", + &block1big().0, + false + ).0.is_err() + ); } #[test] @@ -727,9 +748,9 @@ mod tests { ]); let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.wasm"); - let r = WasmExecutor::new().call(&mut t, 8, &foreign_code[..], "initialise_block", &vec![].and(&from_block_number(1u64))); + let r = WasmExecutor::new().call(&mut t, 8, &foreign_code[..], "Core_initialise_block", &vec![].and(&from_block_number(1u64))); assert!(r.is_ok()); - let r = WasmExecutor::new().call(&mut t, 8, &foreign_code[..], "apply_extrinsic", &vec![].and(&xt())).unwrap(); + let r = WasmExecutor::new().call(&mut t, 8, &foreign_code[..], "BlockBuilder_apply_extrinsic", &vec![].and(&xt())).unwrap(); let r = ApplyResult::decode(&mut &r[..]).unwrap(); assert_eq!(r, Err(ApplyError::CantPay)); } @@ -749,9 +770,9 @@ mod tests { ]); let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm"); - let r = WasmExecutor::new().call(&mut t, 8, &foreign_code[..], "initialise_block", &vec![].and(&from_block_number(1u64))); + let r = WasmExecutor::new().call(&mut t, 8, &foreign_code[..], "Core_initialise_block", &vec![].and(&from_block_number(1u64))); assert!(r.is_ok()); - let r = WasmExecutor::new().call(&mut t, 8, &foreign_code[..], "apply_extrinsic", &vec![].and(&xt())).unwrap(); + let r = WasmExecutor::new().call(&mut t, 8, &foreign_code[..], "BlockBuilder_apply_extrinsic", &vec![].and(&xt())).unwrap(); let r = ApplyResult::decode(&mut &r[..]).unwrap(); assert_eq!(r, Ok(ApplyOutcome::Success)); @@ -764,7 +785,7 @@ mod tests { #[test] fn full_native_block_import_works_with_changes_trie() { let mut t = new_test_ext(true); - Executor::new().call(&mut t, 8, COMPACT_CODE, "execute_block", &block1(true).0, true).0.unwrap(); + Executor::new().call(&mut t, 8, COMPACT_CODE, "Core_execute_block", &block1(true).0, true).0.unwrap(); assert!(t.storage_changes_root(Default::default(), 0).is_some()); } @@ -772,7 +793,7 @@ mod tests { #[test] fn full_wasm_block_import_works_with_changes_trie() { let mut t = new_test_ext(true); - WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "execute_block", &block1(true).0).unwrap(); + WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "Core_execute_block", &block1(true).0).unwrap(); assert!(t.storage_changes_root(Default::default(), 0).is_some()); } @@ -786,8 +807,8 @@ mod tests { fn wasm_execute_block(b: &mut Bencher) { b.iter(|| { let mut t = new_test_ext(false); - WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "execute_block", &block1(false).0).unwrap(); - WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "execute_block", &block2().0).unwrap(); + WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "Core_execute_block", &block1(false).0).unwrap(); + WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "Core_execute_block", &block2().0).unwrap(); }); } } diff --git a/substrate/node/runtime/src/lib.rs b/substrate/node/runtime/src/lib.rs index b8ff92d1dd..5c983b295d 100644 --- a/substrate/node/runtime/src/lib.rs +++ b/substrate/node/runtime/src/lib.rs @@ -59,9 +59,9 @@ use substrate_primitives::u32_trait::{_2, _4}; use node_primitives::{ AccountId, AccountIndex, Balance, BlockNumber, Hash, Index, SessionKey, Signature }; -use grandpa::fg_primitives::{self, ScheduledChange, id::*}; +use grandpa::fg_primitives::{self, ScheduledChange}; use client::{ - block_builder::api as block_builder_api, runtime_api::{self as client_api, id::*} + block_builder::api as block_builder_api, runtime_api as client_api }; use runtime_primitives::{ApplyResult, CheckInherentError, BasicInherentData}; use runtime_primitives::transaction_validity::TransactionValidity; @@ -91,17 +91,12 @@ const NOTE_OFFLINE_POSITION: u32 = 1; /// Runtime version. pub const VERSION: RuntimeVersion = RuntimeVersion { - spec_name: ver_str!("node"), - impl_name: ver_str!("substrate-node"), + spec_name: create_runtime_str!("node"), + impl_name: create_runtime_str!("substrate-node"), authoring_version: 1, spec_version: 1, impl_version: 0, - apis: apis_vec!([ - (BLOCK_BUILDER, 1), - (TAGGED_TRANSACTION_QUEUE, 1), - (METADATA, 1), - (GRANDPA_API, 1), - ]), + apis: RUNTIME_API_VERSIONS, }; /// Native version. diff --git a/substrate/node/runtime/wasm/Cargo.lock b/substrate/node/runtime/wasm/Cargo.lock index 6c6303d863..41a4a3dd66 100644 --- a/substrate/node/runtime/wasm/Cargo.lock +++ b/substrate/node/runtime/wasm/Cargo.lock @@ -827,8 +827,8 @@ name = "serde_derive" version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -900,8 +900,9 @@ dependencies = [ name = "sr-api-macros" version = "0.1.0" dependencies = [ - "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1164,6 +1165,7 @@ version = "0.1.0" dependencies = [ "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-api-macros 0.1.0", "srml-support-procedural-tools 0.1.0", "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/substrate/node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm b/substrate/node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm index fa1fd989ff..2e58c0458a 100644 Binary files a/substrate/node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm and b/substrate/node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm differ