Refactor the runtime API to use traits. (#878)

* Add missing `As` imports.

* Adds new API traits that will be used by the client and runtime

* Switch consensus to new API's

* Switches transaction-pool to new API's

* Move runtime api stuff into its own crate

* Adds `impl_apis!` macro for implementing the new API traits

* Make `metadata` return directly a blob

* Runtime replace `impl_stubs!` with `impl_apis!`

* Switches to none feature based approach for declaring the different API traits

* Fixes compilation error

* Fixes errors

* Make the `decl_apis!` trait usable from the outside

* Make the `test-client` use the new API traits

* Remove last `impl_stubs!` bits and move some of them into wasm executor for tests

* A little bit more documentation
This commit is contained in:
Bastian Köcher
2018-10-09 10:58:29 +02:00
committed by Gav Wood
parent fb058ae235
commit 2c65ad6c7b
25 changed files with 1058 additions and 256 deletions
+85 -31
View File
@@ -20,9 +20,11 @@
// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.
#![recursion_limit="256"]
#[macro_use]
extern crate sr_io as runtime_io;
#[macro_use]
extern crate sr_api as runtime_api;
#[macro_use]
extern crate srml_support;
@@ -61,8 +63,11 @@ mod checked_block;
use rstd::prelude::*;
use substrate_primitives::u32_trait::{_2, _4};
use node_primitives::{AccountId, AccountIndex, Balance, BlockNumber, Hash, Index, SessionKey, Signature, InherentData};
use runtime_api::runtime::*;
use runtime_primitives::ApplyResult;
use runtime_primitives::transaction_validity::TransactionValidity;
use runtime_primitives::generic;
use runtime_primitives::traits::{Convert, BlakeTwo256, DigestItem};
use runtime_primitives::traits::{Convert, BlakeTwo256, DigestItem, Block as BlockT};
use version::{RuntimeVersion, ApiId};
use council::{motions as council_motions, voting as council_voting};
#[cfg(feature = "std")]
@@ -243,37 +248,86 @@ pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, Index, Call>;
/// Executive: handles dispatch to the various modules.
pub type Executive = executive::Executive<Runtime, Block, balances::ChainContext<Runtime>, Balances, AllModules>;
pub mod api {
impl_stubs!(
version => |()| super::VERSION,
metadata => |()| super::Runtime::metadata(),
authorities => |()| super::Consensus::authorities(),
initialise_block => |header| super::Executive::initialise_block(&header),
apply_extrinsic => |extrinsic| super::Executive::apply_extrinsic(extrinsic),
execute_block => |block| super::Executive::execute_block(block),
finalise_block => |()| super::Executive::finalise_block(),
inherent_extrinsics => |inherent| super::inherent_extrinsics(inherent),
validator_count => |()| super::Session::validator_count(),
validators => |()| super::Session::validators(),
timestamp => |()| super::Timestamp::get(),
random_seed => |()| super::System::random_seed(),
account_nonce => |account| super::System::account_nonce(&account),
lookup_address => |address| super::Balances::lookup_address(address),
validate_transaction => |tx| super::Executive::validate_transaction(tx)
);
}
impl_apis! {
impl Core<Block, SessionKey> for Runtime {
fn version() -> RuntimeVersion {
VERSION
}
/// Produces the list of inherent extrinsics.
fn inherent_extrinsics(data: InherentData) -> Vec<UncheckedExtrinsic> {
let mut inherent = vec![generic::UncheckedMortalExtrinsic::new_unsigned(
Call::Timestamp(TimestampCall::set(data.timestamp))
)];
fn authorities() -> Vec<SessionKey> {
Consensus::authorities()
}
if !data.offline_indices.is_empty() {
inherent.push(generic::UncheckedMortalExtrinsic::new_unsigned(
Call::Consensus(ConsensusCall::note_offline(data.offline_indices))
));
fn execute_block(block: Block) {
Executive::execute_block(block)
}
}
inherent
impl Metadata for Runtime {
fn metadata() -> Vec<u8> {
Runtime::metadata()
}
}
impl BlockBuilder<Block, InherentData, UncheckedExtrinsic> for Runtime {
fn initialise_block(header: <Block as BlockT>::Header) {
Executive::initialise_block(&header)
}
fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyResult {
Executive::apply_extrinsic(extrinsic)
}
fn finalise_block() -> <Block as BlockT>::Header {
Executive::finalise_block()
}
fn inherent_extrinsics(data: InherentData) -> Vec<UncheckedExtrinsic> {
let mut inherent = vec![generic::UncheckedMortalExtrinsic::new_unsigned(
Call::Timestamp(TimestampCall::set(data.timestamp))
)];
if !data.offline_indices.is_empty() {
inherent.push(generic::UncheckedMortalExtrinsic::new_unsigned(
Call::Consensus(ConsensusCall::note_offline(data.offline_indices))
));
}
inherent
}
fn random_seed() -> <Block as BlockT>::Hash {
System::random_seed()
}
}
impl OldTxQueue<AccountId, Index, Address, AccountId> for Runtime {
fn account_nonce(account: AccountId) -> Index {
System::account_nonce(&account)
}
fn lookup_address(address: Address) -> Option<AccountId> {
Balances::lookup_address(address)
}
}
impl NewTxQueue<Block, TransactionValidity> for Runtime {
fn validate_transaction(tx: <Block as BlockT>::Extrinsic) -> TransactionValidity {
Executive::validate_transaction(tx)
}
}
impl Miscellaneous<AccountId, u64> for Runtime {
fn validator_count() -> u32 {
Session::validator_count()
}
fn validators() -> Vec<AccountId> {
Session::validators()
}
fn timestamp() -> u64 {
Timestamp::get()
}
}
}