Consensus data added with generic use in service/src/consensus.rs. Th… (#1274)

* Consensus data added with generic use in service/src/consensus.rs. This may need to change.

* refactor consensus service a bit
This commit is contained in:
Simon Littlejohns
2018-12-17 17:51:40 +00:00
committed by Robert Habermeier
parent c1b08cd9b0
commit 1c104e0568
7 changed files with 76 additions and 17 deletions
+1
View File
@@ -3646,6 +3646,7 @@ dependencies = [
"sr-primitives 0.1.0",
"substrate-client 0.1.0",
"substrate-client-db 0.1.0",
"substrate-consensus-aura-primitives 0.1.0",
"substrate-consensus-common 0.1.0",
"substrate-executor 0.1.0",
"substrate-keystore 0.1.0",
@@ -33,6 +33,16 @@ pub mod id {
pub const AURA_API: ApiId = *b"aura_api";
}
/// Aura consensus environmental data. Useful for block-proposing code.
pub struct AuraConsensusData {
/// The timestamp the block should be authored with.
pub timestamp: u64,
/// The slot number.
pub slot: u64,
/// The duration of the slot, in seconds.
pub slot_duration: u64,
}
/// Runtime-APIs
pub mod api {
use client::decl_runtime_apis;
+15 -8
View File
@@ -72,6 +72,7 @@ use futures::{Stream, Future, IntoFuture, future::{self, Either}};
use tokio::timer::{Delay, Timeout};
use api::AuraApi;
pub use aura_primitives::AuraConsensusData;
pub use consensus_common::SyncOracle;
/// A handle to the network. This is generally implemented by providing some
@@ -159,8 +160,8 @@ pub fn start_aura_thread<B, C, E, I, SO, Error>(
) where
B: Block + 'static,
C: Authorities<B> + ChainHead<B> + Send + Sync + 'static,
E: Environment<B, Error=Error> + Send + Sync + 'static,
E::Proposer: Proposer<B, Error=Error> + 'static,
E: Environment<B, AuraConsensusData, Error=Error> + Send + Sync + 'static,
E::Proposer: Proposer<B, AuraConsensusData, Error=Error> + 'static,
I: BlockImport<B> + Send + Sync + 'static,
Error: From<C::Error> + From<I::Error> + 'static,
SO: SyncOracle + Send + Clone + 'static,
@@ -202,8 +203,8 @@ pub fn start_aura<B, C, E, I, SO, Error>(
) -> impl Future<Item=(),Error=()> where
B: Block,
C: Authorities<B> + ChainHead<B>,
E: Environment<B, Error=Error>,
E::Proposer: Proposer<B, Error=Error>,
E: Environment<B, AuraConsensusData, Error=Error>,
E::Proposer: Proposer<B, AuraConsensusData, Error=Error>,
I: BlockImport<B>,
Error: From<C::Error> + From<I::Error>,
SO: SyncOracle + Send + Clone,
@@ -287,10 +288,16 @@ pub fn start_aura<B, C, E, I, SO, Error>(
}
};
let consensus_data = AuraConsensusData {
timestamp,
slot: slot_num,
slot_duration,
};
// deadline our production to approx. the end of the
// slot
Timeout::new(
proposer.propose().into_future(),
proposer.propose(consensus_data).into_future(),
time_until_next(Duration::from_secs(timestamp), slot_duration),
)
} else {
@@ -634,7 +641,7 @@ mod tests {
struct DummyFactory(Arc<TestClient>);
struct DummyProposer(u64, Arc<TestClient>);
impl Environment<TestBlock> for DummyFactory {
impl Environment<TestBlock, AuraConsensusData> for DummyFactory {
type Proposer = DummyProposer;
type Error = Error;
@@ -645,11 +652,11 @@ mod tests {
}
}
impl Proposer<TestBlock> for DummyProposer {
impl Proposer<TestBlock, AuraConsensusData> for DummyProposer {
type Error = Error;
type Create = Result<TestBlock, Error>;
fn propose(&self) -> Result<TestBlock, Error> {
fn propose(&self, _consensus_data: AuraConsensusData) -> Result<TestBlock, Error> {
self.1.new_block().unwrap().bake().map_err(|e| e.into())
}
}
+6 -4
View File
@@ -59,9 +59,9 @@ pub trait Authorities<B: Block> {
}
/// Environment producer for a Consensus instance. Creates proposer instance and communication streams.
pub trait Environment<B: Block> {
pub trait Environment<B: Block, ConsensusData> {
/// The proposer type this creates.
type Proposer: Proposer<B>;
type Proposer: Proposer<B, ConsensusData>;
/// Error which can occur upon creation.
type Error: From<Error>;
@@ -76,13 +76,15 @@ pub trait Environment<B: Block> {
///
/// This will encapsulate creation and evaluation of proposals at a specific
/// block.
pub trait Proposer<B: Block> {
///
/// Proposers are generic over bits of "consensus data" which are engine-specific.
pub trait Proposer<B: Block, ConsensusData> {
/// Error type which can occur when proposing or evaluating.
type Error: From<Error> + ::std::fmt::Debug + 'static;
/// Future that resolves to a committed proposal.
type Create: IntoFuture<Item=B,Error=Self::Error>;
/// Create a proposal.
fn propose(&self) -> Self::Create;
fn propose(&self, consensus_data: ConsensusData) -> Self::Create;
}
/// An oracle for when major synchronization work is being undertaken.
+1
View File
@@ -21,6 +21,7 @@ sr-io = { path = "../../core/sr-io" }
sr-primitives = { path = "../../core/sr-primitives" }
substrate-primitives = { path = "../../core/primitives" }
substrate-consensus-common = { path = "../../core/consensus/common" }
substrate-consensus-aura-primitives = { path = "../../core/consensus/aura/primitives" }
substrate-network = { path = "../../core/network" }
substrate-client = { path = "../../core/client" }
substrate-client-db = { path = "../../core/client/db" }
+42 -5
View File
@@ -31,6 +31,7 @@ use runtime_primitives::traits::{Block as BlockT, Hash as HashT, Header as Heade
use runtime_primitives::generic::BlockId;
use runtime_primitives::BasicInherentData;
use transaction_pool::txpool::{self, Pool as TransactionPool};
use aura_primitives::AuraConsensusData;
type Timestamp = u64;
@@ -111,11 +112,12 @@ pub struct ProposerFactory<C, A> where A: txpool::ChainApi {
pub transaction_pool: Arc<TransactionPool<A>>,
}
impl<C, A> consensus_common::Environment<<C as AuthoringApi>::Block> for ProposerFactory<C, A> where
impl<C, A, ConsensusData> consensus_common::Environment<<C as AuthoringApi>::Block, ConsensusData> for ProposerFactory<C, A> where
C: AuthoringApi,
<C as ProvideRuntimeApi>::Api: BlockBuilderApi<<C as AuthoringApi>::Block, BasicInherentData>,
A: txpool::ChainApi<Block=<C as AuthoringApi>::Block>,
client::error::Error: From<<C as AuthoringApi>::Error>
client::error::Error: From<<C as AuthoringApi>::Error>,
Proposer<<C as AuthoringApi>::Block, C, A>: consensus_common::Proposer<<C as AuthoringApi>::Block, ConsensusData>,
{
type Proposer = Proposer<<C as AuthoringApi>::Block, C, A>;
type Error = error::Error;
@@ -144,6 +146,10 @@ impl<C, A> consensus_common::Environment<<C as AuthoringApi>::Block> for Propose
}
}
struct ConsensusData {
timestamp: Option<u64>,
}
/// The proposer logic.
pub struct Proposer<Block: BlockT, C, A: txpool::ChainApi> {
client: Arc<C>,
@@ -153,7 +159,7 @@ pub struct Proposer<Block: BlockT, C, A: txpool::ChainApi> {
transaction_pool: Arc<TransactionPool<A>>,
}
impl<Block, C, A> consensus_common::Proposer<<C as AuthoringApi>::Block> for Proposer<Block, C, A> where
impl<Block, C, A> consensus_common::Proposer<<C as AuthoringApi>::Block, AuraConsensusData> for Proposer<Block, C, A> where
Block: BlockT,
C: AuthoringApi<Block=Block>,
<C as ProvideRuntimeApi>::Api: BlockBuilderApi<Block, BasicInherentData>,
@@ -163,10 +169,41 @@ impl<Block, C, A> consensus_common::Proposer<<C as AuthoringApi>::Block> for Pro
type Create = Result<<C as AuthoringApi>::Block, error::Error>;
type Error = error::Error;
fn propose(&self) -> Result<<C as AuthoringApi>::Block, error::Error> {
fn propose(&self, consensus_data: AuraConsensusData)
-> Result<<C as AuthoringApi>::Block, error::Error>
{
self.propose_with(ConsensusData { timestamp: Some(consensus_data.timestamp) })
}
}
impl<Block, C, A> consensus_common::Proposer<<C as AuthoringApi>::Block, ()> for Proposer<Block, C, A> where
Block: BlockT,
C: AuthoringApi<Block=Block>,
<C as ProvideRuntimeApi>::Api: BlockBuilderApi<Block, BasicInherentData>,
A: txpool::ChainApi<Block=Block>,
client::error::Error: From<<C as AuthoringApi>::Error>
{
type Create = Result<<C as AuthoringApi>::Block, error::Error>;
type Error = error::Error;
fn propose(&self, _consensus_data: ()) -> Result<<C as AuthoringApi>::Block, error::Error> {
self.propose_with(ConsensusData { timestamp: None })
}
}
impl<Block, C, A> Proposer<Block, C, A> where
Block: BlockT,
C: AuthoringApi<Block=Block>,
<C as ProvideRuntimeApi>::Api: BlockBuilderApi<Block, BasicInherentData>,
A: txpool::ChainApi<Block=Block>,
client::error::Error: From<<C as AuthoringApi>::Error>,
{
fn propose_with(&self, consensus_data: ConsensusData)
-> Result<<C as AuthoringApi>::Block, error::Error>
{
use runtime_primitives::traits::BlakeTwo256;
let timestamp = current_timestamp();
let timestamp = consensus_data.timestamp.unwrap_or_else(current_timestamp);
let inherent_data = BasicInherentData::new(timestamp, 0);
let block = self.client.build_block(
+1
View File
@@ -34,6 +34,7 @@ extern crate substrate_client as client;
extern crate substrate_client_db as client_db;
extern crate parity_codec as codec;
extern crate substrate_transaction_pool as transaction_pool;
extern crate substrate_consensus_aura_primitives as aura_primitives;
extern crate substrate_rpc_servers as rpc;
extern crate target_info;
extern crate tokio;