mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 17:01:09 +00:00
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:
@@ -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! {
|
||||
|
||||
Reference in New Issue
Block a user