Commit b736abcc authored by asynchronous rob's avatar asynchronous rob Committed by Gav Wood
Browse files

Update to latest substrate (#57)

* update to latest substrate

* update WASM and runtime

* Rename Id to ParaId in decl_{module,storage} (exported metadata type) (#58)

* Rename Id to ParaId in decla_module (exported type)

* AccountParaId -> AccountId
parent 2b8f1758
Pipeline #27377 passed with stages
in 15 minutes and 26 seconds
This diff is collapsed.
......@@ -16,6 +16,7 @@ polkadot-parachain = { path = "../parachain" }
polkadot-primitives = { path = "../primitives" }
polkadot-runtime = { path = "../runtime" }
polkadot-statement-table = { path = "../statement-table" }
substrate-consensus-aura-primitives = { 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" }
......
......@@ -17,6 +17,7 @@
//! Errors that can occur during the consensus process.
use primitives::AuthorityId;
use runtime_primitives::RuntimeString;
error_chain! {
links {
......@@ -33,6 +34,10 @@ error_chain! {
description("Local account ID not a validator at this block."),
display("Local account ID ({:?}) not a validator at this block.", id),
}
InherentError(reason: RuntimeString) {
description("Unexpected error while checking inherents"),
display("Unexpected error while checking inherents: {}", reason),
}
PrematureDestruction {
description("Proposer destroyed before finishing proposing or evaluating"),
display("Proposer destroyed before finishing proposing or evaluating"),
......
......@@ -45,6 +45,7 @@ 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_primitives as aura_primitives;
extern crate substrate_finality_grandpa as grandpa;
extern crate substrate_transaction_pool as transaction_pool;
......@@ -74,7 +75,6 @@ use parking_lot::Mutex;
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};
......@@ -82,6 +82,7 @@ use runtime_primitives::traits::ProvideRuntimeApi;
use tokio::runtime::TaskExecutor;
use tokio::timer::{Delay, Interval};
use transaction_pool::txpool::{Pool, ChainApi as PoolChainApi};
use aura_primitives::AuraConsensusData;
use attestation_service::ServiceHandle;
use futures::prelude::*;
......@@ -246,8 +247,6 @@ struct ParachainConsensus<C, N, P> {
handle: TaskExecutor,
/// Store for extrinsic data.
extrinsic_store: ExtrinsicStore,
/// The time after which no parachains may be included.
parachain_empty_duration: Duration,
/// Live agreements.
live_instances: Mutex<HashMap<Hash, Arc<AttestationTracker>>>,
......@@ -321,16 +320,9 @@ impl<C, N, P> ParachainConsensus<C, N, P> where
self.extrinsic_store.clone(),
);
let now = Instant::now();
let dynamic_inclusion = DynamicInclusion::new(
table.num_parachains(),
now,
self.parachain_empty_duration.clone(),
);
let tracker = Arc::new(AttestationTracker {
table,
dynamic_inclusion,
started: Instant::now(),
_drop_signal: drop_signal
});
......@@ -349,7 +341,7 @@ impl<C, N, P> ParachainConsensus<C, N, P> where
struct AttestationTracker {
_drop_signal: exit_future::Signal,
table: Arc<SharedTable>,
dynamic_inclusion: DynamicInclusion,
started: Instant,
}
/// Polkadot proposer factory.
......@@ -376,7 +368,6 @@ impl<C, N, P, TxApi> ProposerFactory<C, N, P, TxApi> where
collators: C,
transaction_pool: Arc<Pool<TxApi>>,
thread_pool: TaskExecutor,
parachain_empty_duration: Duration,
key: Arc<ed25519::Pair>,
extrinsic_store: ExtrinsicStore,
) -> Self {
......@@ -386,7 +377,6 @@ impl<C, N, P, TxApi> ProposerFactory<C, N, P, TxApi> where
collators,
handle: thread_pool.clone(),
extrinsic_store: extrinsic_store.clone(),
parachain_empty_duration,
live_instances: Mutex::new(HashMap::new()),
});
......@@ -406,7 +396,7 @@ impl<C, N, P, TxApi> ProposerFactory<C, N, P, TxApi> where
}
}
impl<C, N, P, TxApi> consensus::Environment<Block> for ProposerFactory<C, N, P, TxApi> where
impl<C, N, P, TxApi> consensus::Environment<Block, AuraConsensusData> for ProposerFactory<C, N, P, TxApi> where
C: Collators + Send + 'static,
N: Network,
TxApi: PoolChainApi<Block=Block>,
......@@ -424,9 +414,6 @@ impl<C, N, P, TxApi> consensus::Environment<Block> for ProposerFactory<C, N, P,
authorities: &[AuthorityId],
sign_with: Arc<ed25519::Pair>,
) -> Result<Self::Proposer, Error> {
// force delay in evaluation this long.
const FORCE_DELAY: Timestamp = Compact(5);
let parent_hash = parent_header.hash();
let parent_id = BlockId::hash(parent_hash);
let tracker = self.parachain_consensus.get_or_instantiate(
......@@ -442,7 +429,6 @@ impl<C, N, P, TxApi> consensus::Environment<Block> for ProposerFactory<C, N, P,
parent_id,
parent_number: parent_header.number,
transaction_pool: self.transaction_pool.clone(),
minimum_timestamp: current_timestamp().0 + FORCE_DELAY.0,
})
}
}
......@@ -517,10 +503,9 @@ pub struct Proposer<C: Send + Sync, TxApi: PoolChainApi> where
parent_number: BlockNumber,
tracker: Arc<AttestationTracker>,
transaction_pool: Arc<Pool<TxApi>>,
minimum_timestamp: u64,
}
impl<C, TxApi> consensus::Proposer<Block> for Proposer<C, TxApi> where
impl<C, TxApi> consensus::Proposer<Block, AuraConsensusData> for Proposer<C, TxApi> where
TxApi: PoolChainApi<Block=Block>,
C: ProvideRuntimeApi + HeaderBackend<Block> + Send + Sync,
C::Api: ParachainHost<Block> + BlockBuilderApi<Block, InherentData>,
......@@ -531,20 +516,41 @@ impl<C, TxApi> consensus::Proposer<Block> for Proposer<C, TxApi> where
future::FutureResult<Block, Error>,
>;
fn propose(&self) -> Self::Create {
fn propose(&self, consensus_data: AuraConsensusData) -> Self::Create {
const ATTEMPT_PROPOSE_EVERY: Duration = Duration::from_millis(100);
const SLOT_DURATION_DENOMINATOR: u64 = 3; // wait up to 1/3 of the slot for candidates.
let initial_included = self.tracker.table.includable_count();
let now = Instant::now();
let enough_candidates = self.tracker.dynamic_inclusion.acceptable_in(
let dynamic_inclusion = DynamicInclusion::new(
self.tracker.table.num_parachains(),
self.tracker.started,
Duration::from_secs(consensus_data.slot_duration / SLOT_DURATION_DENOMINATOR),
);
let enough_candidates = dynamic_inclusion.acceptable_in(
now,
initial_included,
).unwrap_or_else(|| now + Duration::from_millis(1));
let believed_timestamp = consensus_data.timestamp;
// set up delay until next allowed timestamp.
let current_timestamp = current_timestamp();
let delay_future = if current_timestamp.0 >= believed_timestamp {
None
} else {
Some(Delay::new(
Instant::now() + Duration::from_secs(current_timestamp.0 - believed_timestamp)
))
};
let timing = ProposalTiming {
minimum: delay_future,
attempt_propose: Interval::new(now + ATTEMPT_PROPOSE_EVERY, ATTEMPT_PROPOSE_EVERY),
enough_candidates: Delay::new(enough_candidates),
dynamic_inclusion: self.tracker.dynamic_inclusion.clone(),
dynamic_inclusion,
last_included: initial_included,
};
......@@ -555,7 +561,8 @@ impl<C, TxApi> consensus::Proposer<Block> for Proposer<C, TxApi> where
client: self.client.clone(),
transaction_pool: self.transaction_pool.clone(),
table: self.tracker.table.clone(),
minimum_timestamp: self.minimum_timestamp.into(),
believed_minimum_timestamp: believed_timestamp,
consensus_data,
timing,
})
}
......@@ -569,6 +576,7 @@ fn current_timestamp() -> Timestamp {
}
struct ProposalTiming {
minimum: Option<Delay>,
attempt_propose: Interval,
dynamic_inclusion: DynamicInclusion,
enough_candidates: Delay,
......@@ -588,6 +596,14 @@ impl ProposalTiming {
x.expect("timer still alive; intervals never end; qed");
}
// wait until the minimum time has passed.
if let Some(mut minimum) = self.minimum.take() {
if let Async::NotReady = minimum.poll().map_err(ErrorKind::Timer)? {
self.minimum = Some(minimum);
return Ok(Async::NotReady);
}
}
if included == self.last_included {
return self.enough_candidates.poll().map_err(ErrorKind::Timer);
}
......@@ -614,7 +630,8 @@ pub struct CreateProposal<C: Send + Sync, TxApi: PoolChainApi> {
transaction_pool: Arc<Pool<TxApi>>,
table: Arc<SharedTable>,
timing: ProposalTiming,
minimum_timestamp: Timestamp,
believed_minimum_timestamp: u64,
consensus_data: AuraConsensusData,
}
impl<C, TxApi> CreateProposal<C, TxApi> where
......@@ -626,13 +643,10 @@ impl<C, TxApi> CreateProposal<C, TxApi> where
use client::block_builder::BlockBuilder;
use runtime_primitives::traits::{Hash as HashT, BlakeTwo256};
// TODO: handle case when current timestamp behind that in state.
let timestamp = ::std::cmp::max(self.minimum_timestamp.0, current_timestamp().0);
let inherent_data = InherentData {
timestamp,
timestamp: self.believed_minimum_timestamp,
parachains: candidates,
aura_expected_slot: 0, // not required here.
aura_expected_slot: self.consensus_data.slot,
};
let runtime_api = self.client.runtime_api();
......@@ -685,7 +699,7 @@ impl<C, TxApi> CreateProposal<C, TxApi> where
let active_parachains = runtime_api.active_parachains(&self.parent_id)?;
assert!(evaluation::evaluate_initial(
&new_block,
timestamp.into(),
self.believed_minimum_timestamp.into(),
&self.parent_hash,
self.parent_number,
&active_parachains,
......
......@@ -193,14 +193,14 @@ impl<P: ProvideRuntimeApi + Send + Sync + 'static> Router<P>
if let Some(validity) = produced.validity {
let signed = table.sign_and_import(validity.clone()).0;
network.with_spec(|_, ctx|
gossip.multicast(ctx, attestation_topic, signed.encode())
gossip.multicast(ctx, attestation_topic, signed.encode(), false)
);
}
if let Some(availability) = produced.availability {
let signed = table.sign_and_import(availability).0;
network.with_spec(|_, ctx|
gossip.multicast(ctx, attestation_topic, signed.encode())
gossip.multicast(ctx, attestation_topic, signed.encode(), false)
);
}
})
......@@ -225,9 +225,9 @@ impl<P: ProvideRuntimeApi + Send> TableRouter for Router<P>
self.knowledge.lock().note_candidate(hash, Some(block_data), Some(extrinsic));
let mut gossip = self.network.consensus_gossip().write();
self.network.with_spec(|_spec, ctx| {
gossip.multicast(ctx, self.attestation_topic, candidate.encode());
gossip.multicast(ctx, self.attestation_topic, candidate.encode(), false);
if let Some(availability) = availability {
gossip.multicast(ctx, self.attestation_topic, availability.encode());
gossip.multicast(ctx, self.attestation_topic, availability.encode(), false);
}
});
}
......
......@@ -24,7 +24,7 @@ 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 primitives::parachain::{Id as ParaId, Chain, DutyRoster, AttestedCandidate, Statement};
use {system, session};
use srml_support::{StorageValue, StorageMap};
......@@ -46,17 +46,17 @@ pub trait Trait: session::Trait {
decl_storage! {
trait Store for Module<T: Trait> as Parachains {
// Vector of all parachain IDs.
pub Parachains get(active_parachains): Vec<Id>;
pub Parachains get(active_parachains): Vec<ParaId>;
// The parachains registered at present.
pub Code get(parachain_code): map Id => Option<Vec<u8>>;
pub Code get(parachain_code): map ParaId => Option<Vec<u8>>;
// The heads of the parachains registered at present. these are kept sorted.
pub Heads get(parachain_head): map Id => Option<Vec<u8>>;
pub Heads get(parachain_head): map ParaId => Option<Vec<u8>>;
// Did the parachain heads get updated in this block?
DidUpdate: bool;
}
add_extra_genesis {
config(parachains): Vec<(Id, Vec<u8>, Vec<u8>)>;
config(parachains): Vec<(ParaId, Vec<u8>, Vec<u8>)>;
config(_phdata): PhantomData<T>;
build(|storage: &mut sr_primitives::StorageMap, _: &mut ChildrenStorageMap, config: &GenesisConfig<T>| {
use codec::Encode;
......@@ -134,7 +134,7 @@ decl_module! {
/// Register a parachain with given code.
/// Fails if given ID is already used.
pub fn register_parachain(id: Id, code: Vec<u8>, initial_head_data: Vec<u8>) -> Result {
pub fn register_parachain(id: ParaId, code: Vec<u8>, initial_head_data: Vec<u8>) -> Result {
let mut parachains = Self::active_parachains();
match parachains.binary_search(&id) {
Ok(_) => fail!("Parachain already exists"),
......@@ -149,7 +149,7 @@ decl_module! {
}
/// Deregister a parachain with given id
pub fn deregister_parachain(id: Id) -> Result {
pub fn deregister_parachain(id: ParaId) -> Result {
let mut parachains = Self::active_parachains();
match parachains.binary_search(&id) {
Ok(idx) => { parachains.remove(idx); }
......@@ -240,15 +240,15 @@ impl<T: Trait> Module<T> {
// assumes the inner slice is sorted by id.
struct GroupedDutyIter<'a> {
next_idx: usize,
inner: &'a [(usize, Id)],
inner: &'a [(usize, ParaId)],
}
impl<'a> GroupedDutyIter<'a> {
fn new(inner: &'a [(usize, Id)]) -> Self {
fn new(inner: &'a [(usize, ParaId)]) -> Self {
GroupedDutyIter { next_idx: 0, inner }
}
fn group_for(&mut self, wanted_id: Id) -> Option<&'a [(usize, Id)]> {
fn group_for(&mut self, wanted_id: ParaId) -> Option<&'a [(usize, ParaId)]> {
while let Some((id, keys)) = self.next() {
if wanted_id == id {
return Some(keys)
......@@ -260,7 +260,7 @@ impl<T: Trait> Module<T> {
}
impl<'a> Iterator for GroupedDutyIter<'a> {
type Item = (Id, &'a [(usize, Id)]);
type Item = (ParaId, &'a [(usize, ParaId)]);
fn next(&mut self) -> Option<Self::Item> {
if self.next_idx == self.inner.len() { return None }
......@@ -435,7 +435,7 @@ impl<T: Trait> ProvideInherent for Module<T> {
.extrinsics()
.get(T::SET_POSITION as usize)
.map_or(false, |xt| {
xt.is_signed() == Some(true) && match extract_function(&xt) {
xt.is_signed() == Some(false) && match extract_function(&xt) {
Some(Call::set_heads(_)) => true,
_ => false,
}
......@@ -502,7 +502,7 @@ mod tests {
type Parachains = Module<Test>;
fn new_test_ext(parachains: Vec<(Id, Vec<u8>, Vec<u8>)>) -> TestExternalities<Blake2Hasher> {
fn new_test_ext(parachains: Vec<(ParaId, Vec<u8>, Vec<u8>)>) -> TestExternalities<Blake2Hasher> {
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap().0;
let authority_keys = [
Keyring::Alice,
......@@ -629,7 +629,7 @@ mod tests {
let check_roster = |duty_roster: &DutyRoster| {
assert_eq!(duty_roster.validator_duty.len(), 8);
assert_eq!(duty_roster.guarantor_duty.len(), 8);
for i in (0..2).map(Id::from) {
for i in (0..2).map(ParaId::from) {
assert_eq!(duty_roster.validator_duty.iter().filter(|&&j| j == Chain::Parachain(i)).count(), 3);
assert_eq!(duty_roster.guarantor_duty.iter().filter(|&&j| j == Chain::Parachain(i)).count(), 3);
}
......
......@@ -78,7 +78,8 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
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
public_delay: 0,
public_delay: 10 * 60,
max_lock_periods: 6,
}),
grandpa: Some(GrandpaConfig {
authorities: initial_authorities.clone().into_iter().map(|k| (k, 1)).collect(),
......@@ -168,7 +169,8 @@ fn testnet_genesis(initial_authorities: Vec<AuthorityId>) -> GenesisConfig {
launch_period: 9,
voting_period: 18,
minimum_deposit: 10,
public_delay: 0,
public_delay: 10 * 60,
max_lock_periods: 6,
}),
grandpa: Some(GrandpaConfig {
authorities: initial_authorities.clone().into_iter().map(|k| (k, 1)).collect(),
......
......@@ -64,9 +64,6 @@ pub use primitives::{Blake2Hasher};
pub use sr_primitives::traits::ProvideRuntimeApi;
pub use chain_spec::ChainSpec;
// wait 1.5 seconds for parachain candidates before releasing a block.
const PARACHAIN_EMPTY_DURATION: Duration = Duration::from_millis(1500);
/// All configuration for the polkadot node.
pub type Configuration = FactoryFullConfiguration<Factory>;
......@@ -166,25 +163,24 @@ construct_service_factory! {
{ |config: FactoryFullConfiguration<Self>, executor: TaskExecutor| {
FullComponents::<Factory>::new(config, executor)
} },
AuthoritySetup = { |mut service: Self::FullService, executor: TaskExecutor, key: Arc<ed25519::Pair>| {
AuthoritySetup = { |mut service: Self::FullService, executor: TaskExecutor, key: Option<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");
// always run GRANDPA in order to sync.
{
info!("Running Grandpa session as Authority {}", key.public());
let (voter, oracle) = grandpa::run_grandpa(
let voter = grandpa::run_grandpa(
grandpa::Config {
gossip_duration: Duration::new(4, 0), // FIXME: make this available through chainspec?
local_key: Some(key.clone()),
local_key: key.clone(),
name: Some(service.config.name.clone())
},
link_half,
grandpa::NetworkBridge::new(service.network()),
)?;
executor.spawn(oracle);
executor.spawn(voter);
}
......@@ -200,6 +196,12 @@ construct_service_factory! {
})?
};
// run authorship only if authority.
let key = match key {
Some(key) => key,
None => return Ok(service),
};
let client = service.client();
// collator connections and consensus network both fulfilled by this
......@@ -210,7 +212,6 @@ construct_service_factory! {
consensus_network,
service.transaction_pool(),
executor.clone(),
PARACHAIN_EMPTY_DURATION,
key.clone(),
extrinsic_store,
);
......
......@@ -19,8 +19,7 @@
#![no_std]
#![feature(
alloc, core_intrinsics, lang_items, panic_handler, core_panic_info,
alloc_error_handler
alloc, core_intrinsics, lang_items, core_panic_info, alloc_error_handler
)]
extern crate alloc;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment