Macro sp_api::impl_runtime_apis
source · impl_runtime_apis!() { /* proc-macro */ }
Expand description
Tags given trait implementations as runtime apis.
All traits given to this macro, need to be declared with the
decl_runtime_apis!
macro. The implementation of the trait
should follow the declaration given to the
decl_runtime_apis!
macro, besides the Block
type that
is required as first generic parameter for each runtime api trait. When implementing a
runtime api trait, it is required that the trait is referenced 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 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
use sp_version::create_runtime_str;
/// All runtime api implementations need to be done in one call of the macro!
sp_api::impl_runtime_apis! {
impl self::Balance<Block> for Runtime {
fn get_balance() -> u64 {
1
}
fn set_balance(_bal: u64) {
// Store the balance
}
}
impl self::BlockBuilder<Block> for Runtime {
fn build_block() -> Block {
unimplemented!("Please implement me!")
}
}
}
/// Runtime version. This needs to be declared for each runtime.
pub const VERSION: sp_version::RuntimeVersion = sp_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,
transaction_version: 1,
system_version: 1,
};
§Implementing specific api version
If decl_runtime_apis!
declares multiple versions for an api impl_runtime_apis!
should specify which version it implements by adding api_version
attribute to the
impl
block. If omitted - the base/default version is implemented. Here is an example:
sp_api::impl_runtime_apis! {
#[api_version(3)]
impl self::Balance<Block> for Runtime {
// implementation
}
}
In this case Balance
api version 3 is being implemented for Runtime
. The impl
block
must contain all methods declared in version 3 and below.
§Conditional version implementation
impl_runtime_apis!
supports cfg_attr
attribute for conditional compilation. For example
let’s say you want to implement a staging version of the runtime api and put it behind a
feature flag. You can do it this way:
pub enum Runtime {}
sp_api::decl_runtime_apis! {
pub trait ApiWithStagingMethod {
fn stable_one(data: u64);
#[api_version(99)]
fn staging_one();
}
}
sp_api::impl_runtime_apis! {
#[cfg_attr(feature = "enable-staging-api", api_version(99))]
impl self::ApiWithStagingMethod<Block> for Runtime {
fn stable_one(_: u64) {}
#[cfg(feature = "enable-staging-api")]
fn staging_one() {}
}
}
decl_runtime_apis!
declares two version of the api - 1 (the default one, which is
considered stable in our example) and 99 (which is considered staging). In
impl_runtime_apis!
a cfg_attr
attribute is attached to the ApiWithStagingMethod
implementation. If the code is compiled with enable-staging-api
feature a version 99 of
the runtime api will be built which will include staging_one
. Note that staging_one
implementation is feature gated by #[cfg(feature = ... )]
attribute.
If the code is compiled without enable-staging-api
version 1 (the default one) will be
built which doesn’t include staging_one
.
cfg_attr
can also be used together with api_version
. For the next snippet will build
version 99 if enable-staging-api
is enabled and version 2 otherwise because both
cfg_attr
and api_version
are attached to the impl block:
#[cfg_attr(feature = "enable-staging-api", api_version(99))]
#[api_version(2)]
impl self::ApiWithStagingAndVersionedMethods<Block> for Runtime {
// impl skipped
}