Make runtime api generate version and identifier information (#1226)

* Make `decl_runtime_apis!` implement `RuntimeApiInfo` for all runtime
apis

* Make the runtime side generate the info constants as well

* Make `RuntimeApiInfo` implementation use the correct generics

* Adds a test for the runtime api info stuff

* Remove duplicated code by using block from `test-client`

* Adds `compile_fail` tests for `api_version`

* Adds documentation for `api_version`

* Make `impl_runtime_apis!` generate `RUNTIME_API_VERSIONS`

* Update documentation and tests for `RUNTIME_API_VERSIONS`

* Implement `has_api` by using the `RuntimeApiInfo`

* Make `impl_runtime_apis` check that trait identifiers are unique

* Prefix all runtime api function with the corresponding trait

So `execute_block` will be called `Core_execute_block`.
This makes it possible to have traits implement a function with the
same name.

* Rebase master

* Update after master rebase
This commit is contained in:
Bastian Köcher
2018-12-10 11:48:07 +01:00
committed by GitHub
parent a4a67ccbe7
commit 1f6719346f
25 changed files with 661 additions and 396 deletions
+21 -47
View File
@@ -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<Block: BlockT>: Sized {
pub trait ConstructRuntimeApi<Block: BlockT> {
/// Construct an instance of the runtime api.
fn construct_runtime_api<'a, T: CallApiAt<Block>>(call: &'a T) -> ApiRef<'a, Self>;
fn construct_runtime_api<'a, T: CallRuntimeAt<Block>>(
call: &'a T
) -> ApiRef<'a, Self> where Self: Sized;
}
/// An extension for the `RuntimeApi`.
#[cfg(feature = "std")]
pub trait ApiExt {
pub trait ApiExt<Block: BlockT> {
/// 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<F: FnOnce(&Self) -> result::Result<R, E>, R, E>(
&self,
map_call: F
) -> result::Result<R, E>;
) -> result::Result<R, E> where Self: Sized;
/// Checks if the given api is implemented and versions match.
fn has_api<A: RuntimeApiInfo + ?Sized>(
&self,
at: &BlockId<Block>
) -> error::Result<bool> 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<Block: BlockT> {
pub trait CallRuntimeAt<Block: BlockT> {
/// 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<Block: BlockT> {
initialised_block: &mut Option<BlockId<Block>>,
) -> error::Result<Vec<u8>>;
/// Call the given api function with strong arguments at the given block
/// and returns the decoded result.
fn call_api_at_strong<In: Encode, Out: Decode>(
&self,
at: &BlockId<Block>,
function: &'static str,
args: &In,
changes: &mut OverlayedChanges,
initialised_block: &mut Option<BlockId<Block>>,
) -> error::Result<Out> 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<Block>) -> error::Result<RuntimeVersion>;
}
decl_runtime_apis! {