Runtime API clean up (#892)

* Rename `NewTxQueue` to `TaggedTransactionQueue`

* Remove `BlockBuilder` API and support adding documentation to the API functions

* Adds new `BlockBuilder` API

* Fixes compilation with new `BlockBuilder` API

* Some more cleanup

* Cargo.lock update

* Try to fix on stable
This commit is contained in:
Bastian Köcher
2018-10-09 14:01:23 +02:00
committed by GitHub
parent 2c65ad6c7b
commit 6b4b8b8f8e
9 changed files with 240 additions and 170 deletions
+43 -42
View File
@@ -46,7 +46,7 @@ use std::sync::Arc;
use std::time::{self, Duration, Instant};
use client::{Client as SubstrateClient, CallExecutor};
use client::runtime_api::{BlockBuilder as BlockBuilderAPI, Core, Miscellaneous, OldTxQueue};
use client::runtime_api::{Core, BlockBuilder as BlockBuilderAPI, Miscellaneous, OldTxQueue};
use codec::{Decode, Encode};
use node_primitives::{AccountId, Timestamp, SessionKey, InherentData};
use node_runtime::Runtime;
@@ -81,9 +81,6 @@ const MAX_TRANSACTIONS_SIZE: usize = 4 * 1024 * 1024;
pub trait BlockBuilder<Block: BlockT> {
/// Push an extrinsic onto the block. Fails if the extrinsic is invalid.
fn push_extrinsic(&mut self, extrinsic: <Block as BlockT>::Extrinsic) -> Result<()>;
/// Bake the block with provided extrinsics.
fn bake(self) -> Result<Block>;
}
/// Local client abstraction for the consensus.
@@ -97,16 +94,19 @@ pub trait AuthoringApi:
{
/// The block used for this API type.
type Block: BlockT;
/// The block builder for this API type.
type BlockBuilder: BlockBuilder<Self::Block>;
/// The error used by this API type.
type Error;
/// Build a block on top of the given, with inherent extrinsics pre-pushed.
fn build_block(&self, at: &BlockId<Self::Block>, inherent_data: InherentData) -> Result<Self::BlockBuilder>;
fn build_block<F: FnMut(&mut BlockBuilder<Self::Block>) -> ()>(
&self,
at: &BlockId<Self::Block>,
inherent_data: InherentData,
build_ctx: F,
) -> Result<Self::Block>;
}
impl<B, E, Block> BlockBuilder<Block> for client::block_builder::BlockBuilder<B, E, Block, Blake2Hasher> where
impl<'a, B, E, Block> BlockBuilder<Block> for client::block_builder::BlockBuilder<'a, B, E, Block, Blake2Hasher> where
B: client::backend::Backend<Block, Blake2Hasher> + Send + Sync + 'static,
E: CallExecutor<Block, Blake2Hasher> + Send + Sync + Clone + 'static,
Block: BlockT
@@ -114,32 +114,34 @@ impl<B, E, Block> BlockBuilder<Block> for client::block_builder::BlockBuilder<B,
fn push_extrinsic(&mut self, extrinsic: <Block as BlockT>::Extrinsic) -> Result<()> {
client::block_builder::BlockBuilder::push(self, extrinsic).map_err(Into::into)
}
fn bake(self) -> Result<Block> {
client::block_builder::BlockBuilder::bake(self).map_err(Into::into)
}
}
impl<B, E, Block> AuthoringApi for SubstrateClient<B, E, Block> where
impl<'a, B, E, Block> AuthoringApi for SubstrateClient<B, E, Block> where
B: client::backend::Backend<Block, Blake2Hasher> + Send + Sync + 'static,
E: CallExecutor<Block, Blake2Hasher> + Send + Sync + Clone + 'static,
Block: BlockT,
{
type Block = Block;
type BlockBuilder = client::block_builder::BlockBuilder<B, E, Block, Blake2Hasher>;
type Error = client::error::Error;
fn build_block(&self, at: &BlockId<Block>, inherent_data: InherentData) -> Result<Self::BlockBuilder> {
fn build_block<F: FnMut(&mut BlockBuilder<Self::Block>) -> ()>(
&self,
at: &BlockId<Self::Block>,
inherent_data: InherentData,
mut build_ctx: F,
) -> Result<Self::Block> {
let runtime_version = self.runtime_version_at(at)?;
let mut block_builder = self.new_block_at(at)?;
if runtime_version.has_api(*b"inherent", 1) {
for inherent in self.inherent_extrinsics(at, inherent_data)? {
for inherent in self.inherent_extrinsics(at, &inherent_data)? {
block_builder.push(inherent)?;
}
}
Ok(block_builder)
build_ctx(&mut block_builder);
block_builder.bake().map_err(Into::into)
}
}
@@ -300,34 +302,33 @@ impl<C> bft::Proposer<<C as AuthoringApi>::Block> for Proposer<C> where
offline_indices,
};
let mut block_builder = self.client.build_block(&self.parent_id, inherent_data)?;
let block = self.client.build_block(
&self.parent_id,
inherent_data,
|block_builder| {
let mut unqueue_invalid = Vec::new();
let result = self.transaction_pool.cull_and_get_pending(&BlockId::hash(self.parent_hash), |pending_iterator| {
let mut pending_size = 0;
for pending in pending_iterator {
if pending_size + pending.verified.encoded_size() >= MAX_TRANSACTIONS_SIZE { break }
{
let mut unqueue_invalid = Vec::new();
let result = self.transaction_pool.cull_and_get_pending(&BlockId::hash(self.parent_hash), |pending_iterator| {
let mut pending_size = 0;
for pending in pending_iterator {
if pending_size + pending.verified.encoded_size() >= MAX_TRANSACTIONS_SIZE { break }
match block_builder.push_extrinsic(pending.original.clone()) {
Ok(()) => {
pending_size += pending.verified.encoded_size();
}
Err(e) => {
trace!(target: "transaction-pool", "Invalid transaction: {}", e);
unqueue_invalid.push(pending.verified.hash().clone());
match block_builder.push_extrinsic(pending.original.clone()) {
Ok(()) => {
pending_size += pending.verified.encoded_size();
}
Err(e) => {
trace!(target: "transaction-pool", "Invalid transaction: {}", e);
unqueue_invalid.push(pending.verified.hash().clone());
}
}
}
});
if let Err(e) = result {
warn!("Unable to get the pending set: {:?}", e);
}
});
if let Err(e) = result {
warn!("Unable to get the pending set: {:?}", e);
}
self.transaction_pool.remove(&unqueue_invalid, false);
}
let block = block_builder.bake()?;
self.transaction_pool.remove(&unqueue_invalid, false);
})?;
info!("Proposing block [number: {}; hash: {}; parent_hash: {}; extrinsics: [{}]]",
block.header().number(),
@@ -404,7 +405,7 @@ impl<C> bft::Proposer<<C as AuthoringApi>::Block> for Proposer<C> where
// evaluate whether the block is actually valid.
// TODO: is it better to delay this until the delays are finished?
let evaluated = match self.client.execute_block(&self.parent_id, unchecked_proposal.clone()).map_err(Error::from) {
let evaluated = match self.client.execute_block(&self.parent_id, &unchecked_proposal.clone()).map_err(Error::from) {
Ok(()) => Ok(true),
Err(err) => match err.kind() {
error::ErrorKind::Client(client::error::ErrorKind::Execution(_)) => Ok(false),
@@ -445,7 +446,7 @@ impl<C> bft::Proposer<<C as AuthoringApi>::Block> for Proposer<C> where
.filter(|tx| tx.verified.sender == local_id)
.last()
.map(|tx| Ok(tx.verified.index()))
.unwrap_or_else(|| self.client.account_nonce(&self.parent_id, local_id))
.unwrap_or_else(|| self.client.account_nonce(&self.parent_id, &local_id))
.map_err(Error::from)
);