Authorship works again (#50)

* provide through inherent-data when authoring

* remove unneeded codec round-trip in proposer

* refactor polkadot-consensus service architecture

* integrate block authorship into polkadot service

* remove unused extern substrate-network crate in service

* write wrapper for unifying errors in consensus proposer

* extend wrapper further

* switch temporarily to macro-changing branch

* runtime compiles

* implement `inherent_extrinsics` for runtime

* block authorship works

* add GRANDPA to polkadot runtime

* get everything compiling

* use substrate master branch again

* remove some unneeded params

* update WASM

* parse only extrinsics when pruning availability store

* update recent deps

* runtime almost compiles

* need to expose trait type in build : I had to put phantomdata manually.

* finish updating authorship to latest GRANDPA and Aura

* fix tests

* update wasm
This commit is contained in:
Robert Habermeier
2018-12-11 17:55:04 +01:00
committed by GitHub
parent f17258c14d
commit 19095168ce
20 changed files with 1223 additions and 926 deletions
+469 -257
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -10,6 +10,6 @@ parking_lot = "0.4"
log = "0.3"
parity-codec = "2.1"
substrate-primitives = { git = "https://github.com/paritytech/substrate" }
kvdb = { git = "https://github.com/paritytech/parity-common.git" }
kvdb-rocksdb = { git = "https://github.com/paritytech/parity-common.git" }
kvdb-memorydb = { git = "https://github.com/paritytech/parity-common.git" }
kvdb = { git = "https://github.com/paritytech/parity-common", rev="616b40150ded71f57f650067fcbc5c99d7c343e6" }
kvdb-rocksdb = { git = "https://github.com/paritytech/parity-common", rev="616b40150ded71f57f650067fcbc5c99d7c343e6" }
kvdb-memorydb = { git = "https://github.com/paritytech/parity-common", rev="616b40150ded71f57f650067fcbc5c99d7c343e6" }
+1 -1
View File
@@ -77,7 +77,7 @@ fn extrinsic_key(relay_parent: &Hash, candidate_hash: &Hash) -> Vec<u8> {
/// Handle to the availability store.
#[derive(Clone)]
pub struct Store {
inner: Arc<KeyValueDB>,
inner: Arc<dyn KeyValueDB>,
}
impl Store {
+1 -1
View File
@@ -102,7 +102,7 @@ pub fn run<I, T, W>(args: I, worker: W, version: cli::VersionInfo) -> error::Res
let (spec, mut config) = cli::parse_matches::<service::Factory, _>(load_spec, version, "parity-polkadot", &matches)?;
match cli::execute_default::<service::Factory, _,>(spec, worker, &matches)? {
match cli::execute_default::<service::Factory, _,>(spec, worker, &matches, &config)? {
cli::Action::ExecutedInternally => (),
cli::Action::RunService(worker) => {
info!("Parity ·:· Polkadot");
-1
View File
@@ -16,7 +16,6 @@ polkadot-parachain = { path = "../parachain" }
polkadot-primitives = { path = "../primitives" }
polkadot-runtime = { path = "../runtime" }
polkadot-statement-table = { path = "../statement-table" }
substrate-consensus-aura = { git = "https://github.com/paritytech/substrate" }
substrate-finality-grandpa = { git = "https://github.com/paritytech/substrate" }
substrate-consensus-common = { git = "https://github.com/paritytech/substrate" }
substrate-primitives = { git = "https://github.com/paritytech/substrate" }
@@ -0,0 +1,216 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Attestation service.
/// Attestation service. A long running service that creates and manages parachain attestation
/// instances.
///
/// This uses a handle to an underlying thread pool to dispatch heavy work
/// such as candidate verification while performing event-driven work
/// on a local event loop.
use std::thread;
use std::time::{Duration, Instant};
use std::sync::Arc;
use client::{BlockchainEvents, ChainHead, BlockBody};
use client::block_builder::api::BlockBuilder;
use client::blockchain::HeaderBackend;
use client::runtime_api::Core;
use primitives::ed25519;
use futures::prelude::*;
use polkadot_primitives::{Block, BlockId, InherentData};
use polkadot_primitives::parachain::ParachainHost;
use extrinsic_store::Store as ExtrinsicStore;
use runtime_primitives::traits::ProvideRuntimeApi;
use tokio::runtime::TaskExecutor;
use tokio::runtime::current_thread::Runtime as LocalRuntime;
use tokio::timer::Interval;
use super::{Network, Collators};
// creates a task to prune redundant entries in availability store upon block finalization
//
// NOTE: this will need to be changed to finality notification rather than
// block import notifications when the consensus switches to non-instant finality.
fn prune_unneeded_availability<P>(client: Arc<P>, extrinsic_store: ExtrinsicStore)
-> impl Future<Item=(),Error=()> + Send
where P: Send + Sync + BlockchainEvents<Block> + BlockBody<Block> + 'static
{
use codec::{Encode, Decode};
use polkadot_primitives::BlockId;
enum NotifyError {
BodyFetch(::client::error::Error),
}
impl NotifyError {
fn log(&self, hash: &::polkadot_primitives::Hash) {
match *self {
NotifyError::BodyFetch(ref err) => warn!("Failed to fetch block body for imported block {:?}: {:?}", hash, err),
}
}
}
client.finality_notification_stream()
.for_each(move |notification| {
use polkadot_runtime::{Call, ParachainsCall, UncheckedExtrinsic as RuntimeExtrinsic};
let hash = notification.hash;
let parent_hash = notification.header.parent_hash;
let extrinsics = client.block_body(&BlockId::hash(hash))
.map_err(NotifyError::BodyFetch);
let extrinsics = match extrinsics {
Ok(r) => r,
Err(e) => { e.log(&hash); return Ok(()) }
};
let candidate_hashes = match extrinsics
.iter()
.filter_map(|ex| RuntimeExtrinsic::decode(&mut ex.encode().as_slice()))
.filter_map(|ex| match ex.function {
Call::Parachains(ParachainsCall::set_heads(ref heads)) =>
Some(heads.iter().map(|c| c.candidate.hash()).collect()),
_ => None,
})
.next()
{
Some(x) => x,
None => return Ok(()),
};
if let Err(e) = extrinsic_store.candidates_finalized(parent_hash, candidate_hashes) {
warn!(target: "consensus", "Failed to prune unneeded available data: {:?}", e);
}
Ok(())
})
}
/// Parachain candidate attestation service handle.
pub(crate) struct ServiceHandle {
thread: Option<thread::JoinHandle<()>>,
exit_signal: Option<::exit_future::Signal>,
}
/// Create and start a new instance of the attestation service.
pub(crate) fn start<C, N, P>(
client: Arc<P>,
parachain_consensus: Arc<::ParachainConsensus<C, N, P>>,
thread_pool: TaskExecutor,
key: Arc<ed25519::Pair>,
extrinsic_store: ExtrinsicStore,
) -> ServiceHandle
where
C: Collators + Send + Sync + 'static,
<C::Collation as IntoFuture>::Future: Send + 'static,
P: BlockchainEvents<Block> + ChainHead<Block> + BlockBody<Block>,
P: ProvideRuntimeApi + HeaderBackend<Block> + Send + Sync + 'static,
P::Api: ParachainHost<Block> + Core<Block> + BlockBuilder<Block, InherentData>,
N: Network + Send + Sync + 'static,
N::TableRouter: Send + 'static,
{
const TIMER_DELAY: Duration = Duration::from_secs(5);
const TIMER_INTERVAL: Duration = Duration::from_secs(30);
let (signal, exit) = ::exit_future::signal();
let thread = thread::spawn(move || {
let mut runtime = LocalRuntime::new().expect("Could not create local runtime");
let notifications = {
let client = client.clone();
let consensus = parachain_consensus.clone();
let key = key.clone();
client.import_notification_stream().for_each(move |notification| {
let parent_hash = notification.hash;
if notification.is_new_best {
let res = client
.runtime_api()
.authorities(&BlockId::hash(parent_hash))
.map_err(Into::into)
.and_then(|authorities| {
consensus.get_or_instantiate(
parent_hash,
&authorities,
key.clone(),
)
});
if let Err(e) = res {
warn!("Unable to start parachain consensus on top of {:?}: {}",
parent_hash, e);
}
}
Ok(())
})
};
let prune_old_sessions = {
let client = client.clone();
let interval = Interval::new(
Instant::now() + TIMER_DELAY,
TIMER_INTERVAL,
);
interval
.for_each(move |_| match client.leaves() {
Ok(leaves) => {
parachain_consensus.retain(|h| leaves.contains(h));
Ok(())
}
Err(e) => {
warn!("Error fetching leaves from client: {:?}", e);
Ok(())
}
})
.map_err(|e| warn!("Timer error {:?}", e))
};
runtime.spawn(notifications);
thread_pool.spawn(prune_old_sessions);
let prune_available = prune_unneeded_availability(client, extrinsic_store)
.select(exit.clone())
.then(|_| Ok(()));
// spawn this on the tokio executor since it's fine on a thread pool.
thread_pool.spawn(prune_available);
if let Err(e) = runtime.block_on(exit) {
debug!("BFT event loop error {:?}", e);
}
});
ServiceHandle {
thread: Some(thread),
exit_signal: Some(signal),
}
}
impl Drop for ServiceHandle {
fn drop(&mut self) {
if let Some(signal) = self.exit_signal.take() {
signal.fire();
}
if let Some(thread) = self.thread.take() {
thread.join().expect("The service thread has panicked");
}
}
}
@@ -74,9 +74,6 @@ impl DynamicInclusion {
Some(now + until)
}
}
/// Get the start instant.
pub fn started_at(&self) -> Instant { self.start }
}
#[cfg(test)]
+72 -92
View File
@@ -45,7 +45,6 @@ extern crate substrate_client as client;
extern crate exit_future;
extern crate tokio;
extern crate substrate_consensus_common as consensus;
extern crate substrate_consensus_aura as aura;
extern crate substrate_finality_grandpa as grandpa;
extern crate substrate_transaction_pool as transaction_pool;
@@ -65,14 +64,17 @@ use std::collections::{HashMap, HashSet};
use std::sync::Arc;
use std::time::{self, Duration, Instant};
use aura::ExtraVerification;
use client::{BlockchainEvents, ChainHead, BlockBody};
use client::blockchain::HeaderBackend;
use client::block_builder::api::BlockBuilder;
use codec::{Decode, Encode};
use client::block_builder::api::BlockBuilder as BlockBuilderApi;
use client::runtime_api::Core;
use codec::Encode;
use extrinsic_store::Store as ExtrinsicStore;
use parking_lot::Mutex;
use polkadot_primitives::{Hash, Block, BlockId, BlockNumber, Header, Timestamp, SessionKey};
use polkadot_primitives::{Compact, UncheckedExtrinsic};
use polkadot_primitives::{
Hash, Block, BlockId, BlockNumber, Header, Timestamp, SessionKey, InherentData
};
use polkadot_primitives::Compact;
use polkadot_primitives::parachain::{Id as ParaId, Chain, DutyRoster, BlockData, Extrinsic as ParachainExtrinsic, CandidateReceipt, CandidateSignature};
use polkadot_primitives::parachain::{AttestedCandidate, ParachainHost, Statement as PrimitiveStatement};
use primitives::{AuthorityId, ed25519};
@@ -81,6 +83,7 @@ use tokio::runtime::TaskExecutor;
use tokio::timer::{Delay, Interval};
use transaction_pool::txpool::{Pool, ChainApi as PoolChainApi};
use attestation_service::ServiceHandle;
use futures::prelude::*;
use futures::future::{self, Either};
use collation::CollationFetch;
@@ -89,12 +92,11 @@ use dynamic_inclusion::DynamicInclusion;
pub use self::collation::{validate_collation, Collators};
pub use self::error::{ErrorKind, Error};
pub use self::shared_table::{SharedTable, StatementProducer, ProducedStatements, Statement, SignedStatement, GenericStatement};
pub use service::Service;
mod attestation_service;
mod dynamic_inclusion;
mod evaluation;
mod error;
mod service;
mod shared_table;
pub mod collation;
@@ -255,7 +257,7 @@ impl<C, N, P> ParachainConsensus<C, N, P> where
C: Collators + Send + 'static,
N: Network,
P: ProvideRuntimeApi + HeaderBackend<Block> + Send + Sync + 'static,
P::Api: ParachainHost<Block> + BlockBuilder<Block>,
P::Api: ParachainHost<Block> + BlockBuilderApi<Block, InherentData>,
<C::Collation as IntoFuture>::Future: Send + 'static,
N::TableRouter: Send + 'static,
{
@@ -271,8 +273,6 @@ impl<C, N, P> ParachainConsensus<C, N, P> where
)
-> Result<Arc<AttestationTracker>, Error>
{
use runtime_primitives::traits::{Hash as HashT, BlakeTwo256};
let mut live_instances = self.live_instances.lock();
if let Some(tracker) = live_instances.get(&parent_hash) {
return Ok(tracker.clone());
@@ -280,10 +280,6 @@ impl<C, N, P> ParachainConsensus<C, N, P> where
let id = BlockId::hash(parent_hash);
let duty_roster = self.client.runtime_api().duty_roster(&id)?;
let random_seed = self.client.runtime_api().random_seed(&id)?;
let _random_seed = BlakeTwo256::hash(random_seed.as_ref());
let _validators = self.client.runtime_api().validators(&id)?;
let (group_info, local_duty) = make_group_info(
duty_roster,
@@ -298,7 +294,6 @@ impl<C, N, P> ParachainConsensus<C, N, P> where
debug!(target: "consensus", "Active parachains: {:?}", active_parachains);
let _n_parachains = active_parachains.len();
let table = Arc::new(SharedTable::new(group_info, sign_with.clone(), parent_hash, self.extrinsic_store.clone()));
let router = self.network.communication_for(
authorities,
@@ -358,22 +353,55 @@ struct AttestationTracker {
}
/// Polkadot proposer factory.
struct ProposerFactory<C, N, P, TxApi: PoolChainApi> {
pub struct ProposerFactory<C, N, P, TxApi: PoolChainApi> {
parachain_consensus: Arc<ParachainConsensus<C, N, P>>,
transaction_pool: Arc<Pool<TxApi>>,
_service_handle: ServiceHandle,
}
impl<C, N, P, TxApi> ProposerFactory<C, N, P, TxApi> where
C: Collators + Send + Sync + 'static,
<C::Collation as IntoFuture>::Future: Send + 'static,
P: BlockchainEvents<Block> + ChainHead<Block> + BlockBody<Block>,
P: ProvideRuntimeApi + HeaderBackend<Block> + Send + Sync + 'static,
P::Api: ParachainHost<Block> + Core<Block> + BlockBuilderApi<Block, InherentData>,
N: Network + Send + Sync + 'static,
N::TableRouter: Send + 'static,
TxApi: PoolChainApi,
{
/// Create a new proposer factory.
fn new(
parachain_consensus: Arc<ParachainConsensus<C, N, P>>,
pub fn new(
client: Arc<P>,
network: N,
collators: C,
transaction_pool: Arc<Pool<TxApi>>,
thread_pool: TaskExecutor,
parachain_empty_duration: Duration,
key: Arc<ed25519::Pair>,
extrinsic_store: ExtrinsicStore,
) -> Self {
let parachain_consensus = Arc::new(ParachainConsensus {
client: client.clone(),
network,
collators,
handle: thread_pool.clone(),
extrinsic_store: extrinsic_store.clone(),
parachain_empty_duration,
live_instances: Mutex::new(HashMap::new()),
});
let service_handle = ::attestation_service::start(
client,
parachain_consensus.clone(),
thread_pool,
key,
extrinsic_store,
);
ProposerFactory {
parachain_consensus,
transaction_pool,
_service_handle: service_handle,
}
}
}
@@ -383,7 +411,7 @@ impl<C, N, P, TxApi> consensus::Environment<Block> for ProposerFactory<C, N, P,
N: Network,
TxApi: PoolChainApi<Block=Block>,
P: ProvideRuntimeApi + HeaderBackend<Block> + Send + Sync + 'static,
P::Api: ParachainHost<Block> + BlockBuilder<Block>,
P::Api: ParachainHost<Block> + BlockBuilderApi<Block, InherentData>,
<C::Collation as IntoFuture>::Future: Send + 'static,
N::TableRouter: Send + 'static,
{
@@ -495,7 +523,7 @@ pub struct Proposer<C: Send + Sync, TxApi: PoolChainApi> where
impl<C, TxApi> consensus::Proposer<Block> for Proposer<C, TxApi> where
TxApi: PoolChainApi<Block=Block>,
C: ProvideRuntimeApi + HeaderBackend<Block> + Send + Sync,
C::Api: ParachainHost<Block> + BlockBuilder<Block>,
C::Api: ParachainHost<Block> + BlockBuilderApi<Block, InherentData>,
{
type Error = Error;
type Create = Either<
@@ -533,55 +561,6 @@ impl<C, TxApi> consensus::Proposer<Block> for Proposer<C, TxApi> where
}
}
/// Does verification before importing blocks.
/// Should be used for further verification in aura.
pub struct BlockVerifier;
impl ExtraVerification<Block> for BlockVerifier {
type Verified = Either<
future::FutureResult<(), String>,
Box<dyn Future<Item=(), Error=String>>,
>;
fn verify(&self, _header: &Header, body: Option<&[UncheckedExtrinsic]>) -> Self::Verified {
use polkadot_runtime::{Call, UncheckedExtrinsic, TimestampCall};
let body = match body {
None => return Either::A(future::ok(())),
Some(body) => body,
};
// TODO: reintroduce or revisit necessaity for includability tracker.
let timestamp = current_timestamp();
let maybe_in_block = body.iter()
.filter_map(|ex| {
let encoded = ex.encode();
let runtime_ex = UncheckedExtrinsic::decode(&mut &encoded[..])?;
match runtime_ex.function {
Call::Timestamp(TimestampCall::set(t)) => Some(t),
_ => None,
}
})
.next();
let timestamp_in_block = match maybe_in_block {
None => return Either::A(future::ok(())),
Some(t) => t,
};
// we wait until the block timestamp is earlier than current.
if timestamp.0 < timestamp_in_block.0 {
let diff_secs = timestamp_in_block.0 - timestamp.0;
let delay = Delay::new(Instant::now() + Duration::from_secs(diff_secs))
.map_err(move |e| format!("Error waiting for {} seconds: {:?}", diff_secs, e));
Either::B(Box::new(delay))
} else {
Either::A(future::ok(()))
}
}
}
fn current_timestamp() -> Timestamp {
time::SystemTime::now().duration_since(time::UNIX_EPOCH)
.expect("now always later than unix epoch; qed")
@@ -605,7 +584,7 @@ impl ProposalTiming {
//
// this interval is just meant to produce periodic task wakeups
// that lead to the `dynamic_inclusion` getting updated as necessary.
if let Async::Ready(x) = self.attempt_propose.poll().map_err(ErrorKind::Timer)? {
while let Async::Ready(x) = self.attempt_propose.poll().map_err(ErrorKind::Timer)? {
x.expect("timer still alive; intervals never end; qed");
}
@@ -641,26 +620,31 @@ pub struct CreateProposal<C: Send + Sync, TxApi: PoolChainApi> {
impl<C, TxApi> CreateProposal<C, TxApi> where
TxApi: PoolChainApi<Block=Block>,
C: ProvideRuntimeApi + HeaderBackend<Block> + Send + Sync,
C::Api: ParachainHost<Block> + BlockBuilder<Block>,
C::Api: ParachainHost<Block> + BlockBuilderApi<Block, InherentData>,
{
fn propose_with(&self, candidates: Vec<AttestedCandidate>) -> Result<Block, Error> {
use client::block_builder::BlockBuilder;
use runtime_primitives::traits::{Hash as HashT, BlakeTwo256};
use polkadot_primitives::InherentData;
// TODO: handle case when current timestamp behind that in state.
let timestamp = ::std::cmp::max(self.minimum_timestamp.0, current_timestamp().0).into();
let timestamp = ::std::cmp::max(self.minimum_timestamp.0, current_timestamp().0);
let _elapsed_since_start = self.timing.dynamic_inclusion.started_at().elapsed();
let _inherent_data = InherentData {
let inherent_data = InherentData {
timestamp,
parachain_heads: candidates,
parachains: candidates,
aura_expected_slot: 0, // not required here.
};
let runtime_api = self.client.runtime_api();
let mut block_builder = BlockBuilder::at_block(&self.parent_id, &*self.client)?;
{
let inherents = runtime_api.inherent_extrinsics(&self.parent_id, &inherent_data)?;
for inherent in inherents {
block_builder.push(inherent)?;
}
let mut unqueue_invalid = Vec::new();
let mut pending_size = 0;
@@ -685,39 +669,36 @@ impl<C, TxApi> CreateProposal<C, TxApi> where
self.transaction_pool.remove_invalid(&unqueue_invalid);
}
let polkadot_block = block_builder.bake()?;
let new_block = block_builder.bake()?;
info!("Proposing block [number: {}; hash: {}; parent_hash: {}; extrinsics: [{}]]",
polkadot_block.header.number,
Hash::from(polkadot_block.header.hash()),
polkadot_block.header.parent_hash,
polkadot_block.extrinsics.iter()
new_block.header.number,
Hash::from(new_block.header.hash()),
new_block.header.parent_hash,
new_block.extrinsics.iter()
.map(|xt| format!("{}", BlakeTwo256::hash_of(xt)))
.collect::<Vec<_>>()
.join(", ")
);
let substrate_block = Decode::decode(&mut polkadot_block.encode().as_slice())
.expect("polkadot blocks defined to serialize to substrate blocks correctly; qed");
// TODO: full re-evaluation
let active_parachains = self.client.runtime_api().active_parachains(&self.parent_id)?;
let active_parachains = runtime_api.active_parachains(&self.parent_id)?;
assert!(evaluation::evaluate_initial(
&substrate_block,
timestamp,
&new_block,
timestamp.into(),
&self.parent_hash,
self.parent_number,
&active_parachains,
).is_ok());
Ok(substrate_block)
Ok(new_block)
}
}
impl<C, TxApi> Future for CreateProposal<C, TxApi> where
TxApi: PoolChainApi<Block=Block>,
C: ProvideRuntimeApi + HeaderBackend<Block> + Send + Sync,
C::Api: ParachainHost<Block> + BlockBuilder<Block>,
C::Api: ParachainHost<Block> + BlockBuilderApi<Block, InherentData>,
{
type Item = Block;
type Error = Error;
@@ -739,7 +720,6 @@ impl<C, TxApi> Future for CreateProposal<C, TxApi> where
mod tests {
use super::*;
use substrate_keyring::Keyring;
use polkadot_primitives::parachain::Statement as PStatement;
#[test]
fn sign_and_check_statement() {
-247
View File
@@ -1,247 +0,0 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Consensus service.
/// Consensus service. A long running service that manages BFT agreement and parachain
/// candidate agreement over the network.
///
/// This uses a handle to an underlying thread pool to dispatch heavy work
/// such as candidate verification while performing event-driven work
/// on a local event loop.
use std::thread;
use std::time::{Duration, Instant};
use std::sync::Arc;
use client::{BlockchainEvents, ChainHead, BlockBody};
use client::block_builder::api::BlockBuilder;
use client::blockchain::HeaderBackend;
use client::runtime_api::Core;
use primitives::ed25519;
use futures::prelude::*;
use polkadot_primitives::{Block, BlockId};
use polkadot_primitives::parachain::ParachainHost;
use extrinsic_store::Store as ExtrinsicStore;
use runtime_primitives::traits::ProvideRuntimeApi;
use transaction_pool::txpool::{ChainApi as PoolChainApi, Pool};
use tokio::runtime::TaskExecutor as ThreadPoolHandle;
use tokio::runtime::current_thread::Runtime as LocalRuntime;
use tokio::timer::Interval;
use super::{Network, Collators, ProposerFactory};
// creates a task to prune redundant entries in availability store upon block finalization
//
// NOTE: this will need to be changed to finality notification rather than
// block import notifications when the consensus switches to non-instant finality.
fn prune_unneeded_availability<C>(client: Arc<C>, extrinsic_store: ExtrinsicStore)
-> impl Future<Item=(),Error=()> + Send
where C: Send + Sync + BlockchainEvents<Block> + BlockBody<Block> + 'static
{
use codec::{Encode, Decode};
use polkadot_primitives::BlockId;
enum NotifyError {
NoBody,
BodyFetch(::client::error::Error),
UnexpectedFormat,
}
impl NotifyError {
fn log(&self, hash: &::polkadot_primitives::Hash) {
match *self {
NotifyError::NoBody => warn!("No block body for imported block {:?}", hash),
NotifyError::BodyFetch(ref err) => warn!("Failed to fetch block body for imported block {:?}: {:?}", hash, err),
NotifyError::UnexpectedFormat => warn!("Consensus outdated: Block {:?} has unexpected body format", hash),
}
}
}
client.finality_notification_stream()
.for_each(move |notification| {
use polkadot_runtime::{Call, ParachainsCall};
let hash = notification.hash;
let parent_hash = notification.header.parent_hash;
let runtime_block = client.block_body(&BlockId::hash(hash))
.map_err(NotifyError::BodyFetch)
.and_then(|maybe_body| maybe_body.ok_or(NotifyError::NoBody))
.map(|extrinsics| Block { header: notification.header, extrinsics })
.map(|b: Block| ::polkadot_runtime::Block::decode(&mut b.encode().as_slice()))
.and_then(|maybe_block| maybe_block.ok_or(NotifyError::UnexpectedFormat));
let runtime_block = match runtime_block {
Ok(r) => r,
Err(e) => { e.log(&hash); return Ok(()) }
};
let candidate_hashes = match runtime_block.extrinsics
.iter()
.filter_map(|ex| match ex.function {
Call::Parachains(ParachainsCall::set_heads(ref heads)) =>
Some(heads.iter().map(|c| c.candidate.hash()).collect()),
_ => None,
})
.next()
{
Some(x) => x,
None => return Ok(()),
};
if let Err(e) = extrinsic_store.candidates_finalized(parent_hash, candidate_hashes) {
warn!(target: "consensus", "Failed to prune unneeded available data: {:?}", e);
}
Ok(())
})
}
/// Consensus service. Starts working when created.
pub struct Service {
thread: Option<thread::JoinHandle<()>>,
exit_signal: Option<::exit_future::Signal>,
}
impl Service {
/// Create and start a new instance.
pub fn new<C, N, TxApi>(
client: Arc<C>,
network: N,
transaction_pool: Arc<Pool<TxApi>>,
thread_pool: ThreadPoolHandle,
parachain_empty_duration: Duration,
key: ed25519::Pair,
extrinsic_store: ExtrinsicStore,
) -> Service
where
C: BlockchainEvents<Block> + ChainHead<Block> + BlockBody<Block>,
C: ProvideRuntimeApi + HeaderBackend<Block> + Send + Sync + 'static,
C::Api: ParachainHost<Block> + Core<Block> + BlockBuilder<Block>,
N: Network + Collators + Send + Sync + 'static,
N::TableRouter: Send + 'static,
<N::Collation as IntoFuture>::Future: Send + 'static,
TxApi: PoolChainApi<Block=Block> + Send + 'static,
{
use parking_lot::Mutex;
use std::collections::HashMap;
const TIMER_DELAY: Duration = Duration::from_secs(5);
const TIMER_INTERVAL: Duration = Duration::from_secs(30);
let (signal, exit) = ::exit_future::signal();
let thread = thread::spawn(move || {
let mut runtime = LocalRuntime::new().expect("Could not create local runtime");
let key = Arc::new(key);
let parachain_consensus = Arc::new(::ParachainConsensus{
client: client.clone(),
network: network.clone(),
collators: network.clone(),
handle: thread_pool.clone(),
extrinsic_store: extrinsic_store.clone(),
parachain_empty_duration,
live_instances: Mutex::new(HashMap::new()),
});
let factory = ProposerFactory::new(
parachain_consensus.clone(),
transaction_pool
);
let notifications = {
let client = client.clone();
let consensus = parachain_consensus.clone();
let key = key.clone();
client.import_notification_stream().for_each(move |notification| {
let parent_hash = notification.hash;
if notification.is_new_best {
let res = client
.runtime_api()
.authorities(&BlockId::hash(parent_hash))
.map_err(Into::into)
.and_then(|authorities| {
consensus.get_or_instantiate(
parent_hash,
&authorities,
key.clone(),
)
});
if let Err(e) = res {
warn!("Unable to start parachain consensus on top of {:?}: {}",
parent_hash, e);
}
}
Ok(())
})
};
let prune_old_sessions = {
let client = client.clone();
let interval = Interval::new(
Instant::now() + TIMER_DELAY,
TIMER_INTERVAL,
);
interval
.for_each(move |_| match client.leaves() {
Ok(leaves) => {
parachain_consensus.retain(|h| leaves.contains(h));
Ok(())
}
Err(e) => {
warn!("Error fetching leaves from client: {:?}", e);
Ok(())
}
})
.map_err(|e| warn!("Timer error {:?}", e))
};
runtime.spawn(notifications);
thread_pool.spawn(prune_old_sessions);
let prune_available = prune_unneeded_availability(client, extrinsic_store)
.select(exit.clone())
.then(|_| Ok(()));
// spawn this on the tokio executor since it's fine on a thread pool.
thread_pool.spawn(prune_available);
if let Err(e) = runtime.block_on(exit) {
debug!("BFT event loop error {:?}", e);
}
});
Service {
thread: Some(thread),
exit_signal: Some(signal),
}
}
}
impl Drop for Service {
fn drop(&mut self) {
if let Some(signal) = self.exit_signal.take() {
signal.fire();
}
if let Some(thread) = self.thread.take() {
thread.join().expect("The service thread has panicked");
}
}
}
+4 -2
View File
@@ -112,7 +112,9 @@ impl Extrinsic for UncheckedExtrinsic {}
#[derive(Encode, Decode)]
pub struct InherentData {
/// Current timestamp.
pub timestamp: Timestamp,
pub timestamp: u64,
/// Parachain heads update. This contains fully-attested candidates.
pub parachain_heads: Vec<::parachain::AttestedCandidate>,
pub parachains: Vec<::parachain::AttestedCandidate>,
/// Expected slot for aura authorship.
pub aura_expected_slot: u64,
}
+4
View File
@@ -19,11 +19,14 @@ sr-io = { git = "https://github.com/paritytech/substrate" }
srml-support = { git = "https://github.com/paritytech/substrate" }
substrate-primitives = { git = "https://github.com/paritytech/substrate" }
substrate-client = { git = "https://github.com/paritytech/substrate" }
substrate-consensus-aura-primitives = { git = "https://github.com/paritytech/substrate", default-features = false }
srml-aura = { git = "https://github.com/paritytech/substrate" }
srml-balances = { git = "https://github.com/paritytech/substrate" }
srml-consensus = { git = "https://github.com/paritytech/substrate" }
srml-council = { git = "https://github.com/paritytech/substrate" }
srml-democracy = { git = "https://github.com/paritytech/substrate" }
srml-executive = { git = "https://github.com/paritytech/substrate" }
srml-grandpa = { git = "https://github.com/paritytech/substrate" }
sr-primitives = { git = "https://github.com/paritytech/substrate" }
srml-session = { git = "https://github.com/paritytech/substrate" }
srml-staking = { git = "https://github.com/paritytech/substrate" }
@@ -52,6 +55,7 @@ std = [
"srml-council/std",
"srml-democracy/std",
"srml-executive/std",
"srml-grandpa/std",
"sr-primitives/std",
"srml-session/std",
"srml-staking/std",
+110 -204
View File
@@ -27,6 +27,7 @@ extern crate bitvec;
extern crate parity_codec_derive;
extern crate parity_codec as codec;
extern crate substrate_consensus_aura_primitives as consensus_aura;
extern crate substrate_primitives;
#[macro_use]
extern crate substrate_client as client;
@@ -35,18 +36,19 @@ extern crate substrate_client as client;
extern crate sr_std as rstd;
#[cfg(test)]
extern crate sr_io;
#[macro_use]
extern crate sr_version as version;
#[macro_use]
extern crate sr_primitives;
#[macro_use]
extern crate srml_support;
extern crate srml_aura as aura;
extern crate srml_balances as balances;
extern crate srml_consensus as consensus;
extern crate srml_council as council;
extern crate srml_democracy as democracy;
extern crate srml_executive as executive;
extern crate srml_grandpa as grandpa;
extern crate srml_session as session;
extern crate srml_staking as staking;
extern crate srml_system as system;
@@ -60,28 +62,23 @@ extern crate substrate_keyring as keyring;
mod parachains;
#[cfg(feature = "std")]
use codec::{Encode, Decode};
use rstd::prelude::*;
use substrate_primitives::u32_trait::{_2, _4};
use primitives::{
AccountId, AccountIndex, Balance, BlockNumber, Hash, Index, SessionKey, Signature,
parachain, parachain::runtime::ParachainHost, parachain::id::PARACHAIN_HOST,
parachain,
};
#[cfg(feature = "std")]
use primitives::Block as GBlock;
use client::{block_builder::api::runtime::*, runtime_api::{runtime::*, id::*}};
#[cfg(feature = "std")]
use client::runtime_api::ApiExt;
use sr_primitives::ApplyResult;
use client::{
block_builder::api as block_builder_api,
runtime_api as client_api,
};
use consensus_aura::api as aura_api;
use sr_primitives::{ApplyResult, CheckInherentError};
use sr_primitives::transaction_validity::TransactionValidity;
use sr_primitives::generic;
use sr_primitives::traits::{Convert, BlakeTwo256, Block as BlockT};
#[cfg(feature = "std")]
use sr_primitives::traits::ApiRef;
#[cfg(feature = "std")]
use substrate_primitives::AuthorityId;
use sr_primitives::traits::{Convert, BlakeTwo256, Block as BlockT, DigestFor};
use version::RuntimeVersion;
use grandpa::fg_primitives::{self, ScheduledChange};
use council::{motions as council_motions, voting as council_voting};
#[cfg(feature = "std")]
use council::seats as council_seats;
@@ -100,22 +97,17 @@ pub use timestamp::BlockPeriod;
pub use srml_support::{StorageValue, RuntimeMetadata};
const TIMESTAMP_SET_POSITION: u32 = 0;
const NOTE_OFFLINE_POSITION: u32 = 1;
const PARACHAINS_SET_POSITION: u32 = 2;
const PARACHAINS_SET_POSITION: u32 = 1;
const NOTE_OFFLINE_POSITION: u32 = 2; // this should be reintroduced
/// Runtime version.
pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: ver_str!("polkadot"),
impl_name: ver_str!("parity-polkadot"),
spec_name: create_runtime_str!("polkadot"),
impl_name: create_runtime_str!("parity-polkadot"),
authoring_version: 1,
spec_version: 101,
impl_version: 0,
apis: apis_vec!([
(BLOCK_BUILDER, 1),
(TAGGED_TRANSACTION_QUEUE, 1),
(METADATA, 1),
(PARACHAIN_HOST, 1),
]),
apis: RUNTIME_API_VERSIONS,
};
/// Native version.
@@ -140,6 +132,10 @@ impl system::Trait for Runtime {
type Log = Log;
}
impl aura::Trait for Runtime {
type HandleReport = aura::StakingSlasher<Runtime>;
}
impl balances::Trait for Runtime {
type Balance = Balance;
type AccountIndex = AccountIndex;
@@ -152,12 +148,16 @@ impl consensus::Trait for Runtime {
const NOTE_OFFLINE_POSITION: u32 = NOTE_OFFLINE_POSITION;
type Log = Log;
type SessionKey = SessionKey;
type OnOfflineValidator = Staking;
// the aura module handles offline-reports internally
// rather than using an explicit report system.
type InherentOfflineReport = ();
}
impl timestamp::Trait for Runtime {
const TIMESTAMP_SET_POSITION: u32 = TIMESTAMP_SET_POSITION;
type Moment = u64;
type OnTimestampSet = Aura;
}
/// Session key conversion.
@@ -170,7 +170,7 @@ impl Convert<AccountId, SessionKey> for SessionKeyConversion {
impl session::Trait for Runtime {
type ConvertAccountIdToSessionKey = SessionKeyConversion;
type OnSessionChange = Staking;
type OnSessionChange = (Staking, grandpa::SyncedAuthorities<Runtime>);
type Event = Event;
}
@@ -204,6 +204,12 @@ impl treasury::Trait for Runtime {
type Event = Event;
}
impl grandpa::Trait for Runtime {
type SessionKey = SessionKey;
type Log = Log;
type Event = Event;
}
impl parachains::Trait for Runtime {
const SET_POSITION: u32 = PARACHAINS_SET_POSITION;
}
@@ -211,15 +217,19 @@ impl parachains::Trait for Runtime {
construct_runtime!(
pub enum Runtime with Log(InternalLog: DigestItem<Hash, SessionKey>) where
Block = Block,
UncheckedExtrinsic = UncheckedExtrinsic
NodeBlock = primitives::Block,
InherentData = primitives::InherentData
{
System: system::{default, Log(ChangesTrieRoot)},
Aura: aura::{Module},
Timestamp: timestamp::{Module, Call, Storage, Config<T>, Inherent},
Consensus: consensus::{Module, Call, Storage, Config<T>, Log(AuthoritiesChange), Inherent},
// consensus' Inherent is not provided because it assumes instant-finality blocks.
Consensus: consensus::{Module, Call, Storage, Config<T>, Log(AuthoritiesChange) },
Balances: balances,
Session: session,
Staking: staking,
Democracy: democracy,
Grandpa: grandpa::{Module, Call, Storage, Config<T>, Log(), Event<T>},
Council: council::{Module, Call, Storage, Event<T>},
CouncilVoting: council_voting,
CouncilMotions: council_motions::{Module, Call, Storage, Event<T>, Origin},
@@ -248,174 +258,8 @@ 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>;
#[cfg(feature = "std")]
pub struct ClientWithApi {
call: ::std::ptr::NonNull<client::runtime_api::CallApiAt<GBlock>>,
commit_on_success: ::std::cell::RefCell<bool>,
initialised_block: ::std::cell::RefCell<Option<GBlockId>>,
changes: ::std::cell::RefCell<client::runtime_api::OverlayedChanges>,
}
#[cfg(feature = "std")]
unsafe impl Send for ClientWithApi {}
#[cfg(feature = "std")]
unsafe impl Sync for ClientWithApi {}
#[cfg(feature = "std")]
impl ApiExt for ClientWithApi {
fn map_api_result<F: FnOnce(&Self) -> Result<R, E>, R, E>(&self, map_call: F) -> Result<R, E> {
*self.commit_on_success.borrow_mut() = false;
let res = map_call(self);
*self.commit_on_success.borrow_mut() = true;
self.commit_on_ok(&res);
res
}
}
#[cfg(feature = "std")]
impl client::runtime_api::ConstructRuntimeApi<GBlock> for ClientWithApi {
fn construct_runtime_api<'a, T: client::runtime_api::CallApiAt<GBlock>>(call: &'a T) -> ApiRef<'a, Self> {
ClientWithApi {
call: unsafe {
::std::ptr::NonNull::new_unchecked(
::std::mem::transmute(
call as &client::runtime_api::CallApiAt<GBlock>
)
)
},
commit_on_success: true.into(),
initialised_block: None.into(),
changes: Default::default(),
}.into()
}
}
#[cfg(feature = "std")]
impl ClientWithApi {
fn call_api_at<A: Encode, R: Decode>(
&self,
at: &GBlockId,
function: &'static str,
args: &A
) -> client::error::Result<R> {
let res = unsafe {
self.call.as_ref().call_api_at(
at,
function,
args.encode(),
&mut *self.changes.borrow_mut(),
&mut *self.initialised_block.borrow_mut()
).and_then(|r|
R::decode(&mut &r[..])
.ok_or_else(||
client::error::ErrorKind::CallResultDecode(function).into()
)
)
};
self.commit_on_ok(&res);
res
}
fn commit_on_ok<R, E>(&self, res: &Result<R, E>) {
if *self.commit_on_success.borrow() {
if res.is_err() {
self.changes.borrow_mut().discard_prospective();
} else {
self.changes.borrow_mut().commit_prospective();
}
}
}
}
#[cfg(feature = "std")]
type GBlockId = generic::BlockId<GBlock>;
#[cfg(feature = "std")]
impl client::runtime_api::Core<GBlock> for ClientWithApi {
fn version(&self, at: &GBlockId) -> Result<RuntimeVersion, client::error::Error> {
self.call_api_at(at, "version", &())
}
fn authorities(&self, at: &GBlockId) -> Result<Vec<AuthorityId>, client::error::Error> {
self.call_api_at(at, "authorities", &())
}
fn execute_block(&self, at: &GBlockId, block: &GBlock) -> Result<(), client::error::Error> {
self.call_api_at(at, "execute_block", block)
}
fn initialise_block(&self, at: &GBlockId, header: &<GBlock as BlockT>::Header) -> Result<(), client::error::Error> {
self.call_api_at(at, "initialise_block", header)
}
}
#[cfg(feature = "std")]
impl client::block_builder::api::BlockBuilder<GBlock> for ClientWithApi {
fn apply_extrinsic(&self, at: &GBlockId, extrinsic: &<GBlock as BlockT>::Extrinsic) -> Result<ApplyResult, client::error::Error> {
self.call_api_at(at, "apply_extrinsic", extrinsic)
}
fn finalise_block(&self, at: &GBlockId) -> Result<<GBlock as BlockT>::Header, client::error::Error> {
self.call_api_at(at, "finalise_block", &())
}
fn inherent_extrinsics<Inherent: Decode + Encode, Unchecked: Decode + Encode>(
&self, at: &GBlockId, inherent: &Inherent
) -> Result<Vec<Unchecked>, client::error::Error> {
self.call_api_at(at, "inherent_extrinsics", inherent)
}
fn check_inherents<Inherent: Decode + Encode, Error: Decode + Encode>(&self, at: &GBlockId, block: &GBlock, inherent: &Inherent) -> Result<Result<(), Error>, client::error::Error> {
self.call_api_at(at, "check_inherents", &(block, inherent))
}
fn random_seed(&self, at: &GBlockId) -> Result<<GBlock as BlockT>::Hash, client::error::Error> {
self.call_api_at(at, "random_seed", &())
}
}
#[cfg(feature = "std")]
impl client::runtime_api::TaggedTransactionQueue<GBlock> for ClientWithApi {
fn validate_transaction(
&self,
at: &GBlockId,
utx: &<GBlock as BlockT>::Extrinsic
) -> Result<TransactionValidity, client::error::Error> {
self.call_api_at(at, "validate_transaction", utx)
}
}
#[cfg(feature = "std")]
impl client::runtime_api::Metadata<GBlock> for ClientWithApi {
fn metadata(&self, at: &GBlockId) -> Result<OpaqueMetadata, client::error::Error> {
self.call_api_at(at, "metadata", &())
}
}
#[cfg(feature = "std")]
impl ::primitives::parachain::ParachainHost<GBlock> for ClientWithApi {
fn validators(&self, at: &GBlockId) -> Result<Vec<primitives::AccountId>, client::error::Error> {
self.call_api_at(at, "validators", &())
}
fn duty_roster(&self, at: &GBlockId) -> Result<primitives::parachain::DutyRoster, client::error::Error> {
self.call_api_at(at, "calculate_duty_roster", &())
}
fn active_parachains(&self, at: &GBlockId) -> Result<Vec<parachain::Id>, client::error::Error> {
self.call_api_at(at, "active_parachains", &())
}
fn parachain_head(&self, at: &GBlockId, id: &parachain::Id) -> Result<Option<Vec<u8>>, client::error::Error> {
self.call_api_at(at, "parachain_head", &id)
}
fn parachain_code(&self, at: &GBlockId, id: &parachain::Id) -> Result<Option<Vec<u8>>, client::error::Error> {
self.call_api_at(at, "parachain_code", &id)
}
}
impl_runtime_apis! {
impl Core<Block> for Runtime {
impl client_api::Core<Block> for Runtime {
fn version() -> RuntimeVersion {
VERSION
}
@@ -433,13 +277,13 @@ impl_runtime_apis! {
}
}
impl Metadata for Runtime {
impl client_api::Metadata<Block> for Runtime {
fn metadata() -> OpaqueMetadata {
Runtime::metadata().into()
}
}
impl BlockBuilder<Block, InherentData, UncheckedExtrinsic, InherentData, InherentError> for Runtime {
impl block_builder_api::BlockBuilder<Block, primitives::InherentData> for Runtime {
fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyResult {
Executive::apply_extrinsic(extrinsic)
}
@@ -448,12 +292,48 @@ impl_runtime_apis! {
Executive::finalise_block()
}
fn inherent_extrinsics(data: InherentData) -> Vec<UncheckedExtrinsic> {
data.create_inherent_extrinsics()
fn inherent_extrinsics(data: primitives::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
use sr_primitives::traits::ProvideInherent;
let mut inherent = Vec::new();
inherent.extend(
Timestamp::create_inherent_extrinsics(data.timestamp)
.into_iter()
.map(|v| (v.0, UncheckedExtrinsic::new_unsigned(Call::Timestamp(v.1))))
);
inherent.extend(
Parachains::create_inherent_extrinsics(data.parachains)
.into_iter()
.map(|v| (v.0, UncheckedExtrinsic::new_unsigned(Call::Parachains(v.1))))
);
inherent.as_mut_slice().sort_unstable_by_key(|v| v.0);
inherent.into_iter().map(|v| v.1).collect()
}
fn check_inherents(block: Block, data: InherentData) -> Result<(), InherentError> {
data.check_inherents(block)
fn check_inherents(block: Block, data: primitives::InherentData) -> Result<(), CheckInherentError> {
let expected_slot = data.aura_expected_slot;
// draw timestamp out from extrinsics.
let set_timestamp = block.extrinsics()
.get(TIMESTAMP_SET_POSITION as usize)
.and_then(|xt: &UncheckedExtrinsic| match xt.function {
Call::Timestamp(TimestampCall::set(ref t)) => Some(t.clone()),
_ => None,
})
.ok_or_else(|| CheckInherentError::Other("No valid timestamp in block.".into()))?;
// take the "worse" result of normal verification and the timestamp vs. seal
// check.
CheckInherentError::combine_results(
Runtime::check_inherents(block, data),
|| {
Aura::verify_inherent(set_timestamp.into(), expected_slot)
.map_err(|s| CheckInherentError::Other(s.into()))
},
)
}
fn random_seed() -> <Block as BlockT>::Hash {
@@ -461,13 +341,13 @@ impl_runtime_apis! {
}
}
impl TaggedTransactionQueue<Block> for Runtime {
impl client_api::TaggedTransactionQueue<Block> for Runtime {
fn validate_transaction(tx: <Block as BlockT>::Extrinsic) -> TransactionValidity {
Executive::validate_transaction(tx)
}
}
impl ParachainHost for Runtime {
impl parachain::ParachainHost<Block> for Runtime {
fn validators() -> Vec<AccountId> {
Session::validators()
}
@@ -484,5 +364,31 @@ impl_runtime_apis! {
Parachains::parachain_code(&id)
}
}
impl fg_primitives::GrandpaApi<Block> for Runtime {
fn grandpa_pending_change(digest: DigestFor<Block>)
-> Option<ScheduledChange<BlockNumber>>
{
for log in digest.logs.iter().filter_map(|l| match l {
Log(InternalLog::grandpa(grandpa_signal)) => Some(grandpa_signal),
_=> None
}) {
if let Some(change) = Grandpa::scrape_digest_change(log) {
return Some(change);
}
}
None
}
fn grandpa_authorities() -> Vec<(SessionKey, u64)> {
Grandpa::grandpa_authorities()
}
}
impl aura_api::AuraApi<Block> for Runtime {
fn slot_duration() -> u64 {
Aura::slot_duration()
}
}
}
+19 -13
View File
@@ -20,9 +20,10 @@ use rstd::prelude::*;
use codec::Decode;
use bitvec::BigEndian;
use sr_primitives::{RuntimeString, traits::{
use sr_primitives::CheckInherentError;
use sr_primitives::traits::{
Extrinsic, Block as BlockT, Hash as HashT, BlakeTwo256, ProvideInherent,
}};
};
use primitives::parachain::{Id, Chain, DutyRoster, AttestedCandidate, Statement};
use {system, session};
@@ -32,6 +33,9 @@ use srml_support::dispatch::Result;
#[cfg(any(feature = "std", test))]
use sr_primitives::{self, ChildrenStorageMap};
#[cfg(any(feature = "std", test))]
use rstd::marker::PhantomData;
use system::ensure_inherent;
pub trait Trait: session::Trait {
@@ -53,6 +57,7 @@ decl_storage! {
}
add_extra_genesis {
config(parachains): Vec<(Id, Vec<u8>, Vec<u8>)>;
config(_phdata): PhantomData<T>;
build(|storage: &mut sr_primitives::StorageMap, _: &mut ChildrenStorageMap, config: &GenesisConfig<T>| {
use codec::Encode;
@@ -62,11 +67,11 @@ decl_storage! {
let only_ids: Vec<_> = p.iter().map(|&(ref id, _, _)| id).cloned().collect();
storage.insert(GenesisConfig::<T>::hash(<Parachains<T>>::key()).to_vec(), only_ids.encode());
storage.insert(Self::hash(<Parachains<T>>::key()).to_vec(), only_ids.encode());
for (id, code, genesis) in p {
let code_key = GenesisConfig::<T>::hash(&<Code<T>>::key_for(&id)).to_vec();
let head_key = GenesisConfig::<T>::hash(&<Heads<T>>::key_for(&id)).to_vec();
let code_key = Self::hash(&<Code<T>>::key_for(&id)).to_vec();
let head_key = Self::hash(&<Heads<T>>::key_for(&id)).to_vec();
storage.insert(code_key, code.encode());
storage.insert(head_key, genesis.encode());
@@ -418,7 +423,6 @@ impl<T: Trait> Module<T> {
impl<T: Trait> ProvideInherent for Module<T> {
type Inherent = Vec<AttestedCandidate>;
type Call = Call<T>;
type Error = RuntimeString;
fn create_inherent_extrinsics(data: Self::Inherent) -> Vec<(u32, Self::Call)> {
vec![(T::SET_POSITION, Call::set_heads(data))]
@@ -426,7 +430,7 @@ impl<T: Trait> ProvideInherent for Module<T> {
fn check_inherent<Block: BlockT, F: Fn(&Block::Extrinsic) -> Option<&Self::Call>>(
block: &Block, _data: Self::Inherent, extract_function: &F
) -> ::rstd::result::Result<(), Self::Error> {
) -> ::rstd::result::Result<(), CheckInherentError> {
let has_heads = block
.extrinsics()
.get(T::SET_POSITION as usize)
@@ -437,7 +441,11 @@ impl<T: Trait> ProvideInherent for Module<T> {
}
});
if !has_heads { return Err("No valid parachains inherent in block".into()) }
if !has_heads {
return Err(CheckInherentError::Other(
"No valid parachains inherent in block".into()
));
}
Ok(())
}
@@ -446,7 +454,6 @@ impl<T: Trait> ProvideInherent for Module<T> {
#[cfg(test)]
mod tests {
use super::*;
use rstd::marker::PhantomData;
use sr_io::{TestExternalities, with_externalities};
use substrate_primitives::{H256, Blake2Hasher};
use sr_primitives::{generic, BuildStorage};
@@ -464,7 +471,7 @@ mod tests {
impl consensus::Trait for Test {
const NOTE_OFFLINE_POSITION: u32 = 1;
type SessionKey = SessionKey;
type OnOfflineValidator = ();
type InherentOfflineReport = ();
type Log = ::Log;
}
impl system::Trait for Test {
@@ -487,6 +494,7 @@ mod tests {
impl timestamp::Trait for Test {
const TIMESTAMP_SET_POSITION: u32 = 0;
type Moment = u64;
type OnTimestampSet = ();
}
impl Trait for Test {
const SET_POSITION: u32 = 0;
@@ -510,16 +518,14 @@ mod tests {
t.extend(consensus::GenesisConfig::<Test>{
code: vec![],
authorities: authority_keys.iter().map(|k| k.to_raw_public().into()).collect(),
_genesis_phantom_data: PhantomData,
}.build_storage().unwrap().0);
t.extend(session::GenesisConfig::<Test>{
session_length: 1000,
validators: authority_keys.iter().map(|k| k.to_raw_public().into()).collect(),
_genesis_phantom_data: PhantomData,
}.build_storage().unwrap().0);
t.extend(GenesisConfig::<Test>{
parachains: parachains,
_genesis_phantom_data: PhantomData,
_phdata: Default::default(),
}.build_storage().unwrap().0);
t.into()
}
+174 -25
View File
@@ -11,11 +11,25 @@ name = "bitvec"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "blake2-rfc"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "byteorder"
version = "1.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "constant_time_eq"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "crunchy"
version = "0.1.6"
@@ -89,7 +103,7 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -115,7 +129,7 @@ name = "parity-codec-derive"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -148,11 +162,13 @@ dependencies = [
"sr-primitives 0.1.0 (git+https://github.com/paritytech/substrate)",
"sr-std 0.1.0 (git+https://github.com/paritytech/substrate)",
"sr-version 0.1.0 (git+https://github.com/paritytech/substrate)",
"srml-aura 0.1.0 (git+https://github.com/paritytech/substrate)",
"srml-balances 0.1.0 (git+https://github.com/paritytech/substrate)",
"srml-consensus 0.1.0 (git+https://github.com/paritytech/substrate)",
"srml-council 0.1.0 (git+https://github.com/paritytech/substrate)",
"srml-democracy 0.1.0 (git+https://github.com/paritytech/substrate)",
"srml-executive 0.1.0 (git+https://github.com/paritytech/substrate)",
"srml-grandpa 0.1.0 (git+https://github.com/paritytech/substrate)",
"srml-session 0.1.0 (git+https://github.com/paritytech/substrate)",
"srml-staking 0.1.0 (git+https://github.com/paritytech/substrate)",
"srml-support 0.1.0 (git+https://github.com/paritytech/substrate)",
@@ -160,6 +176,7 @@ dependencies = [
"srml-timestamp 0.1.0 (git+https://github.com/paritytech/substrate)",
"srml-treasury 0.1.0 (git+https://github.com/paritytech/substrate)",
"substrate-client 0.1.0 (git+https://github.com/paritytech/substrate)",
"substrate-consensus-aura-primitives 0.1.0 (git+https://github.com/paritytech/substrate)",
"substrate-primitives 0.1.0 (git+https://github.com/paritytech/substrate)",
]
@@ -178,7 +195,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "proc-macro2"
version = "0.4.23"
version = "0.4.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -189,7 +206,7 @@ name = "quote"
version = "0.6.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -231,10 +248,21 @@ name = "serde"
version = "1.0.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "sr-api-macros"
version = "0.1.0"
source = "git+https://github.com/paritytech/substrate#3329915cd5458bd065c9f921891487e71511097c"
dependencies = [
"blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "sr-io"
version = "0.1.0"
source = "git+https://github.com/paritytech/substrate#c10123e41c2f4bfa7aa82f65c229920111c66d19"
source = "git+https://github.com/paritytech/substrate#3329915cd5458bd065c9f921891487e71511097c"
dependencies = [
"hash-db 0.9.0 (git+https://github.com/paritytech/trie)",
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -246,7 +274,7 @@ dependencies = [
[[package]]
name = "sr-primitives"
version = "0.1.0"
source = "git+https://github.com/paritytech/substrate#c10123e41c2f4bfa7aa82f65c229920111c66d19"
source = "git+https://github.com/paritytech/substrate#3329915cd5458bd065c9f921891487e71511097c"
dependencies = [
"integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -260,7 +288,7 @@ dependencies = [
[[package]]
name = "sr-std"
version = "0.1.0"
source = "git+https://github.com/paritytech/substrate#c10123e41c2f4bfa7aa82f65c229920111c66d19"
source = "git+https://github.com/paritytech/substrate#3329915cd5458bd065c9f921891487e71511097c"
dependencies = [
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -268,7 +296,7 @@ dependencies = [
[[package]]
name = "sr-version"
version = "0.1.0"
source = "git+https://github.com/paritytech/substrate#c10123e41c2f4bfa7aa82f65c229920111c66d19"
source = "git+https://github.com/paritytech/substrate#3329915cd5458bd065c9f921891487e71511097c"
dependencies = [
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -277,10 +305,30 @@ dependencies = [
"sr-std 0.1.0 (git+https://github.com/paritytech/substrate)",
]
[[package]]
name = "srml-aura"
version = "0.1.0"
source = "git+https://github.com/paritytech/substrate#3329915cd5458bd065c9f921891487e71511097c"
dependencies = [
"hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 0.1.0 (git+https://github.com/paritytech/substrate)",
"sr-primitives 0.1.0 (git+https://github.com/paritytech/substrate)",
"sr-std 0.1.0 (git+https://github.com/paritytech/substrate)",
"srml-consensus 0.1.0 (git+https://github.com/paritytech/substrate)",
"srml-staking 0.1.0 (git+https://github.com/paritytech/substrate)",
"srml-support 0.1.0 (git+https://github.com/paritytech/substrate)",
"srml-system 0.1.0 (git+https://github.com/paritytech/substrate)",
"srml-timestamp 0.1.0 (git+https://github.com/paritytech/substrate)",
"substrate-primitives 0.1.0 (git+https://github.com/paritytech/substrate)",
]
[[package]]
name = "srml-balances"
version = "0.1.0"
source = "git+https://github.com/paritytech/substrate#c10123e41c2f4bfa7aa82f65c229920111c66d19"
source = "git+https://github.com/paritytech/substrate#3329915cd5458bd065c9f921891487e71511097c"
dependencies = [
"hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -298,7 +346,7 @@ dependencies = [
[[package]]
name = "srml-consensus"
version = "0.1.0"
source = "git+https://github.com/paritytech/substrate#c10123e41c2f4bfa7aa82f65c229920111c66d19"
source = "git+https://github.com/paritytech/substrate#3329915cd5458bd065c9f921891487e71511097c"
dependencies = [
"hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -315,7 +363,7 @@ dependencies = [
[[package]]
name = "srml-council"
version = "0.1.0"
source = "git+https://github.com/paritytech/substrate#c10123e41c2f4bfa7aa82f65c229920111c66d19"
source = "git+https://github.com/paritytech/substrate#3329915cd5458bd065c9f921891487e71511097c"
dependencies = [
"hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -335,7 +383,7 @@ dependencies = [
[[package]]
name = "srml-democracy"
version = "0.1.0"
source = "git+https://github.com/paritytech/substrate#c10123e41c2f4bfa7aa82f65c229920111c66d19"
source = "git+https://github.com/paritytech/substrate#3329915cd5458bd065c9f921891487e71511097c"
dependencies = [
"hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -354,7 +402,7 @@ dependencies = [
[[package]]
name = "srml-executive"
version = "0.1.0"
source = "git+https://github.com/paritytech/substrate#c10123e41c2f4bfa7aa82f65c229920111c66d19"
source = "git+https://github.com/paritytech/substrate#3329915cd5458bd065c9f921891487e71511097c"
dependencies = [
"hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -367,10 +415,29 @@ dependencies = [
"srml-system 0.1.0 (git+https://github.com/paritytech/substrate)",
]
[[package]]
name = "srml-grandpa"
version = "0.1.0"
source = "git+https://github.com/paritytech/substrate#3329915cd5458bd065c9f921891487e71511097c"
dependencies = [
"hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 0.1.0 (git+https://github.com/paritytech/substrate)",
"sr-primitives 0.1.0 (git+https://github.com/paritytech/substrate)",
"sr-std 0.1.0 (git+https://github.com/paritytech/substrate)",
"srml-session 0.1.0 (git+https://github.com/paritytech/substrate)",
"srml-support 0.1.0 (git+https://github.com/paritytech/substrate)",
"srml-system 0.1.0 (git+https://github.com/paritytech/substrate)",
"substrate-finality-grandpa-primitives 0.1.0 (git+https://github.com/paritytech/substrate)",
"substrate-primitives 0.1.0 (git+https://github.com/paritytech/substrate)",
]
[[package]]
name = "srml-metadata"
version = "0.1.0"
source = "git+https://github.com/paritytech/substrate#c10123e41c2f4bfa7aa82f65c229920111c66d19"
source = "git+https://github.com/paritytech/substrate#3329915cd5458bd065c9f921891487e71511097c"
dependencies = [
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -381,7 +448,7 @@ dependencies = [
[[package]]
name = "srml-session"
version = "0.1.0"
source = "git+https://github.com/paritytech/substrate#c10123e41c2f4bfa7aa82f65c229920111c66d19"
source = "git+https://github.com/paritytech/substrate#3329915cd5458bd065c9f921891487e71511097c"
dependencies = [
"hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -401,7 +468,7 @@ dependencies = [
[[package]]
name = "srml-staking"
version = "0.1.0"
source = "git+https://github.com/paritytech/substrate#c10123e41c2f4bfa7aa82f65c229920111c66d19"
source = "git+https://github.com/paritytech/substrate#3329915cd5458bd065c9f921891487e71511097c"
dependencies = [
"hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -423,7 +490,7 @@ dependencies = [
[[package]]
name = "srml-support"
version = "0.1.0"
source = "git+https://github.com/paritytech/substrate#c10123e41c2f4bfa7aa82f65c229920111c66d19"
source = "git+https://github.com/paritytech/substrate#3329915cd5458bd065c9f921891487e71511097c"
dependencies = [
"mashup 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -432,12 +499,46 @@ dependencies = [
"sr-primitives 0.1.0 (git+https://github.com/paritytech/substrate)",
"sr-std 0.1.0 (git+https://github.com/paritytech/substrate)",
"srml-metadata 0.1.0 (git+https://github.com/paritytech/substrate)",
"srml-support-procedural 0.1.0 (git+https://github.com/paritytech/substrate)",
]
[[package]]
name = "srml-support-procedural"
version = "0.1.0"
source = "git+https://github.com/paritytech/substrate#3329915cd5458bd065c9f921891487e71511097c"
dependencies = [
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-api-macros 0.1.0 (git+https://github.com/paritytech/substrate)",
"srml-support-procedural-tools 0.1.0 (git+https://github.com/paritytech/substrate)",
"syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "srml-support-procedural-tools"
version = "0.1.0"
source = "git+https://github.com/paritytech/substrate#3329915cd5458bd065c9f921891487e71511097c"
dependencies = [
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"srml-support-procedural-tools-derive 0.1.0 (git+https://github.com/paritytech/substrate)",
"syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "srml-support-procedural-tools-derive"
version = "0.1.0"
source = "git+https://github.com/paritytech/substrate#3329915cd5458bd065c9f921891487e71511097c"
dependencies = [
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "srml-system"
version = "0.1.0"
source = "git+https://github.com/paritytech/substrate#c10123e41c2f4bfa7aa82f65c229920111c66d19"
source = "git+https://github.com/paritytech/substrate#3329915cd5458bd065c9f921891487e71511097c"
dependencies = [
"hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -454,11 +555,10 @@ dependencies = [
[[package]]
name = "srml-timestamp"
version = "0.1.0"
source = "git+https://github.com/paritytech/substrate#c10123e41c2f4bfa7aa82f65c229920111c66d19"
source = "git+https://github.com/paritytech/substrate#3329915cd5458bd065c9f921891487e71511097c"
dependencies = [
"hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 0.1.0 (git+https://github.com/paritytech/substrate)",
"sr-primitives 0.1.0 (git+https://github.com/paritytech/substrate)",
@@ -472,7 +572,7 @@ dependencies = [
[[package]]
name = "srml-treasury"
version = "0.1.0"
source = "git+https://github.com/paritytech/substrate#c10123e41c2f4bfa7aa82f65c229920111c66d19"
source = "git+https://github.com/paritytech/substrate#3329915cd5458bd065c9f921891487e71511097c"
dependencies = [
"hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -495,19 +595,47 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "substrate-client"
version = "0.1.0"
source = "git+https://github.com/paritytech/substrate#c10123e41c2f4bfa7aa82f65c229920111c66d19"
source = "git+https://github.com/paritytech/substrate#3329915cd5458bd065c9f921891487e71511097c"
dependencies = [
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-api-macros 0.1.0 (git+https://github.com/paritytech/substrate)",
"sr-primitives 0.1.0 (git+https://github.com/paritytech/substrate)",
"sr-std 0.1.0 (git+https://github.com/paritytech/substrate)",
"sr-version 0.1.0 (git+https://github.com/paritytech/substrate)",
"substrate-primitives 0.1.0 (git+https://github.com/paritytech/substrate)",
]
[[package]]
name = "substrate-consensus-aura-primitives"
version = "0.1.0"
source = "git+https://github.com/paritytech/substrate#3329915cd5458bd065c9f921891487e71511097c"
dependencies = [
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-io 0.1.0 (git+https://github.com/paritytech/substrate)",
"sr-primitives 0.1.0 (git+https://github.com/paritytech/substrate)",
"sr-version 0.1.0 (git+https://github.com/paritytech/substrate)",
"srml-support 0.1.0 (git+https://github.com/paritytech/substrate)",
"substrate-client 0.1.0 (git+https://github.com/paritytech/substrate)",
"substrate-primitives 0.1.0 (git+https://github.com/paritytech/substrate)",
]
[[package]]
name = "substrate-finality-grandpa-primitives"
version = "0.1.0"
source = "git+https://github.com/paritytech/substrate#3329915cd5458bd065c9f921891487e71511097c"
dependencies = [
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"sr-primitives 0.1.0 (git+https://github.com/paritytech/substrate)",
"sr-std 0.1.0 (git+https://github.com/paritytech/substrate)",
"substrate-client 0.1.0 (git+https://github.com/paritytech/substrate)",
"substrate-primitives 0.1.0 (git+https://github.com/paritytech/substrate)",
]
[[package]]
name = "substrate-primitives"
version = "0.1.0"
source = "git+https://github.com/paritytech/substrate#c10123e41c2f4bfa7aa82f65c229920111c66d19"
source = "git+https://github.com/paritytech/substrate#3329915cd5458bd065c9f921891487e71511097c"
dependencies = [
"byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -527,7 +655,17 @@ name = "syn"
version = "0.14.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "syn"
version = "0.15.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -550,7 +688,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
"checksum bitvec 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e37e2176261200377c7cde4c6de020394174df556c356f965e4bc239f5ce1c5a"
"checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400"
"checksum byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d"
"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e"
"checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda"
"checksum crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c240f247c278fa08a6d4820a6a222bfc6e0d999e51ba67be94f44c905b2161f2"
"checksum fixed-hash 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a557e80084b05c32b455963ff565a9de6f2866da023d6671705c6aff6f65e01c"
@@ -568,7 +708,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffa42c2cb493b60b12c75b26e8c94cb734af4df4d7f2cc229dc04c1953dac189"
"checksum proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2c725b36c99df7af7bf9324e9c999b9e37d92c8f8caf106d82e1d7953218d2d8"
"checksum proc-macro-hack-impl 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2b753ad9ed99dd8efeaa7d2fb8453c8f6bc3e54b97966d35f1bc77ca6865254a"
"checksum proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)" = "88dae56b29da695d783ea7fc5a90de281f79eb38407e77f6d674dd8befc4ac47"
"checksum proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)" = "77619697826f31a02ae974457af0b29b723e5619e113e9397b8b82c6bd253f09"
"checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c"
"checksum rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "403bb3a286107a04825a5f82e1270acc1e14028d3d554d7a1e08914549575ab8"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
@@ -576,25 +716,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "15c141fc7027dd265a47c090bf864cf62b42c4d228bbcf4e51a0c9e2b0d3f7ef"
"checksum sr-api-macros 0.1.0 (git+https://github.com/paritytech/substrate)" = "<none>"
"checksum sr-io 0.1.0 (git+https://github.com/paritytech/substrate)" = "<none>"
"checksum sr-primitives 0.1.0 (git+https://github.com/paritytech/substrate)" = "<none>"
"checksum sr-std 0.1.0 (git+https://github.com/paritytech/substrate)" = "<none>"
"checksum sr-version 0.1.0 (git+https://github.com/paritytech/substrate)" = "<none>"
"checksum srml-aura 0.1.0 (git+https://github.com/paritytech/substrate)" = "<none>"
"checksum srml-balances 0.1.0 (git+https://github.com/paritytech/substrate)" = "<none>"
"checksum srml-consensus 0.1.0 (git+https://github.com/paritytech/substrate)" = "<none>"
"checksum srml-council 0.1.0 (git+https://github.com/paritytech/substrate)" = "<none>"
"checksum srml-democracy 0.1.0 (git+https://github.com/paritytech/substrate)" = "<none>"
"checksum srml-executive 0.1.0 (git+https://github.com/paritytech/substrate)" = "<none>"
"checksum srml-grandpa 0.1.0 (git+https://github.com/paritytech/substrate)" = "<none>"
"checksum srml-metadata 0.1.0 (git+https://github.com/paritytech/substrate)" = "<none>"
"checksum srml-session 0.1.0 (git+https://github.com/paritytech/substrate)" = "<none>"
"checksum srml-staking 0.1.0 (git+https://github.com/paritytech/substrate)" = "<none>"
"checksum srml-support 0.1.0 (git+https://github.com/paritytech/substrate)" = "<none>"
"checksum srml-support-procedural 0.1.0 (git+https://github.com/paritytech/substrate)" = "<none>"
"checksum srml-support-procedural-tools 0.1.0 (git+https://github.com/paritytech/substrate)" = "<none>"
"checksum srml-support-procedural-tools-derive 0.1.0 (git+https://github.com/paritytech/substrate)" = "<none>"
"checksum srml-system 0.1.0 (git+https://github.com/paritytech/substrate)" = "<none>"
"checksum srml-timestamp 0.1.0 (git+https://github.com/paritytech/substrate)" = "<none>"
"checksum srml-treasury 0.1.0 (git+https://github.com/paritytech/substrate)" = "<none>"
"checksum static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c19be23126415861cb3a23e501d34a708f7f9b2183c5252d690941c2e69199d5"
"checksum substrate-client 0.1.0 (git+https://github.com/paritytech/substrate)" = "<none>"
"checksum substrate-consensus-aura-primitives 0.1.0 (git+https://github.com/paritytech/substrate)" = "<none>"
"checksum substrate-finality-grandpa-primitives 0.1.0 (git+https://github.com/paritytech/substrate)" = "<none>"
"checksum substrate-primitives 0.1.0 (git+https://github.com/paritytech/substrate)" = "<none>"
"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741"
"checksum syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)" = "ae8b29eb5210bc5cf63ed6149cbf9adfc82ac0be023d8735c176ee74a2db4da7"
"checksum uint 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "082df6964410f6aa929a61ddfafc997e4f32c62c22490e439ac351cec827f436"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
+3
View File
@@ -15,14 +15,17 @@ parity-codec = { version = "2.1", default-features = false }
parity-codec-derive = { version = "2.1", default-features = false }
substrate-primitives = { git = "https://github.com/paritytech/substrate", default-features = false }
substrate-client = { git = "https://github.com/paritytech/substrate", default-features = false }
substrate-consensus-aura-primitives = { git = "https://github.com/paritytech/substrate", default-features = false }
sr-std = { git = "https://github.com/paritytech/substrate", default-features = false }
sr-io = { git = "https://github.com/paritytech/substrate", default-features = false }
srml-support = { git = "https://github.com/paritytech/substrate", default-features = false }
srml-aura = { git = "https://github.com/paritytech/substrate", default-features = false }
srml-balances = { git = "https://github.com/paritytech/substrate", default-features = false }
srml-consensus = { git = "https://github.com/paritytech/substrate", default-features = false }
srml-council = { git = "https://github.com/paritytech/substrate", default-features = false }
srml-democracy = { git = "https://github.com/paritytech/substrate", default-features = false }
srml-executive = { git = "https://github.com/paritytech/substrate", default-features = false }
srml-grandpa = { git = "https://github.com/paritytech/substrate", default-features = false }
sr-primitives = { git = "https://github.com/paritytech/substrate", default-features = false }
srml-session = { git = "https://github.com/paritytech/substrate", default-features = false }
srml-staking = { git = "https://github.com/paritytech/substrate", default-features = false }
+2 -1
View File
@@ -12,6 +12,7 @@ slog = "^2"
tokio = "0.1.7"
hex-literal = "0.1"
polkadot-availability-store = { path = "../availability-store" }
polkadot-consensus = { path = "../consensus" }
polkadot-primitives = { path = "../primitives" }
polkadot-runtime = { path = "../runtime" }
polkadot-executor = { path = "../executor" }
@@ -19,9 +20,9 @@ polkadot-network = { path = "../network" }
sr-io = { git = "https://github.com/paritytech/substrate" }
sr-primitives = { git = "https://github.com/paritytech/substrate" }
substrate-primitives = { git = "https://github.com/paritytech/substrate" }
substrate-network = { git = "https://github.com/paritytech/substrate" }
substrate-client = { git = "https://github.com/paritytech/substrate" }
substrate-consensus-aura = { git = "https://github.com/paritytech/substrate" }
substrate-finality-grandpa = { git = "https://github.com/paritytech/substrate" }
substrate-service = { git = "https://github.com/paritytech/substrate" }
substrate-telemetry = { git = "https://github.com/paritytech/substrate" }
substrate-transaction-pool = { git = "https://github.com/paritytech/substrate" }
+16 -20
View File
@@ -17,8 +17,10 @@
//! Polkadot chain configurations.
use primitives::{AuthorityId, ed25519};
use polkadot_runtime::{GenesisConfig, ConsensusConfig, CouncilSeatsConfig, DemocracyConfig,
SessionConfig, StakingConfig, TimestampConfig, BalancesConfig, Perbill, CouncilVotingConfig};
use polkadot_runtime::{
GenesisConfig, ConsensusConfig, CouncilSeatsConfig, DemocracyConfig,
SessionConfig, StakingConfig, TimestampConfig, BalancesConfig, Perbill, CouncilVotingConfig, GrandpaConfig
};
const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/";
const DEFAULT_PROTOCOL_ID: &str = "dot";
@@ -44,7 +46,6 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
consensus: Some(ConsensusConfig {
code: include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm").to_vec(), // TODO change
authorities: initial_authorities.clone(),
_genesis_phantom_data: Default::default(),
}),
system: None,
balances: Some(BalancesConfig {
@@ -55,12 +56,10 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
creation_fee: 0,
reclaim_rebate: 0,
balances: endowed_accounts.iter().map(|&k|(k, 1u128 << 60)).collect(),
_genesis_phantom_data: Default::default(),
}),
session: Some(SessionConfig {
validators: initial_authorities.iter().cloned().map(Into::into).collect(),
session_length: 60, // that's 5 minutes per session.
_genesis_phantom_data: Default::default(),
}),
staking: Some(StakingConfig {
current_era: 0,
@@ -74,13 +73,15 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
bonding_duration: 24 * 60 * 12, // 1 day per bond.
offline_slash_grace: 4,
minimum_validator_count: 4,
_genesis_phantom_data: Default::default(),
}),
democracy: Some(DemocracyConfig {
launch_period: 12 * 60 * 24, // 1 day per public referendum
voting_period: 12 * 60 * 24 * 3, // 3 days to discuss & vote on an active referendum
minimum_deposit: 5000, // 12000 as the minimum deposit for a referendum
_genesis_phantom_data: Default::default(),
public_delay: 0,
}),
grandpa: Some(GrandpaConfig {
authorities: initial_authorities.clone().into_iter().map(|k| (k, 1)).collect(),
}),
council_seats: Some(CouncilSeatsConfig {
active_council: vec![],
@@ -93,17 +94,15 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
term_duration: 12 * 60 * 24 * 24, // 24 day term duration for the council.
desired_seats: 0, // start with no council: we'll raise this once the stake has been dispersed a bit.
inactive_grace_period: 1, // one addition vote should go by before an inactive voter can be reaped.
_genesis_phantom_data: Default::default(),
}),
council_voting: Some(CouncilVotingConfig {
cooloff_period: 75,
voting_period: 20,
_genesis_phantom_data: Default::default(),
enact_delay_period: 0,
}),
parachains: Some(Default::default()),
timestamp: Some(TimestampConfig {
period: 5, // 5 second block time.
_genesis_phantom_data: Default::default(),
period: 2, // 2*2=4 second block time.
}),
treasury: Some(Default::default()),
}
@@ -137,7 +136,6 @@ fn testnet_genesis(initial_authorities: Vec<AuthorityId>) -> GenesisConfig {
consensus: Some(ConsensusConfig {
code: include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm").to_vec(),
authorities: initial_authorities.clone(),
_genesis_phantom_data: Default::default(),
}),
system: None,
balances: Some(BalancesConfig {
@@ -148,12 +146,10 @@ fn testnet_genesis(initial_authorities: Vec<AuthorityId>) -> GenesisConfig {
creation_fee: 0,
reclaim_rebate: 0,
balances: endowed_accounts.iter().map(|&k|(k, (1u128 << 60))).collect(),
_genesis_phantom_data: Default::default(),
}),
session: Some(SessionConfig {
validators: initial_authorities.iter().cloned().map(Into::into).collect(),
session_length: 10,
_genesis_phantom_data: Default::default(),
}),
staking: Some(StakingConfig {
current_era: 0,
@@ -167,13 +163,15 @@ fn testnet_genesis(initial_authorities: Vec<AuthorityId>) -> GenesisConfig {
current_offline_slash: 0,
current_session_reward: 0,
offline_slash_grace: 0,
_genesis_phantom_data: Default::default(),
}),
democracy: Some(DemocracyConfig {
launch_period: 9,
voting_period: 18,
minimum_deposit: 10,
_genesis_phantom_data: Default::default(),
public_delay: 0,
}),
grandpa: Some(GrandpaConfig {
authorities: initial_authorities.clone().into_iter().map(|k| (k, 1)).collect(),
}),
council_seats: Some(CouncilSeatsConfig {
active_council: endowed_accounts.iter().filter(|a| initial_authorities.iter().find(|&b| a[..] == b.0).is_none()).map(|a| (a.clone(), 1000000)).collect(),
@@ -186,17 +184,15 @@ fn testnet_genesis(initial_authorities: Vec<AuthorityId>) -> GenesisConfig {
term_duration: 1000000,
desired_seats: (endowed_accounts.len() - initial_authorities.len()) as u32,
inactive_grace_period: 1,
_genesis_phantom_data: Default::default(),
}),
council_voting: Some(CouncilVotingConfig {
cooloff_period: 75,
voting_period: 20,
_genesis_phantom_data: Default::default(),
enact_delay_period: 0,
}),
parachains: Some(Default::default()),
timestamp: Some(TimestampConfig {
period: 5, // 5 second block time.
_genesis_phantom_data: Default::default(),
period: 2, // 2*2=4 second block time.
}),
treasury: Some(Default::default()),
}
+121 -48
View File
@@ -19,18 +19,18 @@
//! Polkadot service. Specialized wrapper over substrate service.
extern crate polkadot_availability_store as av_store;
extern crate polkadot_consensus as consensus;
extern crate polkadot_primitives;
extern crate polkadot_runtime;
extern crate polkadot_executor;
extern crate polkadot_network;
extern crate sr_primitives;
extern crate substrate_primitives as primitives;
#[macro_use]
extern crate substrate_network as network;
extern crate substrate_client as client;
#[macro_use]
extern crate substrate_service as service;
extern crate substrate_consensus_aura as consensus;
extern crate substrate_consensus_aura as aura;
extern crate substrate_finality_grandpa as grandpa;
extern crate substrate_transaction_pool as transaction_pool;
extern crate tokio;
@@ -42,12 +42,14 @@ extern crate hex_literal;
pub mod chain_spec;
use std::sync::Arc;
use polkadot_primitives::{parachain, AccountId, Block};
use polkadot_runtime::{GenesisConfig, ClientWithApi};
use std::time::Duration;
use polkadot_primitives::{parachain, AccountId, Block, InherentData};
use polkadot_runtime::{GenesisConfig, RuntimeApi};
use primitives::ed25519;
use tokio::runtime::TaskExecutor;
use service::{FactoryFullConfiguration, FullBackend, LightBackend, FullExecutor, LightExecutor};
use transaction_pool::txpool::{Pool as TransactionPool};
use consensus::{import_queue, start_aura, Config as AuraConfig, AuraImportQueue, NothingExtra};
use aura::{import_queue, start_aura, AuraImportQueue, SlotDuration, NothingExtra, InherentProducingFn};
pub use service::{
Roles, PruningMode, TransactionPoolOptions, ComponentClient,
@@ -62,7 +64,7 @@ pub use primitives::{Blake2Hasher};
pub use sr_primitives::traits::ProvideRuntimeApi;
pub use chain_spec::ChainSpec;
const AURA_SLOT_DURATION: u64 = 6;
const PARACHAIN_EMPTY_DURATION: Duration = Duration::from_secs(4);
/// All configuration for the polkadot node.
pub type Configuration = FactoryFullConfiguration<Factory>;
@@ -73,11 +75,19 @@ pub struct CustomConfiguration {
/// Set to `Some` with a collator `AccountId` and desired parachain
/// if the network protocol should be started in collator mode.
pub collating_for: Option<(AccountId, parachain::Id)>,
/// Intermediate state during setup. Will be removed in future. Set to `None`.
// FIXME: rather than putting this on the config, let's have an actual intermediate setup state
// https://github.com/paritytech/substrate/issues/1134
pub grandpa_import_setup: Option<(
Arc<grandpa::BlockImportForService<Factory>>,
grandpa::LinkHalfForService<Factory>
)>,
}
/// Chain API type for the transaction pool.
pub type TxChainApi<Backend, Executor> = transaction_pool::ChainApi<
client::Client<Backend, Executor, Block, ClientWithApi>,
client::Client<Backend, Executor, Block, RuntimeApi>,
Block,
>;
@@ -89,7 +99,7 @@ pub trait PolkadotService {
type Executor: 'static + client::CallExecutor<Block, Blake2Hasher> + Send + Sync + Clone;
/// Get a handle to the client.
fn client(&self) -> Arc<client::Client<Self::Backend, Self::Executor, Block, ClientWithApi>>;
fn client(&self) -> Arc<client::Client<Self::Backend, Self::Executor, Block, RuntimeApi>>;
/// Get a handle to the network.
fn network(&self) -> Arc<NetworkService>;
@@ -102,7 +112,7 @@ impl PolkadotService for Service<FullComponents<Factory>> {
type Backend = <FullComponents<Factory> as Components>::Backend;
type Executor = <FullComponents<Factory> as Components>::Executor;
fn client(&self) -> Arc<client::Client<Self::Backend, Self::Executor, Block, ClientWithApi>> {
fn client(&self) -> Arc<client::Client<Self::Backend, Self::Executor, Block, RuntimeApi>> {
Service::client(self)
}
fn network(&self) -> Arc<NetworkService> {
@@ -118,9 +128,10 @@ impl PolkadotService for Service<LightComponents<Factory>> {
type Backend = <LightComponents<Factory> as Components>::Backend;
type Executor = <LightComponents<Factory> as Components>::Executor;
fn client(&self) -> Arc<client::Client<Self::Backend, Self::Executor, Block, ClientWithApi>> {
fn client(&self) -> Arc<client::Client<Self::Backend, Self::Executor, Block, RuntimeApi>> {
Service::client(self)
}
fn network(&self) -> Arc<NetworkService> {
Service::network(self)
}
@@ -130,10 +141,18 @@ impl PolkadotService for Service<LightComponents<Factory>> {
}
}
fn inherent_data_import_queue(timestamp: u64, slot: u64) -> InherentData {
InherentData {
parachains: Vec::new(),
timestamp,
aura_expected_slot: slot,
}
}
construct_service_factory! {
struct Factory {
Block = Block,
RuntimeApi = ClientWithApi,
RuntimeApi = RuntimeApi,
NetworkProtocol = PolkadotProtocol { |config: &Configuration| Ok(PolkadotProtocol::new(config.custom.collating_for)) },
RuntimeDispatch = polkadot_executor::Executor,
FullTransactionPoolApi = TxChainApi<FullBackend<Self>, FullExecutor<Self>>
@@ -144,54 +163,108 @@ construct_service_factory! {
Configuration = CustomConfiguration,
FullService = FullComponents<Self>
{ |config: FactoryFullConfiguration<Self>, executor: TaskExecutor| {
let is_auth = config.roles == Roles::AUTHORITY;
FullComponents::<Factory>::new(config, executor.clone()).map(move |service|{
if is_auth {
if let Ok(Some(Ok(key))) = service.keystore().contents()
.map(|keys| keys.get(0).map(|k| service.keystore().load(k, "")))
FullComponents::<Factory>::new(config, executor)
} },
AuthoritySetup = { |mut service: Self::FullService, executor: TaskExecutor, key: Arc<ed25519::Pair>| {
use polkadot_network::consensus::ConsensusNetwork;
let (block_import, link_half) = service.config.custom.grandpa_import_setup.take()
.expect("Link Half and Block Import are present for Full Services or setup failed before. qed");
{
info!("Running Grandpa session as Authority {}", key.public());
let (voter, oracle) = grandpa::run_grandpa(
grandpa::Config {
gossip_duration: Duration::new(4, 0), // FIXME: make this available through chainspec?
local_key: Some(key.clone()),
name: Some(service.config.name.clone())
},
link_half,
grandpa::NetworkBridge::new(service.network()),
)?;
executor.spawn(oracle);
executor.spawn(voter);
}
let extrinsic_store = {
use std::path::PathBuf;
let mut path = PathBuf::from(service.config.database_path.clone());
path.push("availability");
::av_store::Store::new(::av_store::Config {
cache_size: None,
path,
})?
};
let client = service.client();
// collator connections and consensus network both fulfilled by this
let consensus_network = ConsensusNetwork::new(service.network(), service.client());
let proposer_factory = ::consensus::ProposerFactory::new(
client.clone(),
consensus_network.clone(),
consensus_network,
service.transaction_pool(),
executor.clone(),
PARACHAIN_EMPTY_DURATION,
key.clone(),
extrinsic_store,
);
info!("Using authority key {}", key.public());
let task = start_aura(
AuraConfig {
local_key: Some(Arc::new(key)),
slot_duration: AURA_SLOT_DURATION,
},
service.client(),
service.proposer(),
SlotDuration::get_or_compute(&*client)?,
key,
client.clone(),
client,
Arc::new(proposer_factory),
service.network(),
);
executor.spawn(task);
}
}
service
})
}
},
AuthoritySetup = { |service, _, _| Ok(service) },
Ok(service)
}},
LightService = LightComponents<Self>
{ |config, executor| <LightComponents<Factory>>::new(config, executor) },
FullImportQueue = AuraImportQueue<Self::Block, FullClient<Self>, NothingExtra>
{ |config, client| Ok(import_queue(
AuraConfig {
local_key: None,
slot_duration: 5
},
FullImportQueue = AuraImportQueue<
Self::Block,
grandpa::BlockImportForService<Self>,
NothingExtra,
InherentProducingFn<InherentData>,
>
{ |config: &mut FactoryFullConfiguration<Self>, client: Arc<FullClient<Self>>| {
let slot_duration = SlotDuration::get_or_compute(&*client)?;
let (block_import, link_half) = grandpa::block_import::<_, _, _, RuntimeApi, FullClient<Self>>(client.clone(), client)?;
let block_import = Arc::new(block_import);
config.custom.grandpa_import_setup = Some((block_import.clone(), link_half));
Ok(import_queue(
slot_duration,
block_import,
NothingExtra,
inherent_data_import_queue as _,
))
}},
LightImportQueue = AuraImportQueue<
Self::Block,
LightClient<Self>,
NothingExtra,
InherentProducingFn<InherentData>,
>
{ |config, client: Arc<LightClient<Self>>| {
let slot_duration = SlotDuration::get_or_compute(&*client)?;
Ok(import_queue(
slot_duration,
client,
NothingExtra,
inherent_data_import_queue as _,
))
},
LightImportQueue = AuraImportQueue<Self::Block, LightClient<Self>, NothingExtra>
{ |config, client| Ok(import_queue(
AuraConfig {
local_key: None,
slot_duration: 5
},
client,
NothingExtra,
))
},
}},
}
}