mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-24 17:11:05 +00:00
Update to latest Substrate master. (#353)
* Integrate srml/im-online * Fix all build errors with old aura. * Fix most of the build errors. * Builds and tests seem to pass (I will not trust this commit yet) * Apply suggestions from code review Co-Authored-By: Robert Habermeier <rphmeier@gmail.com> * Kill some warnings. * fix panics on 0 validators * Fix dev chain. * Fix author stuff * fix im online integration. * Some tweaks * Introduce app-crypto * Initial build work * codec update / tweaks * patch polkadot-erasure-coding input * More fixes for new crypto * More fixes * Update parachains module * evamp parachain crypto * More crypto work. * Chain spec and service. * ChainSpec stuff * Last bits for a clean build * Tweak coment * adapt polkadot-validation to the new keystore * polkadot-network compiles, but tests don't * Integrate the new parachain validation stuff * delete message_routing file * make polkadot-network tests compile and pass * runtime tests compile and pass * update substrate ref * service compiles * all tests pass * Add TODO, change branch back to polkadot-master * Lock file * TODOs done * Issue number * Remove old tODO * Remove commented code
This commit is contained in:
@@ -33,11 +33,11 @@ use extrinsic_store::Store as ExtrinsicStore;
|
||||
use futures::prelude::*;
|
||||
use futures03::{TryStreamExt as _, StreamExt as _};
|
||||
use log::error;
|
||||
use primitives::ed25519;
|
||||
use polkadot_primitives::{Block, BlockId, AuraId};
|
||||
use polkadot_primitives::{Block, BlockId};
|
||||
use polkadot_primitives::parachain::{CandidateReceipt, ParachainHost};
|
||||
use runtime_primitives::traits::{ProvideRuntimeApi, Header as HeaderT};
|
||||
use aura::AuraApi;
|
||||
use babe_primitives::BabeApi;
|
||||
use keystore::KeyStorePtr;
|
||||
|
||||
use tokio::{timer::Interval, runtime::current_thread::Runtime as LocalRuntime};
|
||||
use log::{warn, debug};
|
||||
@@ -50,14 +50,14 @@ type TaskExecutor = Arc<dyn futures::future::Executor<Box<dyn Future<Item = (),
|
||||
pub(crate) fn fetch_candidates<P: BlockBody<Block>>(client: &P, block: &BlockId)
|
||||
-> ClientResult<Option<impl Iterator<Item=CandidateReceipt>>>
|
||||
{
|
||||
use parity_codec::{Encode, Decode};
|
||||
use codec::{Encode, Decode};
|
||||
use polkadot_runtime::{Call, ParachainsCall, UncheckedExtrinsic as RuntimeExtrinsic};
|
||||
|
||||
let extrinsics = client.block_body(block)?;
|
||||
Ok(match extrinsics {
|
||||
Some(extrinsics) => extrinsics
|
||||
.into_iter()
|
||||
.filter_map(|ex| RuntimeExtrinsic::decode(&mut ex.encode().as_slice()))
|
||||
.filter_map(|ex| RuntimeExtrinsic::decode(&mut ex.encode().as_slice()).ok())
|
||||
.filter_map(|ex| match ex.function {
|
||||
Call::Parachains(ParachainsCall::set_heads(heads)) => {
|
||||
Some(heads.into_iter().map(|c| c.candidate))
|
||||
@@ -114,7 +114,7 @@ pub(crate) fn start<C, N, P, SC>(
|
||||
select_chain: SC,
|
||||
parachain_validation: Arc<crate::ParachainValidation<C, N, P>>,
|
||||
thread_pool: TaskExecutor,
|
||||
key: Arc<ed25519::Pair>,
|
||||
keystore: KeyStorePtr,
|
||||
extrinsic_store: ExtrinsicStore,
|
||||
max_block_data_size: Option<u64>,
|
||||
) -> ServiceHandle
|
||||
@@ -123,7 +123,7 @@ pub(crate) fn start<C, N, P, SC>(
|
||||
<C::Collation as IntoFuture>::Future: Send + 'static,
|
||||
P: BlockchainEvents<Block> + BlockBody<Block>,
|
||||
P: ProvideRuntimeApi + HeaderBackend<Block> + Send + Sync + 'static,
|
||||
P::Api: ParachainHost<Block> + BlockBuilder<Block> + AuraApi<Block, AuraId>,
|
||||
P::Api: ParachainHost<Block> + BlockBuilder<Block> + BabeApi<Block>,
|
||||
N: Network + Send + Sync + 'static,
|
||||
N::TableRouter: Send + 'static,
|
||||
<N::BuildTableRouter as IntoFuture>::Future: Send + 'static,
|
||||
@@ -138,7 +138,8 @@ pub(crate) fn start<C, N, P, SC>(
|
||||
let notifications = {
|
||||
let client = client.clone();
|
||||
let validation = parachain_validation.clone();
|
||||
let key = key.clone();
|
||||
|
||||
let keystore = keystore.clone();
|
||||
|
||||
client.import_notification_stream()
|
||||
.map(|v| Ok::<_, ()>(v)).compat()
|
||||
@@ -148,7 +149,7 @@ pub(crate) fn start<C, N, P, SC>(
|
||||
let res = validation.get_or_instantiate(
|
||||
parent_hash,
|
||||
notification.header.parent_hash().clone(),
|
||||
key.clone(),
|
||||
&keystore,
|
||||
max_block_data_size,
|
||||
);
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ use polkadot_primitives::{Block, Hash, BlockId, Balance, parachain::{
|
||||
}};
|
||||
use runtime_primitives::traits::ProvideRuntimeApi;
|
||||
use parachain::{wasm_executor::{self, ExternalitiesError, ExecutionMode}, MessageRef, UpwardMessageRef};
|
||||
|
||||
use trie::TrieConfiguration;
|
||||
use futures::prelude::*;
|
||||
use log::debug;
|
||||
|
||||
@@ -186,7 +186,7 @@ impl std::error::Error for Error {
|
||||
pub fn message_queue_root<A, I: IntoIterator<Item=A>>(messages: I) -> Hash
|
||||
where A: AsRef<[u8]>
|
||||
{
|
||||
::trie::ordered_trie_root::<primitives::Blake2Hasher, _, _>(messages)
|
||||
::trie::trie_types::Layout::<primitives::Blake2Hasher>::ordered_trie_root(messages)
|
||||
}
|
||||
|
||||
/// Compute the set of egress roots for all given outgoing messages.
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
//! Errors that can occur during the validation process.
|
||||
|
||||
use runtime_primitives::RuntimeString;
|
||||
use primitives::ed25519::Public as AuthorityId;
|
||||
use polkadot_primitives::parachain::ValidatorId;
|
||||
|
||||
/// Error type for validation
|
||||
#[derive(Debug, derive_more::Display, derive_more::From)]
|
||||
@@ -35,7 +35,7 @@ pub enum Error {
|
||||
},
|
||||
/// Local account not a validator at this block
|
||||
#[display(fmt = "Local account ID ({:?}) not a validator at this block.", _0)]
|
||||
NotValidator(AuthorityId),
|
||||
NotValidator(ValidatorId),
|
||||
/// Unexpected error checking inherents
|
||||
#[display(fmt = "Unexpected error while checking inherents: {}", _0)]
|
||||
InherentError(RuntimeString),
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
use super::MAX_TRANSACTIONS_SIZE;
|
||||
|
||||
use parity_codec::Encode;
|
||||
use codec::Encode;
|
||||
use polkadot_primitives::{Block, Hash, BlockNumber};
|
||||
use polkadot_primitives::parachain::Id as ParaId;
|
||||
|
||||
|
||||
@@ -31,21 +31,21 @@
|
||||
|
||||
use std::{collections::{HashMap, HashSet}, pin::Pin, sync::Arc, time::{self, Duration, Instant}};
|
||||
|
||||
use aura::{SlotDuration, AuraApi};
|
||||
use babe_primitives::BabeApi;
|
||||
use client::{BlockchainEvents, BlockBody};
|
||||
use client::blockchain::HeaderBackend;
|
||||
use client::block_builder::api::BlockBuilder as BlockBuilderApi;
|
||||
use parity_codec::Encode;
|
||||
use codec::Encode;
|
||||
use consensus::SelectChain;
|
||||
use extrinsic_store::Store as ExtrinsicStore;
|
||||
use parking_lot::Mutex;
|
||||
use polkadot_primitives::{Hash, Block, BlockId, BlockNumber, Header, SessionKey, AuraId};
|
||||
use polkadot_primitives::{Hash, Block, BlockId, BlockNumber, Header};
|
||||
use polkadot_primitives::parachain::{
|
||||
Id as ParaId, Chain, DutyRoster, Extrinsic as ParachainExtrinsic, CandidateReceipt,
|
||||
ParachainHost, AttestedCandidate, Statement as PrimitiveStatement, Message, OutgoingMessage,
|
||||
CollatorSignature, Collation, PoVBlock,
|
||||
Collation, PoVBlock, ValidatorSignature, ValidatorPair, ValidatorId
|
||||
};
|
||||
use primitives::{Pair, ed25519};
|
||||
use primitives::Pair;
|
||||
use runtime_primitives::{
|
||||
traits::{ProvideRuntimeApi, Header as HeaderT, DigestFor}, ApplyError
|
||||
};
|
||||
@@ -58,10 +58,9 @@ use futures03::{future::{self, Either, FutureExt}, task::Context, stream::Stream
|
||||
use collation::CollationFetch;
|
||||
use dynamic_inclusion::DynamicInclusion;
|
||||
use inherents::InherentData;
|
||||
use runtime_aura::timestamp::TimestampInherentData;
|
||||
use runtime_babe::timestamp::TimestampInherentData;
|
||||
use log::{info, debug, warn, trace, error};
|
||||
|
||||
use ed25519::Public as AuthorityId;
|
||||
use keystore::KeyStorePtr;
|
||||
|
||||
type TaskExecutor = Arc<dyn futures::future::Executor<Box<dyn Future<Item = (), Error = ()> + Send>> + Send + Sync>;
|
||||
|
||||
@@ -145,7 +144,7 @@ pub trait Network {
|
||||
fn communication_for(
|
||||
&self,
|
||||
table: Arc<SharedTable>,
|
||||
authorities: &[SessionKey],
|
||||
authorities: &[ValidatorId],
|
||||
exit: exit_future::Exit,
|
||||
) -> Self::BuildTableRouter;
|
||||
}
|
||||
@@ -154,7 +153,7 @@ pub trait Network {
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct GroupInfo {
|
||||
/// Authorities meant to check validity of candidates.
|
||||
validity_guarantors: HashSet<SessionKey>,
|
||||
validity_guarantors: HashSet<ValidatorId>,
|
||||
/// Number of votes needed for validity.
|
||||
needed_validity: usize,
|
||||
}
|
||||
@@ -162,32 +161,32 @@ pub struct GroupInfo {
|
||||
/// Sign a table statement against a parent hash.
|
||||
/// The actual message signed is the encoded statement concatenated with the
|
||||
/// parent hash.
|
||||
pub fn sign_table_statement(statement: &Statement, key: &ed25519::Pair, parent_hash: &Hash) -> CollatorSignature {
|
||||
pub fn sign_table_statement(statement: &Statement, key: &ValidatorPair, parent_hash: &Hash) -> ValidatorSignature {
|
||||
// we sign using the primitive statement type because that's what the runtime
|
||||
// expects. These types probably encode the same way so this clone could be optimized
|
||||
// out in the future.
|
||||
let mut encoded = PrimitiveStatement::from(statement.clone()).encode();
|
||||
encoded.extend(parent_hash.as_ref());
|
||||
|
||||
key.sign(&encoded).into()
|
||||
key.sign(&encoded)
|
||||
}
|
||||
|
||||
/// Check signature on table statement.
|
||||
pub fn check_statement(statement: &Statement, signature: &CollatorSignature, signer: SessionKey, parent_hash: &Hash) -> bool {
|
||||
use runtime_primitives::traits::Verify;
|
||||
pub fn check_statement(statement: &Statement, signature: &ValidatorSignature, signer: ValidatorId, parent_hash: &Hash) -> bool {
|
||||
use runtime_primitives::traits::AppVerify;
|
||||
|
||||
let mut encoded = PrimitiveStatement::from(statement.clone()).encode();
|
||||
encoded.extend(parent_hash.as_ref());
|
||||
|
||||
signature.verify(&encoded[..], &signer.into())
|
||||
signature.verify(&encoded[..], &signer)
|
||||
}
|
||||
|
||||
/// Compute group info out of a duty roster and a local authority set.
|
||||
pub fn make_group_info(
|
||||
roster: DutyRoster,
|
||||
authorities: &[AuthorityId],
|
||||
local_id: AuthorityId,
|
||||
) -> Result<(HashMap<ParaId, GroupInfo>, LocalDuty), Error> {
|
||||
authorities: &[ValidatorId],
|
||||
local_id: Option<ValidatorId>,
|
||||
) -> Result<(HashMap<ParaId, GroupInfo>, Option<LocalDuty>), Error> {
|
||||
if roster.validator_duty.len() != authorities.len() {
|
||||
return Err(Error::InvalidDutyRosterLength {
|
||||
expected: authorities.len(),
|
||||
@@ -200,7 +199,7 @@ pub fn make_group_info(
|
||||
|
||||
let duty_iter = authorities.iter().zip(&roster.validator_duty);
|
||||
for (authority, v_duty) in duty_iter {
|
||||
if authority == &local_id {
|
||||
if Some(authority) == local_id.as_ref() {
|
||||
local_validation = Some(v_duty.clone());
|
||||
}
|
||||
|
||||
@@ -219,16 +218,24 @@ pub fn make_group_info(
|
||||
live_group.needed_validity = validity_len / 2 + validity_len % 2;
|
||||
}
|
||||
|
||||
match local_validation {
|
||||
Some(local_validation) => {
|
||||
let local_duty = LocalDuty {
|
||||
validation: local_validation,
|
||||
};
|
||||
|
||||
Ok((map, local_duty))
|
||||
}
|
||||
None => return Err(Error::NotValidator(local_id)),
|
||||
}
|
||||
let local_duty = local_validation.map(|v| LocalDuty {
|
||||
validation: v
|
||||
});
|
||||
|
||||
Ok((map, local_duty))
|
||||
|
||||
}
|
||||
|
||||
// finds the first key we are capable of signing with out of the given set of validators,
|
||||
// if any.
|
||||
fn signing_key(validators: &[ValidatorId], keystore: &KeyStorePtr) -> Option<Arc<ValidatorPair>> {
|
||||
let keystore = keystore.read();
|
||||
validators.iter()
|
||||
.find_map(|v| {
|
||||
keystore.key_pair::<ValidatorPair>(&v).ok()
|
||||
})
|
||||
.map(|pair| Arc::new(pair))
|
||||
}
|
||||
|
||||
/// Constructs parachain-agreement instances.
|
||||
@@ -252,7 +259,7 @@ impl<C, N, P> ParachainValidation<C, N, P> where
|
||||
C: Collators + Send + 'static,
|
||||
N: Network,
|
||||
P: ProvideRuntimeApi + HeaderBackend<Block> + BlockBody<Block> + Send + Sync + 'static,
|
||||
P::Api: ParachainHost<Block> + BlockBuilderApi<Block> + AuraApi<Block, AuraId>,
|
||||
P::Api: ParachainHost<Block> + BlockBuilderApi<Block>,
|
||||
<C::Collation as IntoFuture>::Future: Send + 'static,
|
||||
N::TableRouter: Send + 'static,
|
||||
<N::BuildTableRouter as IntoFuture>::Future: Send + 'static,
|
||||
@@ -268,7 +275,7 @@ impl<C, N, P> ParachainValidation<C, N, P> where
|
||||
&self,
|
||||
parent_hash: Hash,
|
||||
grandparent_hash: Hash,
|
||||
sign_with: Arc<ed25519::Pair>,
|
||||
keystore: &KeyStorePtr,
|
||||
max_block_data_size: Option<u64>,
|
||||
)
|
||||
-> Result<Arc<AttestationTracker>, Error>
|
||||
@@ -280,7 +287,8 @@ impl<C, N, P> ParachainValidation<C, N, P> where
|
||||
|
||||
let id = BlockId::hash(parent_hash);
|
||||
|
||||
let authorities = self.client.runtime_api().authorities(&id)?;
|
||||
let validators = self.client.runtime_api().validators(&id)?;
|
||||
let sign_with = signing_key(&validators[..], keystore);
|
||||
|
||||
// compute the parent candidates, if we know of them.
|
||||
// this will allow us to circulate outgoing messages to other peers as necessary.
|
||||
@@ -312,14 +320,14 @@ impl<C, N, P> ParachainValidation<C, N, P> where
|
||||
|
||||
let (group_info, local_duty) = make_group_info(
|
||||
duty_roster,
|
||||
&authorities,
|
||||
sign_with.public(),
|
||||
&validators,
|
||||
sign_with.as_ref().map(|k| k.public()),
|
||||
)?;
|
||||
|
||||
info!(
|
||||
"Starting parachain attestation session on top of parent {:?}. Local parachain duty is {:?}",
|
||||
parent_hash,
|
||||
local_duty.validation,
|
||||
local_duty,
|
||||
);
|
||||
|
||||
let active_parachains = self.client.runtime_api().active_parachains(&id)?;
|
||||
@@ -327,9 +335,9 @@ impl<C, N, P> ParachainValidation<C, N, P> where
|
||||
debug!(target: "validation", "Active parachains: {:?}", active_parachains);
|
||||
|
||||
let table = Arc::new(SharedTable::new(
|
||||
&authorities,
|
||||
validators.clone(),
|
||||
group_info,
|
||||
sign_with.clone(),
|
||||
sign_with,
|
||||
parent_hash,
|
||||
self.extrinsic_store.clone(),
|
||||
max_block_data_size,
|
||||
@@ -339,11 +347,11 @@ impl<C, N, P> ParachainValidation<C, N, P> where
|
||||
|
||||
let router = self.network.communication_for(
|
||||
table.clone(),
|
||||
&authorities,
|
||||
&validators,
|
||||
exit.clone(),
|
||||
);
|
||||
|
||||
if let Chain::Parachain(id) = local_duty.validation {
|
||||
if let Some(Chain::Parachain(id)) = local_duty.as_ref().map(|d| d.validation) {
|
||||
self.launch_work(parent_hash, id, router, max_block_data_size, exit);
|
||||
}
|
||||
|
||||
@@ -446,9 +454,9 @@ struct AttestationTracker {
|
||||
pub struct ProposerFactory<C, N, P, SC, TxApi: PoolChainApi> {
|
||||
parachain_validation: Arc<ParachainValidation<C, N, P>>,
|
||||
transaction_pool: Arc<Pool<TxApi>>,
|
||||
key: Arc<ed25519::Pair>,
|
||||
keystore: KeyStorePtr,
|
||||
_service_handle: ServiceHandle,
|
||||
aura_slot_duration: SlotDuration,
|
||||
babe_slot_duration: u64,
|
||||
_select_chain: SC,
|
||||
max_block_data_size: Option<u64>,
|
||||
}
|
||||
@@ -458,7 +466,7 @@ impl<C, N, P, SC, TxApi> ProposerFactory<C, N, P, SC, TxApi> where
|
||||
<C::Collation as IntoFuture>::Future: Send + 'static,
|
||||
P: BlockchainEvents<Block> + BlockBody<Block>,
|
||||
P: ProvideRuntimeApi + HeaderBackend<Block> + Send + Sync + 'static,
|
||||
P::Api: ParachainHost<Block> + BlockBuilderApi<Block> + AuraApi<Block, AuraId>,
|
||||
P::Api: ParachainHost<Block> + BlockBuilderApi<Block> + BabeApi<Block>,
|
||||
N: Network + Send + Sync + 'static,
|
||||
N::TableRouter: Send + 'static,
|
||||
<N::BuildTableRouter as IntoFuture>::Future: Send + 'static,
|
||||
@@ -473,9 +481,9 @@ impl<C, N, P, SC, TxApi> ProposerFactory<C, N, P, SC, TxApi> where
|
||||
collators: C,
|
||||
transaction_pool: Arc<Pool<TxApi>>,
|
||||
thread_pool: TaskExecutor,
|
||||
key: Arc<ed25519::Pair>,
|
||||
keystore: KeyStorePtr,
|
||||
extrinsic_store: ExtrinsicStore,
|
||||
aura_slot_duration: SlotDuration,
|
||||
babe_slot_duration: u64,
|
||||
max_block_data_size: Option<u64>,
|
||||
) -> Self {
|
||||
let parachain_validation = Arc::new(ParachainValidation {
|
||||
@@ -492,7 +500,7 @@ impl<C, N, P, SC, TxApi> ProposerFactory<C, N, P, SC, TxApi> where
|
||||
_select_chain.clone(),
|
||||
parachain_validation.clone(),
|
||||
thread_pool,
|
||||
key.clone(),
|
||||
keystore.clone(),
|
||||
extrinsic_store,
|
||||
max_block_data_size,
|
||||
);
|
||||
@@ -500,9 +508,9 @@ impl<C, N, P, SC, TxApi> ProposerFactory<C, N, P, SC, TxApi> where
|
||||
ProposerFactory {
|
||||
parachain_validation,
|
||||
transaction_pool,
|
||||
key,
|
||||
keystore,
|
||||
_service_handle: service_handle,
|
||||
aura_slot_duration,
|
||||
babe_slot_duration,
|
||||
_select_chain,
|
||||
max_block_data_size,
|
||||
}
|
||||
@@ -514,7 +522,7 @@ impl<C, N, P, SC, TxApi> consensus::Environment<Block> for ProposerFactory<C, N,
|
||||
N: Network,
|
||||
TxApi: PoolChainApi<Block=Block>,
|
||||
P: ProvideRuntimeApi + HeaderBackend<Block> + BlockBody<Block> + Send + Sync + 'static,
|
||||
P::Api: ParachainHost<Block> + BlockBuilderApi<Block> + AuraApi<Block, AuraId>,
|
||||
P::Api: ParachainHost<Block> + BlockBuilderApi<Block> + BabeApi<Block>,
|
||||
<C::Collation as IntoFuture>::Future: Send + 'static,
|
||||
N::TableRouter: Send + 'static,
|
||||
<N::BuildTableRouter as IntoFuture>::Future: Send + 'static,
|
||||
@@ -524,16 +532,16 @@ impl<C, N, P, SC, TxApi> consensus::Environment<Block> for ProposerFactory<C, N,
|
||||
type Error = Error;
|
||||
|
||||
fn init(
|
||||
&self,
|
||||
&mut self,
|
||||
parent_header: &Header,
|
||||
) -> Result<Self::Proposer, Error> {
|
||||
let parent_hash = parent_header.hash();
|
||||
let parent_id = BlockId::hash(parent_hash);
|
||||
let sign_with = self.key.clone();
|
||||
|
||||
let tracker = self.parachain_validation.get_or_instantiate(
|
||||
parent_hash,
|
||||
parent_header.parent_hash().clone(),
|
||||
sign_with,
|
||||
&self.keystore,
|
||||
self.max_block_data_size,
|
||||
)?;
|
||||
|
||||
@@ -544,12 +552,13 @@ impl<C, N, P, SC, TxApi> consensus::Environment<Block> for ProposerFactory<C, N,
|
||||
parent_id,
|
||||
parent_number: parent_header.number,
|
||||
transaction_pool: self.transaction_pool.clone(),
|
||||
slot_duration: self.aura_slot_duration,
|
||||
slot_duration: self.babe_slot_duration,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// The local duty of a validator.
|
||||
#[derive(Debug)]
|
||||
pub struct LocalDuty {
|
||||
validation: Chain,
|
||||
}
|
||||
@@ -564,7 +573,7 @@ pub struct Proposer<C: Send + Sync, TxApi: PoolChainApi> where
|
||||
parent_number: BlockNumber,
|
||||
tracker: Arc<AttestationTracker>,
|
||||
transaction_pool: Arc<Pool<TxApi>>,
|
||||
slot_duration: SlotDuration,
|
||||
slot_duration: u64,
|
||||
}
|
||||
|
||||
impl<C, TxApi> consensus::Proposer<Block> for Proposer<C, TxApi> where
|
||||
@@ -575,7 +584,7 @@ impl<C, TxApi> consensus::Proposer<Block> for Proposer<C, TxApi> where
|
||||
type Error = Error;
|
||||
type Create = Either<CreateProposal<C, TxApi>, future::Ready<Result<Block, Error>>>;
|
||||
|
||||
fn propose(&self,
|
||||
fn propose(&mut self,
|
||||
inherent_data: InherentData,
|
||||
inherent_digests: DigestFor<Block>,
|
||||
max_duration: Duration,
|
||||
@@ -589,7 +598,7 @@ impl<C, TxApi> consensus::Proposer<Block> for Proposer<C, TxApi> where
|
||||
let dynamic_inclusion = DynamicInclusion::new(
|
||||
self.tracker.table.num_parachains(),
|
||||
self.tracker.started,
|
||||
Duration::from_secs(self.slot_duration.get() / SLOT_DURATION_DENOMINATOR),
|
||||
Duration::from_millis(self.slot_duration / SLOT_DURATION_DENOMINATOR),
|
||||
);
|
||||
|
||||
let enough_candidates = dynamic_inclusion.acceptable_in(
|
||||
@@ -607,7 +616,7 @@ impl<C, TxApi> consensus::Proposer<Block> for Proposer<C, TxApi> where
|
||||
let delay_future = if current_timestamp >= believed_timestamp {
|
||||
None
|
||||
} else {
|
||||
Some(Delay::new(Duration::from_secs(current_timestamp - believed_timestamp)))
|
||||
Some(Delay::new(Duration::from_millis (current_timestamp - believed_timestamp)))
|
||||
};
|
||||
|
||||
let timing = ProposalTiming {
|
||||
@@ -638,8 +647,7 @@ impl<C, TxApi> consensus::Proposer<Block> for Proposer<C, TxApi> where
|
||||
fn current_timestamp() -> u64 {
|
||||
time::SystemTime::now().duration_since(time::UNIX_EPOCH)
|
||||
.expect("now always later than unix epoch; qed")
|
||||
.as_secs()
|
||||
.into()
|
||||
.as_millis() as u64
|
||||
}
|
||||
|
||||
struct ProposalTiming {
|
||||
@@ -811,17 +819,17 @@ impl<C, TxApi> futures03::Future for CreateProposal<C, TxApi> where
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use substrate_keyring::Ed25519Keyring;
|
||||
use substrate_keyring::Sr25519Keyring;
|
||||
|
||||
#[test]
|
||||
fn sign_and_check_statement() {
|
||||
let statement: Statement = GenericStatement::Valid([1; 32].into());
|
||||
let parent_hash = [2; 32].into();
|
||||
|
||||
let sig = sign_table_statement(&statement, &Ed25519Keyring::Alice.pair(), &parent_hash);
|
||||
let sig = sign_table_statement(&statement, &Sr25519Keyring::Alice.pair().into(), &parent_hash);
|
||||
|
||||
assert!(check_statement(&statement, &sig, Ed25519Keyring::Alice.into(), &parent_hash));
|
||||
assert!(!check_statement(&statement, &sig, Ed25519Keyring::Alice.into(), &[0xff; 32].into()));
|
||||
assert!(!check_statement(&statement, &sig, Ed25519Keyring::Bob.into(), &parent_hash));
|
||||
assert!(check_statement(&statement, &sig, Sr25519Keyring::Alice.public().into(), &parent_hash));
|
||||
assert!(!check_statement(&statement, &sig, Sr25519Keyring::Alice.public().into(), &[0xff; 32].into()));
|
||||
assert!(!check_statement(&statement, &sig, Sr25519Keyring::Bob.public().into(), &parent_hash));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,9 +22,10 @@ use std::sync::Arc;
|
||||
|
||||
use extrinsic_store::{Data, Store as ExtrinsicStore};
|
||||
use table::{self, Table, Context as TableContextTrait};
|
||||
use polkadot_primitives::{Block, BlockId, Hash, SessionKey};
|
||||
use polkadot_primitives::parachain::{Id as ParaId, Collation, Extrinsic, CandidateReceipt,
|
||||
AttestedCandidate, ParachainHost, PoVBlock, ValidatorIndex,
|
||||
use polkadot_primitives::{Block, BlockId, Hash};
|
||||
use polkadot_primitives::parachain::{
|
||||
Id as ParaId, Collation, Extrinsic, CandidateReceipt, ValidatorPair, ValidatorId,
|
||||
AttestedCandidate, ParachainHost, PoVBlock, ValidatorIndex
|
||||
};
|
||||
|
||||
use parking_lot::Mutex;
|
||||
@@ -34,7 +35,7 @@ use bitvec::bitvec;
|
||||
|
||||
use super::{GroupInfo, TableRouter};
|
||||
use self::includable::IncludabilitySender;
|
||||
use primitives::{ed25519, Pair};
|
||||
use primitives::Pair;
|
||||
use runtime_primitives::traits::ProvideRuntimeApi;
|
||||
|
||||
mod includable;
|
||||
@@ -45,14 +46,14 @@ pub use table::generic::Statement as GenericStatement;
|
||||
|
||||
struct TableContext {
|
||||
parent_hash: Hash,
|
||||
key: Arc<ed25519::Pair>,
|
||||
key: Option<Arc<ValidatorPair>>,
|
||||
groups: HashMap<ParaId, GroupInfo>,
|
||||
index_mapping: HashMap<ValidatorIndex, SessionKey>,
|
||||
validators: Vec<ValidatorId>,
|
||||
}
|
||||
|
||||
impl table::Context for TableContext {
|
||||
fn is_member_of(&self, authority: ValidatorIndex, group: &ParaId) -> bool {
|
||||
let key = match self.index_mapping.get(&authority) {
|
||||
let key = match self.validators.get(authority as usize) {
|
||||
Some(val) => val,
|
||||
None => return false,
|
||||
};
|
||||
@@ -66,28 +67,26 @@ impl table::Context for TableContext {
|
||||
}
|
||||
|
||||
impl TableContext {
|
||||
fn local_id(&self) -> SessionKey {
|
||||
self.key.public().into()
|
||||
fn local_id(&self) -> Option<ValidatorId> {
|
||||
self.key.as_ref().map(|k| k.public())
|
||||
}
|
||||
|
||||
fn local_index(&self) -> ValidatorIndex {
|
||||
let id = self.local_id();
|
||||
self
|
||||
.index_mapping
|
||||
.iter()
|
||||
.find(|(_, k)| k == &&id)
|
||||
.map(|(i, _)| *i)
|
||||
.unwrap()
|
||||
fn local_index(&self) -> Option<ValidatorIndex> {
|
||||
self.local_id().and_then(|id|
|
||||
self.validators
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_, k)| k == &&id)
|
||||
.map(|(i, _)| i as ValidatorIndex)
|
||||
)
|
||||
}
|
||||
|
||||
fn sign_statement(&self, statement: table::Statement) -> table::SignedStatement {
|
||||
let signature = crate::sign_table_statement(&statement, &self.key, &self.parent_hash).into();
|
||||
|
||||
table::SignedStatement {
|
||||
statement,
|
||||
signature,
|
||||
sender: self.local_index(),
|
||||
}
|
||||
fn sign_statement(&self, statement: table::Statement) -> Option<table::SignedStatement> {
|
||||
self.local_index().and_then(move |sender|
|
||||
self.key.as_ref()
|
||||
.map(|key| crate::sign_table_statement(&statement, key, &self.parent_hash).into())
|
||||
.map(move |signature| table::SignedStatement { statement, signature, sender })
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,15 +141,10 @@ impl SharedTableInner {
|
||||
) -> Option<ParachainWork<
|
||||
<R::FetchValidationProof as IntoFuture>::Future,
|
||||
>> {
|
||||
let summary = match self.table.import_statement(context, statement) {
|
||||
Some(summary) => summary,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
let summary = self.table.import_statement(context, statement)?;
|
||||
self.update_trackers(&summary.candidate, context);
|
||||
|
||||
let local_index = context.local_index();
|
||||
|
||||
let local_index = context.local_index()?;
|
||||
let para_member = context.is_member_of(local_index, &summary.group_id);
|
||||
|
||||
let digest = &summary.candidate;
|
||||
@@ -399,16 +393,15 @@ impl SharedTable {
|
||||
/// Provide the key to sign with, and the parent hash of the relay chain
|
||||
/// block being built.
|
||||
pub fn new(
|
||||
authorities: &[ed25519::Public],
|
||||
validators: Vec<ValidatorId>,
|
||||
groups: HashMap<ParaId, GroupInfo>,
|
||||
key: Arc<ed25519::Pair>,
|
||||
key: Option<Arc<ValidatorPair>>,
|
||||
parent_hash: Hash,
|
||||
extrinsic_store: ExtrinsicStore,
|
||||
max_block_data_size: Option<u64>,
|
||||
) -> Self {
|
||||
let index_mapping = authorities.iter().enumerate().map(|(i, k)| (i as ValidatorIndex, k.clone())).collect();
|
||||
Self {
|
||||
context: Arc::new(TableContext { groups, key, parent_hash, index_mapping, }),
|
||||
SharedTable {
|
||||
context: Arc::new(TableContext { groups, key, parent_hash, validators: validators.clone(), }),
|
||||
max_block_data_size,
|
||||
inner: Arc::new(Mutex::new(SharedTableInner {
|
||||
table: Table::default(),
|
||||
@@ -425,7 +418,7 @@ impl SharedTable {
|
||||
}
|
||||
|
||||
/// Get the local validator session key.
|
||||
pub fn session_key(&self) -> SessionKey {
|
||||
pub fn session_key(&self) -> Option<ValidatorId> {
|
||||
self.context.local_id()
|
||||
}
|
||||
|
||||
@@ -482,9 +475,10 @@ impl SharedTable {
|
||||
}).collect()
|
||||
}
|
||||
|
||||
/// Sign and import the result of candidate validation.
|
||||
/// Sign and import the result of candidate validation. Returns `None` if the table
|
||||
/// was instantiated without a local key.
|
||||
pub fn import_validated(&self, validated: Validated)
|
||||
-> SignedStatement
|
||||
-> Option<SignedStatement>
|
||||
{
|
||||
let digest = match validated.statement {
|
||||
GenericStatement::Candidate(ref c) => c.hash(),
|
||||
@@ -493,9 +487,11 @@ impl SharedTable {
|
||||
|
||||
let signed_statement = self.context.sign_statement(validated.statement);
|
||||
|
||||
let mut inner = self.inner.lock();
|
||||
inner.table.import_statement(&*self.context, signed_statement.clone());
|
||||
inner.validated.insert(digest, ValidationWork::Done(validated.result));
|
||||
if let Some(ref signed) = signed_statement {
|
||||
let mut inner = self.inner.lock();
|
||||
inner.table.import_statement(&*self.context, signed.clone());
|
||||
inner.validated.insert(digest, ValidationWork::Done(validated.result));
|
||||
}
|
||||
|
||||
signed_statement
|
||||
}
|
||||
@@ -576,15 +572,15 @@ impl SharedTable {
|
||||
}
|
||||
|
||||
/// Returns id of the validator corresponding to the given index.
|
||||
pub fn index_to_id(&self, index: ValidatorIndex) -> Option<SessionKey> {
|
||||
self.context.index_mapping.get(&index).cloned()
|
||||
pub fn index_to_id(&self, index: ValidatorIndex) -> Option<ValidatorId> {
|
||||
self.context.validators.get(index as usize).cloned()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use substrate_keyring::Ed25519Keyring;
|
||||
use substrate_keyring::Sr25519Keyring;
|
||||
use primitives::crypto::UncheckedInto;
|
||||
use polkadot_primitives::parachain::{BlockData, ConsolidatedIngress};
|
||||
use futures::future;
|
||||
@@ -617,11 +613,12 @@ mod tests {
|
||||
let para_id = ParaId::from(1);
|
||||
let parent_hash = Default::default();
|
||||
|
||||
let local_key = Arc::new(Ed25519Keyring::Alice.pair());
|
||||
let local_id = local_key.public();
|
||||
let local_key = Sr25519Keyring::Alice.pair();
|
||||
let local_id: ValidatorId = local_key.public().into();
|
||||
let local_key: Arc<ValidatorPair> = Arc::new(local_key.into());
|
||||
|
||||
let validity_other_key = Ed25519Keyring::Bob.pair();
|
||||
let validity_other = validity_other_key.public();
|
||||
let validity_other_key = Sr25519Keyring::Bob.pair();
|
||||
let validity_other: ValidatorId = validity_other_key.public().into();
|
||||
let validity_other_index = 1;
|
||||
|
||||
groups.insert(para_id, GroupInfo {
|
||||
@@ -630,9 +627,9 @@ mod tests {
|
||||
});
|
||||
|
||||
let shared_table = SharedTable::new(
|
||||
&[local_id, validity_other],
|
||||
[local_id, validity_other].to_vec(),
|
||||
groups,
|
||||
local_key.clone(),
|
||||
Some(local_key.clone()),
|
||||
parent_hash,
|
||||
ExtrinsicStore::new_in_memory(),
|
||||
None,
|
||||
@@ -651,7 +648,7 @@ mod tests {
|
||||
|
||||
let candidate_statement = GenericStatement::Candidate(candidate);
|
||||
|
||||
let signature = crate::sign_table_statement(&candidate_statement, &validity_other_key, &parent_hash);
|
||||
let signature = crate::sign_table_statement(&candidate_statement, &validity_other_key.into(), &parent_hash);
|
||||
let signed_statement = ::table::generic::SignedStatement {
|
||||
statement: candidate_statement,
|
||||
signature: signature.into(),
|
||||
@@ -671,11 +668,12 @@ mod tests {
|
||||
let para_id = ParaId::from(1);
|
||||
let parent_hash = Default::default();
|
||||
|
||||
let local_key = Arc::new(Ed25519Keyring::Alice.pair());
|
||||
let local_id = local_key.public();
|
||||
let local_key = Sr25519Keyring::Alice.pair();
|
||||
let local_id: ValidatorId = local_key.public().into();
|
||||
let local_key: Arc<ValidatorPair> = Arc::new(local_key.into());
|
||||
|
||||
let validity_other_key = Ed25519Keyring::Bob.pair();
|
||||
let validity_other = validity_other_key.public();
|
||||
let validity_other_key = Sr25519Keyring::Bob.pair();
|
||||
let validity_other: ValidatorId = validity_other_key.public().into();
|
||||
let validity_other_index = 1;
|
||||
|
||||
groups.insert(para_id, GroupInfo {
|
||||
@@ -684,9 +682,9 @@ mod tests {
|
||||
});
|
||||
|
||||
let shared_table = SharedTable::new(
|
||||
&[local_id, validity_other],
|
||||
[local_id, validity_other].to_vec(),
|
||||
groups,
|
||||
local_key.clone(),
|
||||
Some(local_key.clone()),
|
||||
parent_hash,
|
||||
ExtrinsicStore::new_in_memory(),
|
||||
None,
|
||||
@@ -705,7 +703,7 @@ mod tests {
|
||||
|
||||
let candidate_statement = GenericStatement::Candidate(candidate);
|
||||
|
||||
let signature = crate::sign_table_statement(&candidate_statement, &validity_other_key, &parent_hash);
|
||||
let signature = crate::sign_table_statement(&candidate_statement, &validity_other_key.into(), &parent_hash);
|
||||
let signed_statement = ::table::generic::SignedStatement {
|
||||
statement: candidate_statement,
|
||||
signature: signature.into(),
|
||||
@@ -806,11 +804,12 @@ mod tests {
|
||||
let para_id = ParaId::from(1);
|
||||
let parent_hash = Default::default();
|
||||
|
||||
let local_key = Arc::new(Ed25519Keyring::Alice.pair());
|
||||
let local_id = local_key.public();
|
||||
let local_key = Sr25519Keyring::Alice.pair();
|
||||
let local_id: ValidatorId = local_key.public().into();
|
||||
let local_key: Arc<ValidatorPair> = Arc::new(local_key.into());
|
||||
|
||||
let validity_other_key = Ed25519Keyring::Bob.pair();
|
||||
let validity_other = validity_other_key.public();
|
||||
let validity_other_key = Sr25519Keyring::Bob.pair();
|
||||
let validity_other: ValidatorId = validity_other_key.public().into();
|
||||
let validity_other_index = 1;
|
||||
|
||||
groups.insert(para_id, GroupInfo {
|
||||
@@ -819,9 +818,9 @@ mod tests {
|
||||
});
|
||||
|
||||
let shared_table = SharedTable::new(
|
||||
&[local_id, validity_other],
|
||||
[local_id, validity_other].to_vec(),
|
||||
groups,
|
||||
local_key.clone(),
|
||||
Some(local_key.clone()),
|
||||
parent_hash,
|
||||
ExtrinsicStore::new_in_memory(),
|
||||
None,
|
||||
@@ -841,7 +840,7 @@ mod tests {
|
||||
let hash = candidate.hash();
|
||||
let candidate_statement = GenericStatement::Candidate(candidate);
|
||||
|
||||
let signature = crate::sign_table_statement(&candidate_statement, &validity_other_key, &parent_hash);
|
||||
let signature = crate::sign_table_statement(&candidate_statement, &validity_other_key.into(), &parent_hash);
|
||||
let signed_statement = ::table::generic::SignedStatement {
|
||||
statement: candidate_statement,
|
||||
signature: signature.into(),
|
||||
@@ -872,11 +871,12 @@ mod tests {
|
||||
let extrinsic = Extrinsic { outgoing_messages: Vec::new() };
|
||||
let parent_hash = Default::default();
|
||||
|
||||
let local_key = Arc::new(Ed25519Keyring::Alice.pair());
|
||||
let local_id = local_key.public();
|
||||
let local_key = Sr25519Keyring::Alice.pair();
|
||||
let local_id: ValidatorId = local_key.public().into();
|
||||
let local_key: Arc<ValidatorPair> = Arc::new(local_key.into());
|
||||
|
||||
let validity_other_key = Ed25519Keyring::Bob.pair();
|
||||
let validity_other = validity_other_key.public();
|
||||
let validity_other_key = Sr25519Keyring::Bob.pair();
|
||||
let validity_other: ValidatorId = validity_other_key.public().into();
|
||||
|
||||
groups.insert(para_id, GroupInfo {
|
||||
validity_guarantors: [local_id.clone(), validity_other.clone()].iter().cloned().collect(),
|
||||
@@ -884,9 +884,9 @@ mod tests {
|
||||
});
|
||||
|
||||
let shared_table = SharedTable::new(
|
||||
&[local_id, validity_other],
|
||||
[local_id, validity_other].to_vec(),
|
||||
groups,
|
||||
local_key.clone(),
|
||||
Some(local_key.clone()),
|
||||
parent_hash,
|
||||
ExtrinsicStore::new_in_memory(),
|
||||
None,
|
||||
@@ -908,7 +908,7 @@ mod tests {
|
||||
candidate,
|
||||
pov_block,
|
||||
extrinsic,
|
||||
));
|
||||
)).unwrap();
|
||||
|
||||
assert!(shared_table.inner.lock().validated.get(&hash).expect("validation has started").is_done());
|
||||
|
||||
@@ -919,29 +919,4 @@ mod tests {
|
||||
|
||||
assert!(a.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn index_mapping_from_authorities() {
|
||||
let authorities_set: &[&[_]] = &[
|
||||
&[],
|
||||
&[Ed25519Keyring::Alice.pair().public()],
|
||||
&[Ed25519Keyring::Alice.pair().public(), Ed25519Keyring::Bob.pair().public()],
|
||||
&[Ed25519Keyring::Bob.pair().public(), Ed25519Keyring::Alice.pair().public()],
|
||||
&[Ed25519Keyring::Alice.pair().public(), Ed25519Keyring::Bob.pair().public(), Ed25519Keyring::Charlie.pair().public()],
|
||||
&[Ed25519Keyring::Charlie.pair().public(), Ed25519Keyring::Bob.pair().public(), Ed25519Keyring::Alice.pair().public()],
|
||||
];
|
||||
|
||||
for authorities in authorities_set {
|
||||
let shared_table = SharedTable::new(
|
||||
authorities,
|
||||
HashMap::new(),
|
||||
Arc::new(Ed25519Keyring::Alice.pair()),
|
||||
Default::default(),
|
||||
ExtrinsicStore::new_in_memory(),
|
||||
None,
|
||||
);
|
||||
let expected_mapping = authorities.iter().enumerate().map(|(i, k)| (i as ValidatorIndex, k.clone())).collect();
|
||||
assert_eq!(shared_table.context.index_mapping, expected_mapping);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user