mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-21 05:05:41 +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:
@@ -16,7 +16,7 @@
|
||||
|
||||
//! Bridge between the network and consensus service for getting collations to it.
|
||||
|
||||
use parity_codec::{Encode, Decode};
|
||||
use codec::{Encode, Decode};
|
||||
use polkadot_primitives::Hash;
|
||||
use polkadot_primitives::parachain::{CollatorId, Id as ParaId, Collation};
|
||||
use substrate_network::PeerId;
|
||||
|
||||
@@ -22,8 +22,8 @@ use substrate_network::consensus_gossip::{
|
||||
ValidatorContext, MessageIntent, ConsensusMessage,
|
||||
};
|
||||
use polkadot_validation::{GenericStatement, SignedStatement};
|
||||
use polkadot_primitives::{Block, Hash, SessionKey, parachain::ValidatorIndex};
|
||||
use parity_codec::{Decode, Encode};
|
||||
use polkadot_primitives::{Block, Hash, parachain::{ValidatorIndex, ValidatorId}};
|
||||
use codec::{Decode, Encode};
|
||||
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::sync::Arc;
|
||||
@@ -218,9 +218,9 @@ impl RegisteredMessageValidator {
|
||||
#[derive(Default)]
|
||||
pub(crate) struct MessageValidationData {
|
||||
/// The authorities at a block.
|
||||
pub(crate) authorities: Vec<SessionKey>,
|
||||
/// Mapping from validator index to `SessionKey`.
|
||||
pub(crate) index_mapping: HashMap<ValidatorIndex, SessionKey>,
|
||||
pub(crate) authorities: Vec<ValidatorId>,
|
||||
/// Mapping from validator index to `ValidatorId`.
|
||||
pub(crate) index_mapping: HashMap<ValidatorIndex, ValidatorId>,
|
||||
}
|
||||
|
||||
impl MessageValidationData {
|
||||
@@ -481,15 +481,15 @@ impl<O: KnownOracle + ?Sized> network_gossip::Validator<Block> for MessageValida
|
||||
-> GossipValidationResult<Hash>
|
||||
{
|
||||
let (res, cost_benefit) = match GossipMessage::decode(&mut data) {
|
||||
None => (GossipValidationResult::Discard, cost::MALFORMED_MESSAGE),
|
||||
Some(GossipMessage::Neighbor(VersionedNeighborPacket::V1(packet))) => {
|
||||
Err(_) => (GossipValidationResult::Discard, cost::MALFORMED_MESSAGE),
|
||||
Ok(GossipMessage::Neighbor(VersionedNeighborPacket::V1(packet))) => {
|
||||
let (res, cb, topics) = self.inner.write().validate_neighbor_packet(sender, packet);
|
||||
for new_topic in topics {
|
||||
context.send_topic(sender, new_topic, false);
|
||||
}
|
||||
(res, cb)
|
||||
}
|
||||
Some(GossipMessage::Statement(statement)) => {
|
||||
Ok(GossipMessage::Statement(statement)) => {
|
||||
let (res, cb) = self.inner.write().validate_statement(statement);
|
||||
if let GossipValidationResult::ProcessAndKeep(ref topic) = res {
|
||||
context.broadcast_message(topic.clone(), data.to_vec(), false);
|
||||
@@ -535,7 +535,7 @@ impl<O: KnownOracle + ?Sized> network_gossip::Validator<Block> for MessageValida
|
||||
};
|
||||
|
||||
match GossipMessage::decode(&mut &data[..]) {
|
||||
Some(GossipMessage::Statement(statement)) => {
|
||||
Ok(GossipMessage::Statement(statement)) => {
|
||||
let signed = statement.signed_statement;
|
||||
|
||||
match signed.statement {
|
||||
@@ -573,7 +573,7 @@ mod tests {
|
||||
use parking_lot::Mutex;
|
||||
use polkadot_primitives::parachain::{CandidateReceipt, HeadData};
|
||||
use substrate_primitives::crypto::UncheckedInto;
|
||||
use substrate_primitives::ed25519::Signature as Ed25519Signature;
|
||||
use substrate_primitives::sr25519::Signature as Sr25519Signature;
|
||||
|
||||
#[derive(PartialEq, Clone, Debug)]
|
||||
enum ContextEvent {
|
||||
@@ -669,7 +669,7 @@ mod tests {
|
||||
relay_parent: hash_a,
|
||||
signed_statement: SignedStatement {
|
||||
statement: GenericStatement::Candidate(candidate_receipt),
|
||||
signature: Ed25519Signature([255u8; 64]),
|
||||
signature: Sr25519Signature([255u8; 64]).into(),
|
||||
sender: 1,
|
||||
}
|
||||
});
|
||||
@@ -786,7 +786,7 @@ mod tests {
|
||||
relay_parent: hash_a,
|
||||
signed_statement: SignedStatement {
|
||||
statement: GenericStatement::Valid(c_hash),
|
||||
signature: Ed25519Signature([255u8; 64]),
|
||||
signature: Sr25519Signature([255u8; 64]).into(),
|
||||
sender: 1,
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,265 +0,0 @@
|
||||
// Copyright 2019 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/>.
|
||||
|
||||
//! Data structures and synchronous logic for ICMP message gossip.
|
||||
|
||||
use sr_primitives::traits::{BlakeTwo256, Hash as HashT};
|
||||
use polkadot_primitives::Hash;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use substrate_client::error::Error as ClientError;
|
||||
use super::{MAX_CHAIN_HEADS, GossipValidationResult, LeavesVec, ChainContext};
|
||||
|
||||
/// Construct a topic for a message queue root deterministically.
|
||||
pub fn queue_topic(queue_root: Hash) -> Hash {
|
||||
let mut v = queue_root.as_ref().to_vec();
|
||||
v.extend(b"message_queue");
|
||||
|
||||
BlakeTwo256::hash(&v[..])
|
||||
}
|
||||
|
||||
/// A view of which queue roots are current for a given set of leaves.
|
||||
#[derive(Default)]
|
||||
pub struct View {
|
||||
leaves: LeavesVec,
|
||||
leaf_topics: HashMap<Hash, HashSet<Hash>>, // leaf_hash -> { topics }
|
||||
expected_queues: HashMap<Hash, Hash>, // topic -> queue-root
|
||||
}
|
||||
|
||||
impl View {
|
||||
/// Update the set of current leaves.
|
||||
pub fn update_leaves<T: ChainContext + ?Sized, I>(&mut self, context: &T, new_leaves: I)
|
||||
-> Result<(), ClientError>
|
||||
where I: Iterator<Item=Hash>
|
||||
{
|
||||
let new_leaves = new_leaves.take(MAX_CHAIN_HEADS);
|
||||
let old_leaves = {
|
||||
let mut new = LeavesVec::new();
|
||||
for leaf in new_leaves {
|
||||
new.push(leaf.clone());
|
||||
}
|
||||
|
||||
std::mem::replace(&mut self.leaves, new)
|
||||
};
|
||||
|
||||
let expected_queues = &mut self.expected_queues;
|
||||
let leaves = &self.leaves;
|
||||
self.leaf_topics.retain(|l, topics| {
|
||||
if leaves.contains(l) { return true }
|
||||
|
||||
// prune out all data about old leaves we don't follow anymore.
|
||||
for topic in topics.iter() {
|
||||
expected_queues.remove(topic);
|
||||
}
|
||||
false
|
||||
});
|
||||
|
||||
let mut res = Ok(());
|
||||
|
||||
// add in new data about fresh leaves.
|
||||
for new_leaf in &self.leaves {
|
||||
if old_leaves.contains(new_leaf) { continue }
|
||||
|
||||
let mut this_leaf_topics = HashSet::new();
|
||||
|
||||
let r = context.leaf_unrouted_roots(new_leaf, &mut |&queue_root| {
|
||||
let topic = queue_topic(queue_root);
|
||||
this_leaf_topics.insert(topic);
|
||||
expected_queues.insert(topic, queue_root);
|
||||
});
|
||||
|
||||
if r.is_err() {
|
||||
res = r;
|
||||
}
|
||||
|
||||
self.leaf_topics.insert(*new_leaf, this_leaf_topics);
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
/// Validate an incoming message queue against this view.
|
||||
pub fn validate_queue(&self, messages: &super::GossipParachainMessages)
|
||||
-> (GossipValidationResult<Hash>, i32)
|
||||
{
|
||||
let ostensible_topic = queue_topic(messages.queue_root);
|
||||
if !self.is_topic_live(&ostensible_topic) {
|
||||
(GossipValidationResult::Discard, super::cost::UNNEEDED_ICMP_MESSAGES)
|
||||
} else if !messages.queue_root_is_correct() {
|
||||
(
|
||||
GossipValidationResult::Discard,
|
||||
super::cost::icmp_messages_root_mismatch(messages.messages.len()),
|
||||
)
|
||||
} else {
|
||||
(
|
||||
GossipValidationResult::ProcessAndKeep(ostensible_topic),
|
||||
super::benefit::NEW_ICMP_MESSAGES,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether a message with given topic is live.
|
||||
pub fn is_topic_live(&self, topic: &Hash) -> bool {
|
||||
self.expected_queues.get(topic).is_some()
|
||||
}
|
||||
|
||||
/// Whether a message is allowed under the intersection of the given leaf-set
|
||||
/// and our own.
|
||||
pub fn allowed_intersecting(&self, other_leaves: &LeavesVec, topic: &Hash) -> bool {
|
||||
for i in other_leaves {
|
||||
for j in &self.leaves {
|
||||
if i == j {
|
||||
let leaf_topics = self.leaf_topics.get(i)
|
||||
.expect("leaf_topics are mutated only in update_leaves; \
|
||||
we have an entry for each item in self.leaves; \
|
||||
i is in self.leaves; qed");
|
||||
|
||||
if leaf_topics.contains(topic) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::tests::TestChainContext;
|
||||
use crate::gossip::{Known, GossipParachainMessages};
|
||||
use polkadot_primitives::parachain::Message as ParachainMessage;
|
||||
|
||||
fn hash(x: u8) -> Hash {
|
||||
[x; 32].into()
|
||||
}
|
||||
|
||||
fn message_queue(from: u8, to: u8) -> Option<[[u8; 2]; 1]> {
|
||||
if from == to {
|
||||
None
|
||||
} else {
|
||||
Some([[from, to]])
|
||||
}
|
||||
}
|
||||
|
||||
fn message_queue_root(from: u8, to: u8) -> Option<Hash> {
|
||||
message_queue(from, to).map(
|
||||
|q| polkadot_validation::message_queue_root(q.iter())
|
||||
)
|
||||
}
|
||||
|
||||
fn check_roots(view: &View, i: u8, max: u8) -> bool {
|
||||
for j in 0..max {
|
||||
if let Some(messages) = message_queue(i, j) {
|
||||
let queue_root = message_queue_root(i, j).unwrap();
|
||||
let messages = GossipParachainMessages {
|
||||
queue_root,
|
||||
messages: messages.iter().map(|m| ParachainMessage(m.to_vec())).collect(),
|
||||
};
|
||||
|
||||
match view.validate_queue(&messages).0 {
|
||||
GossipValidationResult::ProcessAndKeep(topic) => if topic != queue_topic(queue_root) {
|
||||
return false
|
||||
},
|
||||
_ => return false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_leaves_none_in_common() {
|
||||
let mut ctx = TestChainContext::default();
|
||||
let max = 5;
|
||||
|
||||
for i in 0..max {
|
||||
ctx.known_map.insert(hash(i as u8), Known::Leaf);
|
||||
|
||||
let messages_out: Vec<_> = (0..max).filter_map(|j| message_queue_root(i, j)).collect();
|
||||
|
||||
if !messages_out.is_empty() {
|
||||
ctx.ingress_roots.insert(hash(i as u8), messages_out);
|
||||
}
|
||||
}
|
||||
|
||||
let mut view = View::default();
|
||||
view.update_leaves(
|
||||
&ctx,
|
||||
[hash(0), hash(1)].iter().cloned(),
|
||||
).unwrap();
|
||||
|
||||
assert!(check_roots(&view, 0, max));
|
||||
assert!(check_roots(&view, 1, max));
|
||||
|
||||
assert!(!check_roots(&view, 2, max));
|
||||
assert!(!check_roots(&view, 3, max));
|
||||
assert!(!check_roots(&view, 4, max));
|
||||
assert!(!check_roots(&view, 5, max));
|
||||
|
||||
view.update_leaves(
|
||||
&ctx,
|
||||
[hash(2), hash(3), hash(4)].iter().cloned(),
|
||||
).unwrap();
|
||||
|
||||
assert!(!check_roots(&view, 0, max));
|
||||
assert!(!check_roots(&view, 1, max));
|
||||
|
||||
assert!(check_roots(&view, 2, max));
|
||||
assert!(check_roots(&view, 3, max));
|
||||
assert!(check_roots(&view, 4, max));
|
||||
|
||||
assert!(!check_roots(&view, 5, max));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_leaves_overlapping() {
|
||||
let mut ctx = TestChainContext::default();
|
||||
let max = 5;
|
||||
|
||||
for i in 0..max {
|
||||
ctx.known_map.insert(hash(i as u8), Known::Leaf);
|
||||
|
||||
let messages_out: Vec<_> = (0..max).filter_map(|j| message_queue_root(i, j)).collect();
|
||||
|
||||
if !messages_out.is_empty() {
|
||||
ctx.ingress_roots.insert(hash(i as u8), messages_out);
|
||||
}
|
||||
}
|
||||
|
||||
let mut view = View::default();
|
||||
view.update_leaves(
|
||||
&ctx,
|
||||
[hash(0), hash(1), hash(2)].iter().cloned(),
|
||||
).unwrap();
|
||||
|
||||
view.update_leaves(
|
||||
&ctx,
|
||||
[hash(2), hash(3), hash(4)].iter().cloned(),
|
||||
).unwrap();
|
||||
|
||||
assert!(!check_roots(&view, 0, max));
|
||||
assert!(!check_roots(&view, 1, max));
|
||||
|
||||
assert!(check_roots(&view, 2, max));
|
||||
assert!(check_roots(&view, 3, max));
|
||||
assert!(check_roots(&view, 4, max));
|
||||
|
||||
assert!(!check_roots(&view, 5, max));
|
||||
}
|
||||
}
|
||||
+15
-19
@@ -25,12 +25,12 @@ mod router;
|
||||
pub mod validation;
|
||||
pub mod gossip;
|
||||
|
||||
use parity_codec::{Decode, Encode};
|
||||
use codec::{Decode, Encode};
|
||||
use futures::sync::oneshot;
|
||||
use polkadot_primitives::{Block, SessionKey, Hash, Header};
|
||||
use polkadot_primitives::{Block, Hash, Header};
|
||||
use polkadot_primitives::parachain::{
|
||||
Id as ParaId, BlockData, CollatorId, CandidateReceipt, Collation, PoVBlock,
|
||||
StructuredUnroutedIngress,
|
||||
StructuredUnroutedIngress, ValidatorId
|
||||
};
|
||||
use substrate_network::{
|
||||
PeerId, RequestId, Context, StatusMessage as GenericFullStatus,
|
||||
@@ -78,7 +78,7 @@ pub struct Status {
|
||||
}
|
||||
|
||||
struct PoVBlockRequest {
|
||||
attempted_peers: HashSet<SessionKey>,
|
||||
attempted_peers: HashSet<ValidatorId>,
|
||||
validation_session_parent: Hash,
|
||||
candidate_hash: Hash,
|
||||
block_data_hash: Hash,
|
||||
@@ -115,8 +115,8 @@ enum CollatorState {
|
||||
}
|
||||
|
||||
impl CollatorState {
|
||||
fn send_key<F: FnMut(Message)>(&mut self, key: SessionKey, mut f: F) {
|
||||
f(Message::SessionKey(key));
|
||||
fn send_key<F: FnMut(Message)>(&mut self, key: ValidatorId, mut f: F) {
|
||||
f(Message::ValidatorId(key));
|
||||
if let CollatorState::RolePending(role) = *self {
|
||||
f(Message::CollatorRole(role));
|
||||
*self = CollatorState::Primed(Some(role));
|
||||
@@ -160,7 +160,7 @@ pub enum Message {
|
||||
/// As a validator, tell the peer your current session key.
|
||||
// TODO: do this with a cryptographic proof of some kind
|
||||
// https://github.com/paritytech/polkadot/issues/47
|
||||
SessionKey(SessionKey),
|
||||
ValidatorId(ValidatorId),
|
||||
/// Requesting parachain proof-of-validation block (relay_parent, candidate_hash).
|
||||
RequestPovBlock(RequestId, Hash, Hash),
|
||||
/// Provide requested proof-of-validation block data by candidate hash or nothing if unknown.
|
||||
@@ -186,7 +186,7 @@ pub struct PolkadotProtocol {
|
||||
peers: HashMap<PeerId, PeerInfo>,
|
||||
collating_for: Option<(CollatorId, ParaId)>,
|
||||
collators: CollatorPool,
|
||||
validators: HashMap<SessionKey, PeerId>,
|
||||
validators: HashMap<ValidatorId, PeerId>,
|
||||
local_collations: LocalCollations<Collation>,
|
||||
live_validation_sessions: LiveValidationSessions,
|
||||
in_flight: HashMap<(RequestId, PeerId), PoVBlockRequest>,
|
||||
@@ -319,7 +319,7 @@ impl PolkadotProtocol {
|
||||
fn on_polkadot_message(&mut self, ctx: &mut dyn Context<Block>, who: PeerId, msg: Message) {
|
||||
trace!(target: "p_net", "Polkadot message from {}: {:?}", who, msg);
|
||||
match msg {
|
||||
Message::SessionKey(key) => self.on_session_key(ctx, who, key),
|
||||
Message::ValidatorId(key) => self.on_session_key(ctx, who, key),
|
||||
Message::RequestPovBlock(req_id, relay_parent, candidate_hash) => {
|
||||
let pov_block = self.live_validation_sessions.with_pov_block(
|
||||
&relay_parent,
|
||||
@@ -352,7 +352,7 @@ impl PolkadotProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
fn on_session_key(&mut self, ctx: &mut dyn Context<Block>, who: PeerId, key: SessionKey) {
|
||||
fn on_session_key(&mut self, ctx: &mut dyn Context<Block>, who: PeerId, key: ValidatorId) {
|
||||
{
|
||||
let info = match self.peers.get_mut(&who) {
|
||||
Some(peer) => peer,
|
||||
@@ -473,12 +473,8 @@ impl Specialization<Block> for PolkadotProtocol {
|
||||
}
|
||||
|
||||
fn on_connect(&mut self, ctx: &mut dyn Context<Block>, who: PeerId, status: FullStatus) {
|
||||
let local_status = match Status::decode(&mut &status.chain_status[..]) {
|
||||
Some(status) => status,
|
||||
None => {
|
||||
Status { collating_for: None }
|
||||
}
|
||||
};
|
||||
let local_status = Status::decode(&mut &status.chain_status[..])
|
||||
.unwrap_or_else(|_| Status { collating_for: None });
|
||||
|
||||
let validator = status.roles.contains(substrate_network::config::Roles::AUTHORITY);
|
||||
|
||||
@@ -575,11 +571,11 @@ impl Specialization<Block> for PolkadotProtocol {
|
||||
message: Vec<u8>,
|
||||
) {
|
||||
match Message::decode(&mut &message[..]) {
|
||||
Some(msg) => {
|
||||
Ok(msg) => {
|
||||
ctx.report_peer(who.clone(), benefit::VALID_FORMAT);
|
||||
self.on_polkadot_message(ctx, who, msg)
|
||||
},
|
||||
None => {
|
||||
Err(_) => {
|
||||
trace!(target: "p_net", "Bad message from {}", who);
|
||||
ctx.report_peer(who, cost::INVALID_FORMAT);
|
||||
}
|
||||
@@ -684,7 +680,7 @@ impl PolkadotProtocol {
|
||||
&mut self,
|
||||
ctx: &mut dyn Context<Block>,
|
||||
relay_parent: Hash,
|
||||
targets: HashSet<SessionKey>,
|
||||
targets: HashSet<ValidatorId>,
|
||||
collation: Collation,
|
||||
) {
|
||||
debug!(target: "p_net", "Importing local collation on relay parent {:?} and parachain {:?}",
|
||||
|
||||
@@ -19,24 +19,22 @@
|
||||
//! Collations are attempted to be repropagated when a new validator connects,
|
||||
//! a validator changes his session key, or when they are generated.
|
||||
|
||||
use polkadot_primitives::{Hash, SessionKey};
|
||||
|
||||
use polkadot_primitives::{Hash, parachain::{ValidatorId}};
|
||||
use crate::collator_pool::Role;
|
||||
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
const LIVE_FOR: Duration = Duration::from_secs(60 * 5);
|
||||
|
||||
struct LocalCollation<C> {
|
||||
targets: HashSet<SessionKey>,
|
||||
targets: HashSet<ValidatorId>,
|
||||
collation: C,
|
||||
live_since: Instant,
|
||||
}
|
||||
|
||||
/// Tracker for locally collated values and which validators to send them to.
|
||||
pub struct LocalCollations<C> {
|
||||
primary_for: HashSet<SessionKey>,
|
||||
primary_for: HashSet<ValidatorId>,
|
||||
local_collations: HashMap<Hash, LocalCollation<C>>,
|
||||
}
|
||||
|
||||
@@ -51,7 +49,7 @@ impl<C: Clone> LocalCollations<C> {
|
||||
|
||||
/// Validator gave us a new role. If the new role is "primary", this function might return
|
||||
/// a set of collations to send to that validator.
|
||||
pub fn note_validator_role(&mut self, key: SessionKey, role: Role) -> Vec<(Hash, C)> {
|
||||
pub fn note_validator_role(&mut self, key: ValidatorId, role: Role) -> Vec<(Hash, C)> {
|
||||
match role {
|
||||
Role::Backup => {
|
||||
self.primary_for.remove(&key);
|
||||
@@ -70,7 +68,7 @@ impl<C: Clone> LocalCollations<C> {
|
||||
|
||||
/// Fresh session key from a validator. Returns a vector of collations to send
|
||||
/// to the validator.
|
||||
pub fn fresh_key(&mut self, old_key: &SessionKey, new_key: &SessionKey) -> Vec<(Hash, C)> {
|
||||
pub fn fresh_key(&mut self, old_key: &ValidatorId, new_key: &ValidatorId) -> Vec<(Hash, C)> {
|
||||
if self.primary_for.remove(old_key) {
|
||||
self.primary_for.insert(new_key.clone());
|
||||
|
||||
@@ -81,7 +79,7 @@ impl<C: Clone> LocalCollations<C> {
|
||||
}
|
||||
|
||||
/// Validator disconnected.
|
||||
pub fn on_disconnect(&mut self, key: &SessionKey) {
|
||||
pub fn on_disconnect(&mut self, key: &ValidatorId) {
|
||||
self.primary_for.remove(key);
|
||||
}
|
||||
|
||||
@@ -99,10 +97,10 @@ impl<C: Clone> LocalCollations<C> {
|
||||
pub fn add_collation<'a>(
|
||||
&'a mut self,
|
||||
relay_parent: Hash,
|
||||
targets: HashSet<SessionKey>,
|
||||
targets: HashSet<ValidatorId>,
|
||||
collation: C
|
||||
)
|
||||
-> impl Iterator<Item=(SessionKey, C)> + 'a
|
||||
-> impl Iterator<Item=(ValidatorId, C)> + 'a
|
||||
{
|
||||
self.local_collations.insert(relay_parent, LocalCollation {
|
||||
targets,
|
||||
@@ -119,7 +117,7 @@ impl<C: Clone> LocalCollations<C> {
|
||||
.map(move |k| (k.clone(), borrowed_collation.clone()))
|
||||
}
|
||||
|
||||
fn collations_targeting(&self, key: &SessionKey) -> Vec<(Hash, C)> {
|
||||
fn collations_targeting(&self, key: &ValidatorId) -> Vec<(Hash, C)> {
|
||||
self.local_collations.iter()
|
||||
.filter(|&(_, ref v)| v.targets.contains(key))
|
||||
.map(|(h, v)| (*h, v.collation.clone()))
|
||||
|
||||
@@ -199,13 +199,16 @@ impl<P: ProvideRuntimeApi + Send + Sync + 'static, E, N, T> Router<P, E, N, T> w
|
||||
validated.extrinsic().cloned(),
|
||||
);
|
||||
|
||||
|
||||
// propagate the statement.
|
||||
// consider something more targeted than gossip in the future.
|
||||
let statement = GossipStatement::new(
|
||||
parent_hash,
|
||||
table.import_validated(validated),
|
||||
match table.import_validated(validated) {
|
||||
None => return,
|
||||
Some(s) => s,
|
||||
}
|
||||
);
|
||||
|
||||
network.gossip_message(attestation_topic, statement.into());
|
||||
})
|
||||
.map_err(|e| debug!(target: "p_net", "Failed to produce statements: {:?}", e))
|
||||
@@ -224,10 +227,18 @@ impl<P: ProvideRuntimeApi + Send, E, N, T> TableRouter for Router<P, E, N, T> wh
|
||||
fn local_collation(&self, collation: Collation, extrinsic: Extrinsic) {
|
||||
// produce a signed statement
|
||||
let hash = collation.receipt.hash();
|
||||
let validated = Validated::collated_local(collation.receipt, collation.pov.clone(), extrinsic.clone());
|
||||
let validated = Validated::collated_local(
|
||||
collation.receipt,
|
||||
collation.pov.clone(),
|
||||
extrinsic.clone(),
|
||||
);
|
||||
|
||||
let statement = GossipStatement::new(
|
||||
self.parent_hash(),
|
||||
self.table.import_validated(validated),
|
||||
match self.table.import_validated(validated) {
|
||||
None => return,
|
||||
Some(s) => s,
|
||||
},
|
||||
);
|
||||
|
||||
// give to network to make available.
|
||||
|
||||
@@ -21,13 +21,13 @@ use super::{PolkadotProtocol, Status, Message, FullStatus};
|
||||
use crate::validation::SessionParams;
|
||||
|
||||
use polkadot_validation::GenericStatement;
|
||||
use polkadot_primitives::{Block, Hash, SessionKey};
|
||||
use polkadot_primitives::{Block, Hash};
|
||||
use polkadot_primitives::parachain::{
|
||||
CandidateReceipt, HeadData, PoVBlock, BlockData, CollatorId, ValidatorId,
|
||||
StructuredUnroutedIngress,
|
||||
StructuredUnroutedIngress
|
||||
};
|
||||
use substrate_primitives::crypto::UncheckedInto;
|
||||
use parity_codec::Encode;
|
||||
use codec::Encode;
|
||||
use substrate_network::{
|
||||
PeerId, Context, config::Roles, message::generic::ConsensusMessage,
|
||||
specialization::NetworkSpecialization,
|
||||
@@ -96,7 +96,7 @@ fn make_status(status: &Status, roles: Roles) -> FullStatus {
|
||||
}
|
||||
}
|
||||
|
||||
fn make_validation_session(parent_hash: Hash, local_key: SessionKey) -> SessionParams {
|
||||
fn make_validation_session(parent_hash: Hash, local_key: ValidatorId) -> SessionParams {
|
||||
SessionParams {
|
||||
local_session_key: Some(local_key),
|
||||
parent_hash,
|
||||
@@ -131,13 +131,13 @@ fn sends_session_key() {
|
||||
let mut ctx = TestContext::default();
|
||||
let params = make_validation_session(parent_hash, local_key.clone());
|
||||
protocol.new_validation_session(&mut ctx, params);
|
||||
assert!(ctx.has_message(peer_a, Message::SessionKey(local_key.clone())));
|
||||
assert!(ctx.has_message(peer_a, Message::ValidatorId(local_key.clone())));
|
||||
}
|
||||
|
||||
{
|
||||
let mut ctx = TestContext::default();
|
||||
protocol.on_connect(&mut ctx, peer_b.clone(), make_status(&collator_status, Roles::NONE));
|
||||
assert!(ctx.has_message(peer_b.clone(), Message::SessionKey(local_key)));
|
||||
assert!(ctx.has_message(peer_b.clone(), Message::ValidatorId(local_key)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,13 +186,13 @@ fn fetches_from_those_with_knowledge() {
|
||||
{
|
||||
let mut ctx = TestContext::default();
|
||||
protocol.on_connect(&mut ctx, peer_a.clone(), make_status(&status, Roles::AUTHORITY));
|
||||
assert!(ctx.has_message(peer_a.clone(), Message::SessionKey(local_key)));
|
||||
assert!(ctx.has_message(peer_a.clone(), Message::ValidatorId(local_key)));
|
||||
}
|
||||
|
||||
// peer A gives session key and gets asked for data.
|
||||
{
|
||||
let mut ctx = TestContext::default();
|
||||
on_message(&mut protocol, &mut ctx, peer_a.clone(), Message::SessionKey(a_key.clone()));
|
||||
on_message(&mut protocol, &mut ctx, peer_a.clone(), Message::ValidatorId(a_key.clone()));
|
||||
assert!(protocol.validators.contains_key(&a_key));
|
||||
assert!(ctx.has_message(peer_a.clone(), Message::RequestPovBlock(1, parent_hash, candidate_hash)));
|
||||
}
|
||||
@@ -203,7 +203,7 @@ fn fetches_from_those_with_knowledge() {
|
||||
{
|
||||
let mut ctx = TestContext::default();
|
||||
protocol.on_connect(&mut ctx, peer_b.clone(), make_status(&status, Roles::AUTHORITY));
|
||||
on_message(&mut protocol, &mut ctx, peer_b.clone(), Message::SessionKey(b_key.clone()));
|
||||
on_message(&mut protocol, &mut ctx, peer_b.clone(), Message::ValidatorId(b_key.clone()));
|
||||
assert!(!ctx.has_message(peer_b.clone(), Message::RequestPovBlock(2, parent_hash, candidate_hash)));
|
||||
|
||||
}
|
||||
@@ -340,8 +340,8 @@ fn many_session_keys() {
|
||||
let status = Status { collating_for: None };
|
||||
protocol.on_connect(&mut ctx, peer_a.clone(), make_status(&status, Roles::AUTHORITY));
|
||||
|
||||
assert!(ctx.has_message(peer_a.clone(), Message::SessionKey(local_key_a.clone())));
|
||||
assert!(ctx.has_message(peer_a, Message::SessionKey(local_key_b.clone())));
|
||||
assert!(ctx.has_message(peer_a.clone(), Message::ValidatorId(local_key_a.clone())));
|
||||
assert!(ctx.has_message(peer_a, Message::ValidatorId(local_key_b.clone())));
|
||||
}
|
||||
|
||||
let peer_b = PeerId::random();
|
||||
@@ -354,7 +354,7 @@ fn many_session_keys() {
|
||||
let status = Status { collating_for: None };
|
||||
protocol.on_connect(&mut ctx, peer_b.clone(), make_status(&status, Roles::AUTHORITY));
|
||||
|
||||
assert!(!ctx.has_message(peer_b.clone(), Message::SessionKey(local_key_a.clone())));
|
||||
assert!(ctx.has_message(peer_b, Message::SessionKey(local_key_b.clone())));
|
||||
assert!(!ctx.has_message(peer_b.clone(), Message::ValidatorId(local_key_a.clone())));
|
||||
assert!(ctx.has_message(peer_b, Message::ValidatorId(local_key_b.clone())));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,11 +23,11 @@ use crate::gossip::GossipMessage;
|
||||
use substrate_network::Context as NetContext;
|
||||
use substrate_network::consensus_gossip::TopicNotification;
|
||||
use substrate_primitives::{NativeOrEncoded, ExecutionContext};
|
||||
use substrate_keyring::Ed25519Keyring;
|
||||
use substrate_keyring::Sr25519Keyring;
|
||||
use crate::PolkadotProtocol;
|
||||
|
||||
use polkadot_validation::{SharedTable, MessagesFrom, Network};
|
||||
use polkadot_primitives::{SessionKey, Block, Hash, Header, BlockId};
|
||||
use polkadot_primitives::{Block, Hash, Header, BlockId};
|
||||
use polkadot_primitives::parachain::{
|
||||
Id as ParaId, Chain, DutyRoster, ParachainHost, OutgoingMessage,
|
||||
ValidatorId, StructuredUnroutedIngress, BlockIngressRoots, Status,
|
||||
@@ -41,7 +41,7 @@ use sr_primitives::traits::{ApiRef, ProvideRuntimeApi};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use futures::{prelude::*, sync::mpsc};
|
||||
use parity_codec::Encode;
|
||||
use codec::Encode;
|
||||
|
||||
use super::TestContext;
|
||||
|
||||
@@ -398,20 +398,23 @@ impl IngressBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
fn make_table(data: &ApiData, local_key: &Ed25519Keyring, parent_hash: Hash) -> Arc<SharedTable> {
|
||||
fn make_table(data: &ApiData, local_key: &Sr25519Keyring, parent_hash: Hash) -> Arc<SharedTable> {
|
||||
use av_store::Store;
|
||||
use substrate_primitives::crypto::Pair;
|
||||
|
||||
let sr_pair = local_key.pair();
|
||||
let local_key = polkadot_primitives::parachain::ValidatorPair::from(local_key.pair());
|
||||
let store = Store::new_in_memory();
|
||||
let (group_info, _) = ::polkadot_validation::make_group_info(
|
||||
DutyRoster { validator_duty: data.duties.clone() },
|
||||
&data.validators, // only possible as long as parachain crypto === aura crypto
|
||||
SessionKey::from(*local_key)
|
||||
Some(sr_pair.public().into()),
|
||||
).unwrap();
|
||||
|
||||
Arc::new(SharedTable::new(
|
||||
data.validators.as_slice(),
|
||||
data.validators.clone(),
|
||||
group_info,
|
||||
Arc::new(local_key.pair()),
|
||||
Some(Arc::new(local_key)),
|
||||
parent_hash,
|
||||
store,
|
||||
None,
|
||||
|
||||
@@ -28,10 +28,10 @@ use substrate_network::consensus_gossip::{
|
||||
use polkadot_validation::{
|
||||
Network as ParachainNetwork, SharedTable, Collators, Statement, GenericStatement, SignedStatement,
|
||||
};
|
||||
use polkadot_primitives::{Block, BlockId, Hash, SessionKey};
|
||||
use polkadot_primitives::{Block, BlockId, Hash};
|
||||
use polkadot_primitives::parachain::{
|
||||
Id as ParaId, Collation, Extrinsic, ParachainHost, CandidateReceipt, CollatorId,
|
||||
ValidatorId, PoVBlock, ValidatorIndex,
|
||||
ValidatorId, PoVBlock, ValidatorIndex
|
||||
};
|
||||
|
||||
use futures::prelude::*;
|
||||
@@ -54,7 +54,7 @@ use super::PolkadotProtocol;
|
||||
|
||||
pub use polkadot_validation::Incoming;
|
||||
|
||||
use parity_codec::{Encode, Decode};
|
||||
use codec::{Encode, Decode};
|
||||
|
||||
/// An executor suitable for dispatching async consensus tasks.
|
||||
pub trait Executor {
|
||||
@@ -120,7 +120,7 @@ impl Stream for GossipMessageStream {
|
||||
};
|
||||
|
||||
debug!(target: "validation", "Processing statement for live validation session");
|
||||
if let Some(gmsg) = GossipMessage::decode(&mut &msg.message[..]) {
|
||||
if let Ok(gmsg) = GossipMessage::decode(&mut &msg.message[..]) {
|
||||
return Ok(Async::Ready(Some((gmsg, msg.sender))))
|
||||
}
|
||||
}
|
||||
@@ -186,11 +186,11 @@ impl NetworkService for super::NetworkService {
|
||||
/// Params to a current validation session.
|
||||
pub struct SessionParams {
|
||||
/// The local session key.
|
||||
pub local_session_key: Option<SessionKey>,
|
||||
pub local_session_key: Option<ValidatorId>,
|
||||
/// The parent hash.
|
||||
pub parent_hash: Hash,
|
||||
/// The authorities.
|
||||
pub authorities: Vec<SessionKey>,
|
||||
pub authorities: Vec<ValidatorId>,
|
||||
}
|
||||
|
||||
/// Wrapper around the network service
|
||||
@@ -336,7 +336,7 @@ impl<P, E, N, T> ParachainNetwork for ValidationNetwork<P, E, N, T> where
|
||||
let local_session_key = table.session_key();
|
||||
|
||||
let build_fetcher = self.instantiate_session(SessionParams {
|
||||
local_session_key: Some(local_session_key),
|
||||
local_session_key,
|
||||
parent_hash,
|
||||
authorities: authorities.to_vec(),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user