Module polkadot_primitives::runtime_api
source · Expand description
Runtime API module declares the trait ParachainHost which is part
of the Runtime API exposed from the Runtime to the Host.
The functions in trait ParachainHost` can be part of the stable API (which is versioned) or they can be staging (aka unstable/testing functions).
The separation outlined above is achieved with the versioned API feature
of decl_runtime_apis! and impl_runtime_apis!. Before moving on let’s
see a quick example about how API versioning works.
Runtime API versioning crash course
The versioning is achieved with the api_version attribute. It can be
placed on:
- trait declaration - represents the base version of the API.
- method declaration (inside a trait declaration) - represents a versioned method, which is not available in the base version.
- trait implementation - represents which version of the API is being implemented.
Let’s see a quick example:
sp_api::decl_runtime_apis! {
#[api_version(2)]
pub trait MyApi {
fn fn1();
fn fn2();
#[api_version(3)]
fn fn3();
#[api_version(4)]
fn fn4();
}
}
struct Runtime {}
sp_api::impl_runtime_apis! {
#[api_version(3)]
impl self::MyApi<Block> for Runtime {
fn fn1() {}
fn fn2() {}
fn fn3() {}
}
}
A new API named MyApi is declared with decl_runtime_apis!. The trait declaration
has got an api_version attribute which represents its base version - 2 in this case.
The API has got three methods - fn1, fn2, fn3 and fn4. fn3 and fn4 has got
an api_version attribute which makes them versioned methods. These methods do not exist
in the base version of the API. Behind the scenes the declaration above creates three
runtime APIs:
MyApiV2withfn1andfn2MyApiV3withfn1,fn2andfn3.MyApiV4withfn1,fn2,fn3andfn4.
Please note that v4 contains all methods from v3, v3 all methods from v2 and so on.
Back to our example. At the end runtime API is implemented for struct Runtime with
impl_runtime_apis macro. api_version attribute is attached to the impl block which
means that a version different from the base one is being implemented - in our case this
is v3.
This version of the API contains three methods so the impl block has got definitions
for them. Note that fn4 is not implemented as it is not part of this version of the API.
impl_runtime_apis generates a default implementation for it calling unimplemented!().
Hopefully this should be all you need to know in order to use versioned methods in the node.
For more details about how the API versioning works refer to spi_api
documentation here.
How versioned methods are used for ParachainHost
Let’s introduce two types of ParachainHost API implementation:
- stable - used on stable production networks like Polkadot and Kusama. There is only one stable API at a single point in time.
- staging - methods that are ready for production, but will be released on Rococo first. We can batch together multiple changes and then release all of them to production, by making staging production (bump base version). We can not change or remove any method in staging after a release, as this would break Rococo. It should be ok to keep adding methods to staging across several releases. For experimental methods, you have to keep them on a separate branch until ready.
The stable version of ParachainHost is indicated by the base version of the API. Any staging
method must use api_version attribute so that it is assigned to a specific version of a
staging API. This way in a single declaration one can see what’s the stable version of
ParachainHost and what staging versions/functions are available.
All stable API functions should use primitives from the latest version.
In the time of writing of this document - this is v2. So for example:
fn validators() -> Vec<v2::ValidatorId>;indicates a function from the stable v2 API.
All staging API functions should use primitives from vstaging. They should be clearly
separated from the stable primitives.
Traits
- The API for querying the state of parachains on-chain.