Unverified Commit c12969e1 authored by Gav Wood's avatar Gav Wood Committed by GitHub
Browse files

Update to Substrate master (#176)



* Update to master

This introduces a new type `CollatorId`, currently just `SessionKey`
but which would forseeably change to its own thing. It seems to work
like this (despite there being a lot of the new-incompatible
`AccountId` replaced). No idea if it does anything sensible, though.

* Cleanups

* Fix tests

* Remove commented code

* Specify commit hash

* Remove commented code

* Correct version

* Update runtime/Cargo.toml
Co-Authored-By: default avatargavofyork <github@gavwood.com>

* PairT instead of _Pair

* Update lock file

* Remove rev causing upset
parent ae9dab2a
Pipeline #33096 passed with stages
in 13 minutes and 41 seconds
This diff is collapsed.
......@@ -64,8 +64,8 @@ use std::time::Duration;
use futures::{future, stream, Stream, Future, IntoFuture};
use client::BlockchainEvents;
use primitives::ed25519;
use polkadot_primitives::{AccountId, BlockId, SessionKey};
use primitives::{ed25519, Pair};
use polkadot_primitives::{BlockId, SessionKey};
use polkadot_primitives::parachain::{self, BlockData, DutyRoster, HeadData, ConsolidatedIngress, Message, Id as ParaId};
use polkadot_cli::{PolkadotService, CustomConfiguration, CoreApi, ParachainHost};
use polkadot_cli::{Worker, IntoExit, ProvideRuntimeApi};
......@@ -127,11 +127,6 @@ pub trait RelayChainContext {
fn unrouted_egress(&self, id: ParaId) -> Self::FutureEgress;
}
fn key_to_account_id(key: &ed25519::Pair) -> AccountId {
let pubkey_bytes: [u8; 32] = key.public().into();
pubkey_bytes.into()
}
/// Collate the necessary ingress queue using the given context.
pub fn collate_ingress<'a, R>(relay_context: R)
-> impl Future<Item=ConsolidatedIngress, Error=R::Error> + 'a
......@@ -195,7 +190,7 @@ pub fn collate<'a, R, P>(
let receipt = parachain::CandidateReceipt {
parachain_index: local_id,
collator: key_to_account_id(&*key),
collator: key.public(),
signature,
head_data,
balance_uploads: Vec::new(),
......@@ -253,7 +248,7 @@ impl<P, E> Worker for CollationNode<P, E> where
fn configuration(&self) -> CustomConfiguration {
let mut config = CustomConfiguration::default();
config.collating_for = Some((
key_to_account_id(&*self.key),
self.key.public(),
self.para_id.clone(),
));
config
......
......@@ -16,9 +16,8 @@
//! Bridge between the network and consensus service for getting collations to it.
use polkadot_primitives::{AccountId, Hash};
use polkadot_primitives::{parachain::CollatorId, Hash};
use polkadot_primitives::parachain::{Id as ParaId, Collation};
use futures::sync::oneshot;
use std::collections::hash_map::{HashMap, Entry};
......@@ -40,9 +39,9 @@ pub enum Role {
#[allow(dead_code)]
pub enum Action {
/// Disconnect the given collator.
Disconnect(AccountId),
Disconnect(CollatorId),
/// Give the collator a new role.
NewRole(AccountId, Role),
NewRole(CollatorId, Role),
}
struct CollationSlot {
......@@ -111,13 +110,13 @@ impl SlotEntries {
}
struct ParachainCollators {
primary: AccountId,
backup: Vec<AccountId>,
primary: CollatorId,
backup: Vec<CollatorId>,
}
/// Manages connected collators and role assignments from the perspective of a validator.
pub struct CollatorPool {
collators: HashMap<AccountId, ParaId>,
collators: HashMap<CollatorId, ParaId>,
parachain_collators: HashMap<ParaId, ParachainCollators>,
collations: HashMap<(Hash, ParaId), CollationSlot>,
}
......@@ -133,19 +132,19 @@ impl CollatorPool {
}
/// Call when a new collator is authenticated. Returns the role.
pub fn on_new_collator(&mut self, account_id: AccountId, para_id: ParaId) -> Role {
self.collators.insert(account_id.clone(), para_id);
pub fn on_new_collator(&mut self, collator_id: CollatorId, para_id: ParaId) -> Role {
self.collators.insert(collator_id.clone(), para_id);
match self.parachain_collators.entry(para_id) {
Entry::Vacant(vacant) => {
vacant.insert(ParachainCollators {
primary: account_id,
primary: collator_id,
backup: Vec::new(),
});
Role::Primary
},
Entry::Occupied(mut occupied) => {
occupied.get_mut().backup.push(account_id);
occupied.get_mut().backup.push(collator_id);
Role::Backup
}
......@@ -154,21 +153,21 @@ impl CollatorPool {
/// Called when a collator disconnects. If it was the primary, returns a new primary for that
/// parachain.
pub fn on_disconnect(&mut self, account_id: AccountId) -> Option<AccountId> {
self.collators.remove(&account_id).and_then(|para_id| match self.parachain_collators.entry(para_id) {
pub fn on_disconnect(&mut self, collator_id: CollatorId) -> Option<CollatorId> {
self.collators.remove(&collator_id).and_then(|para_id| match self.parachain_collators.entry(para_id) {
Entry::Vacant(_) => None,
Entry::Occupied(mut occ) => {
if occ.get().primary == account_id {
if occ.get().primary == collator_id {
if occ.get().backup.is_empty() {
occ.remove();
None
} else {
let mut collators = occ.get_mut();
collators.primary = collators.backup.pop().expect("backup non-empty; qed");
Some(collators.primary)
Some(collators.primary.clone())
}
} else {
let pos = occ.get().backup.iter().position(|a| a == &account_id)
let pos = occ.get().backup.iter().position(|a| a == &collator_id)
.expect("registered collator always present in backup if not primary; qed");
occ.get_mut().backup.remove(pos);
......@@ -181,8 +180,8 @@ impl CollatorPool {
/// Called when a collation is received.
/// The collator should be registered for the parachain of the collation as a precondition of this function.
/// The collation should have been checked for integrity of signature before passing to this function.
pub fn on_collation(&mut self, account_id: AccountId, relay_parent: Hash, collation: Collation) {
if let Some(para_id) = self.collators.get(&account_id) {
pub fn on_collation(&mut self, collator_id: CollatorId, relay_parent: Hash, collation: Collation) {
if let Some(para_id) = self.collators.get(&collator_id) {
debug_assert_eq!(para_id, &collation.receipt.parachain_index);
// TODO: punish if not primary?
......@@ -219,20 +218,20 @@ impl CollatorPool {
#[cfg(test)]
mod tests {
use super::*;
use substrate_primitives::crypto::UncheckedInto;
use polkadot_primitives::parachain::{CandidateReceipt, BlockData, HeadData};
use substrate_primitives::H512;
use futures::Future;
#[test]
fn disconnect_primary_gives_new_primary() {
let mut pool = CollatorPool::new();
let para_id: ParaId = 5.into();
let bad_primary = [0; 32].into();
let good_backup = [1; 32].into();
let bad_primary: CollatorId = [0; 32].unchecked_into();
let good_backup: CollatorId = [1; 32].unchecked_into();
assert_eq!(pool.on_new_collator(bad_primary, para_id.clone()), Role::Primary);
assert_eq!(pool.on_new_collator(good_backup, para_id.clone()), Role::Backup);
assert_eq!(pool.on_disconnect(bad_primary), Some(good_backup));
assert_eq!(pool.on_new_collator(bad_primary.clone(), para_id.clone()), Role::Primary);
assert_eq!(pool.on_new_collator(good_backup.clone(), para_id.clone()), Role::Backup);
assert_eq!(pool.on_disconnect(bad_primary), Some(good_backup.clone()));
assert_eq!(pool.on_disconnect(good_backup), None);
}
......@@ -240,11 +239,11 @@ mod tests {
fn disconnect_backup_removes_from_pool() {
let mut pool = CollatorPool::new();
let para_id: ParaId = 5.into();
let primary = [0; 32].into();
let backup = [1; 32].into();
let primary = [0; 32].unchecked_into();
let backup: CollatorId = [1; 32].unchecked_into();
assert_eq!(pool.on_new_collator(primary, para_id.clone()), Role::Primary);
assert_eq!(pool.on_new_collator(backup, para_id.clone()), Role::Backup);
assert_eq!(pool.on_new_collator(backup.clone(), para_id.clone()), Role::Backup);
assert_eq!(pool.on_disconnect(backup), None);
assert!(pool.parachain_collators.get(&para_id).unwrap().backup.is_empty());
}
......@@ -253,19 +252,19 @@ mod tests {
fn await_before_collation() {
let mut pool = CollatorPool::new();
let para_id: ParaId = 5.into();
let primary = [0; 32].into();
let primary: CollatorId = [0; 32].unchecked_into();
let relay_parent = [1; 32].into();
assert_eq!(pool.on_new_collator(primary, para_id.clone()), Role::Primary);
assert_eq!(pool.on_new_collator(primary.clone(), para_id.clone()), Role::Primary);
let (tx1, rx1) = oneshot::channel();
let (tx2, rx2) = oneshot::channel();
pool.await_collation(relay_parent, para_id, tx1);
pool.await_collation(relay_parent, para_id, tx2);
pool.on_collation(primary, relay_parent, Collation {
pool.on_collation(primary.clone(), relay_parent, Collation {
receipt: CandidateReceipt {
parachain_index: para_id,
collator: primary.into(),
signature: H512::from([2; 64]).into(),
signature: Default::default(),
head_data: HeadData(vec![1, 2, 3]),
balance_uploads: vec![],
egress_queue_roots: vec![],
......@@ -283,16 +282,16 @@ mod tests {
fn collate_before_await() {
let mut pool = CollatorPool::new();
let para_id: ParaId = 5.into();
let primary = [0; 32].into();
let primary: CollatorId = [0; 32].unchecked_into();
let relay_parent = [1; 32].into();
assert_eq!(pool.on_new_collator(primary, para_id.clone()), Role::Primary);
assert_eq!(pool.on_new_collator(primary.clone(), para_id.clone()), Role::Primary);
pool.on_collation(primary, relay_parent, Collation {
pool.on_collation(primary.clone(), relay_parent, Collation {
receipt: CandidateReceipt {
parachain_index: para_id,
collator: primary.into(),
signature: H512::from([2; 64]).into(),
collator: primary,
signature: Default::default(),
head_data: HeadData(vec![1, 2, 3]),
balance_uploads: vec![],
egress_queue_roots: vec![],
......
......@@ -128,7 +128,7 @@ impl MessageValidationData {
::polkadot_validation::check_statement(
&statement.statement,
&statement.signature,
statement.sender,
statement.sender.clone(),
relay_parent,
)
}
......
......@@ -54,13 +54,13 @@ pub mod gossip;
use codec::{Decode, Encode};
use futures::sync::oneshot;
use polkadot_primitives::{AccountId, Block, SessionKey, Hash, Header};
use polkadot_primitives::{Block, SessionKey, Hash, Header, parachain::CollatorId};
use polkadot_primitives::parachain::{Id as ParaId, BlockData, CandidateReceipt, Collation};
use substrate_network::{NodeIndex, RequestId, Context, Severity};
use substrate_network::{message, generic_message};
use substrate_network::specialization::NetworkSpecialization as Specialization;
use substrate_network::StatusMessage as GenericFullStatus;
use self::validation::{LiveValidationSessions, RecentSessionKeys, InsertedRecentKey};
use self::validation::{LiveValidationSessions, RecentValidatorIds, InsertedRecentKey};
use self::collator_pool::{CollatorPool, Role, Action};
use self::local_collations::LocalCollations;
......@@ -81,7 +81,7 @@ pub type NetworkService = ::substrate_network::Service<Block, PolkadotProtocol>;
/// Status of a Polkadot node.
#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
pub struct Status {
collating_for: Option<(AccountId, ParaId)>,
collating_for: Option<(CollatorId, ParaId)>,
}
struct BlockDataRequest {
......@@ -128,8 +128,8 @@ impl CollatorState {
}
struct PeerInfo {
collating_for: Option<(AccountId, ParaId)>,
validator_keys: RecentSessionKeys,
collating_for: Option<(CollatorId, ParaId)>,
validator_keys: RecentValidatorIds,
claimed_validator: bool,
collator_state: CollatorState,
}
......@@ -165,7 +165,7 @@ fn send_polkadot_message(ctx: &mut Context<Block>, to: NodeIndex, message: Messa
/// Polkadot protocol attachment for substrate.
pub struct PolkadotProtocol {
peers: HashMap<NodeIndex, PeerInfo>,
collating_for: Option<(AccountId, ParaId)>,
collating_for: Option<(CollatorId, ParaId)>,
collators: CollatorPool,
validators: HashMap<SessionKey, NodeIndex>,
local_collations: LocalCollations<Collation>,
......@@ -178,7 +178,7 @@ pub struct PolkadotProtocol {
impl PolkadotProtocol {
/// Instantiate a polkadot protocol handler.
pub fn new(collating_for: Option<(AccountId, ParaId)>) -> Self {
pub fn new(collating_for: Option<(CollatorId, ParaId)>) -> Self {
PolkadotProtocol {
peers: HashMap::new(),
collators: CollatorPool::new(),
......@@ -220,7 +220,7 @@ impl PolkadotProtocol {
for (id, peer_data) in self.peers.iter_mut()
.filter(|&(_, ref info)| info.should_send_key())
{
peer_data.collator_state.send_key(new_local, |msg| send_polkadot_message(
peer_data.collator_state.send_key(new_local.clone(), |msg| send_polkadot_message(
ctx,
*id,
msg
......@@ -251,8 +251,8 @@ impl PolkadotProtocol {
}
Err(Some(known_keys)) => {
let next_peer = known_keys.iter()
.filter_map(|x| validator_keys.get(x).map(|id| (*x, *id)))
.find(|&(ref key, _)| pending.attempted_peers.insert(*key))
.filter_map(|x| validator_keys.get(x).map(|id| (x.clone(), *id)))
.find(|&(ref key, _)| pending.attempted_peers.insert(key.clone()))
.map(|(_, id)| id);
// dispatch to peer
......@@ -323,14 +323,14 @@ impl PolkadotProtocol {
}
let local_collations = &mut self.local_collations;
let new_collations = match info.validator_keys.insert(key) {
let new_collations = match info.validator_keys.insert(key.clone()) {
InsertedRecentKey::AlreadyKnown => Vec::new(),
InsertedRecentKey::New(Some(old_key)) => {
self.validators.remove(&old_key);
local_collations.fresh_key(&old_key, &key)
}
InsertedRecentKey::New(None) => info.collator_state.role()
.map(|r| local_collations.note_validator_role(key, r))
.map(|r| local_collations.note_validator_role(key.clone(), r))
.unwrap_or_else(Vec::new),
};
......@@ -418,7 +418,7 @@ impl Specialization<Block> for PolkadotProtocol {
let validator = status.roles.contains(substrate_network::config::Roles::AUTHORITY);
let mut peer_info = PeerInfo {
collating_for: local_status.collating_for,
collating_for: local_status.collating_for.clone(),
validator_keys: Default::default(),
claimed_validator: validator,
collator_state: CollatorState::Fresh,
......@@ -442,7 +442,7 @@ impl Specialization<Block> for PolkadotProtocol {
// send session keys.
if peer_info.should_send_key() {
for local_session_key in self.live_validation_sessions.recent_keys() {
peer_info.collator_state.send_key(*local_session_key, |msg| send_polkadot_message(
peer_info.collator_state.send_key(local_session_key.clone(), |msg| send_polkadot_message(
ctx,
who,
msg,
......@@ -544,7 +544,7 @@ impl PolkadotProtocol {
// we received a collation from a peer
fn on_collation(&mut self, ctx: &mut Context<Block>, from: NodeIndex, relay_parent: Hash, collation: Collation) {
let collation_para = collation.receipt.parachain_index;
let collated_acc = collation.receipt.collator;
let collated_acc = collation.receipt.collator.clone();
match self.peers.get(&from) {
None => ctx.report_peer(from, Severity::Useless("Unknown Polkadot specific reason".to_string())),
......@@ -571,11 +571,11 @@ impl PolkadotProtocol {
}
// get connected peer with given account ID for collation.
fn collator_peer(&mut self, account_id: AccountId) -> Option<(NodeIndex, &mut PeerInfo)> {
fn collator_peer(&mut self, collator_id: CollatorId) -> Option<(NodeIndex, &mut PeerInfo)> {
let check_info = |info: &PeerInfo| info
.collating_for
.as_ref()
.map_or(false, |&(ref acc_id, _)| acc_id == &account_id);
.map_or(false, |&(ref acc_id, _)| acc_id == &collator_id);
self.peers
.iter_mut()
......@@ -585,8 +585,8 @@ impl PolkadotProtocol {
}
// disconnect a collator by account-id.
fn disconnect_bad_collator(&mut self, ctx: &mut Context<Block>, account_id: AccountId) {
if let Some((who, _)) = self.collator_peer(account_id) {
fn disconnect_bad_collator(&mut self, ctx: &mut Context<Block>, collator_id: CollatorId) {
if let Some((who, _)) = self.collator_peer(collator_id) {
ctx.report_peer(who, Severity::Bad("Consensus layer determined the given collator misbehaved".to_string()))
}
}
......
......@@ -58,7 +58,7 @@ impl<C: Clone> LocalCollations<C> {
Vec::new()
}
Role::Primary => {
let new_primary = self.primary_for.insert(key);
let new_primary = self.primary_for.insert(key.clone());
if new_primary {
self.collations_targeting(&key)
} else {
......@@ -72,7 +72,7 @@ impl<C: Clone> LocalCollations<C> {
/// to the validator.
pub fn fresh_key(&mut self, old_key: &SessionKey, new_key: &SessionKey) -> Vec<(Hash, C)> {
if self.primary_for.remove(old_key) {
self.primary_for.insert(*new_key);
self.primary_for.insert(new_key.clone());
self.collations_targeting(new_key)
} else {
......@@ -116,7 +116,7 @@ impl<C: Clone> LocalCollations<C> {
let borrowed_collation = &local.collation;
local.targets
.intersection(&self.primary_for)
.map(move |k| (*k, borrowed_collation.clone()))
.map(move |k| (k.clone(), borrowed_collation.clone()))
}
fn collations_targeting(&self, key: &SessionKey) -> Vec<(Hash, C)> {
......@@ -130,14 +130,16 @@ impl<C: Clone> LocalCollations<C> {
#[cfg(test)]
mod tests {
use super::*;
use substrate_primitives::crypto::UncheckedInto;
use polkadot_primitives::parachain::ValidatorId;
#[test]
fn add_validator_with_ready_collation() {
let key = [1; 32].into();
let key: ValidatorId = [1; 32].unchecked_into();
let relay_parent = [2; 32].into();
let targets = {
let mut set = HashSet::new();
set.insert(key);
set.insert(key.clone());
set
};
......@@ -148,18 +150,18 @@ mod tests {
#[test]
fn rename_with_ready() {
let orig_key = [1; 32].into();
let new_key = [2; 32].into();
let orig_key: ValidatorId = [1; 32].unchecked_into();
let new_key: ValidatorId = [2; 32].unchecked_into();
let relay_parent = [255; 32].into();
let targets = {
let mut set = HashSet::new();
set.insert(new_key);
set.insert(new_key.clone());
set
};
let mut tracker: LocalCollations<u8> = LocalCollations::new();
assert!(tracker.add_collation(relay_parent, targets, 5).next().is_none());
assert!(tracker.note_validator_role(orig_key, Role::Primary).is_empty());
assert!(tracker.note_validator_role(orig_key.clone(), Role::Primary).is_empty());
assert_eq!(tracker.fresh_key(&orig_key, &new_key), vec![(relay_parent, 5u8)]);
}
......@@ -183,16 +185,16 @@ mod tests {
#[test]
fn add_collation_with_connected_target() {
let key = [1; 32].into();
let key: ValidatorId = [1; 32].unchecked_into();
let relay_parent = [2; 32].into();
let targets = {
let mut set = HashSet::new();
set.insert(key);
set.insert(key.clone());
set
};
let mut tracker = LocalCollations::new();
assert!(tracker.note_validator_role(key, Role::Primary).is_empty());
assert!(tracker.note_validator_role(key.clone(), Role::Primary).is_empty());
assert_eq!(tracker.add_collation(relay_parent, targets, 5).next(), Some((key, 5)));
}
......
......@@ -426,8 +426,8 @@ impl DeferredStatements {
fn push(&mut self, statement: SignedStatement) {
let (hash, trace) = match statement.statement {
GenericStatement::Candidate(_) => return,
GenericStatement::Valid(hash) => (hash, StatementTrace::Valid(statement.sender, hash)),
GenericStatement::Invalid(hash) => (hash, StatementTrace::Invalid(statement.sender, hash)),
GenericStatement::Valid(hash) => (hash, StatementTrace::Valid(statement.sender.clone(), hash)),
GenericStatement::Invalid(hash) => (hash, StatementTrace::Invalid(statement.sender.clone(), hash)),
};
if self.known_traces.insert(trace) {
......@@ -443,8 +443,8 @@ impl DeferredStatements {
for statement in deferred.iter() {
let trace = match statement.statement {
GenericStatement::Candidate(_) => continue,
GenericStatement::Valid(hash) => StatementTrace::Valid(statement.sender, hash),
GenericStatement::Invalid(hash) => StatementTrace::Invalid(statement.sender, hash),
GenericStatement::Valid(hash) => StatementTrace::Valid(statement.sender.clone(), hash),
GenericStatement::Invalid(hash) => StatementTrace::Invalid(statement.sender.clone(), hash),
};
self.known_traces.remove(&trace);
......@@ -512,19 +512,20 @@ impl<S> Future for ComputeIngress<S> where S: Stream<Item=IngressPair> {
#[cfg(test)]
mod tests {
use super::*;
use substrate_primitives::H512;
use substrate_primitives::crypto::UncheckedInto;
use futures::stream;
use polkadot_primitives::parachain::ValidatorId;
#[test]
fn deferred_statements_works() {
let mut deferred = DeferredStatements::new();
let hash = [1; 32].into();
let sig = H512::from([2; 64]).into();
let sender = [255; 32].into();
let sig = Default::default();
let sender: ValidatorId = [255; 32].unchecked_into();
let statement = SignedStatement {
statement: GenericStatement::Valid(hash),
sender,
sender: sender.clone(),
signature: sig,
};
......
......@@ -22,8 +22,8 @@ use validation::{ValidationSession, Knowledge};
use parking_lot::Mutex;
use polkadot_validation::GenericStatement;
use polkadot_primitives::{Block, SessionKey};
use polkadot_primitives::parachain::{CandidateReceipt, HeadData, BlockData};
use substrate_primitives::H512;
use polkadot_primitives::parachain::{CandidateReceipt, HeadData, BlockData, CollatorId, ValidatorId};
use substrate_primitives::crypto::UncheckedInto;
use codec::Encode;
use substrate_network::{
Severity, NodeIndex, PeerInfo, ClientHandle, Context, config::Roles,
......@@ -107,10 +107,10 @@ fn sends_session_key() {
let peer_a = 1;
let peer_b = 2;
let parent_hash = [0; 32].into();
let local_key = [1; 32].into();
let local_key: ValidatorId = [1; 32].unchecked_into();
let validator_status = Status { collating_for: None };
let collator_status = Status { collating_for: Some(([2; 32].into(), 5.into())) };
let collator_status = Status { collating_for: Some(([2; 32].unchecked_into(), 5.into())) };
{
let mut ctx = TestContext::default();
......@@ -120,9 +120,9 @@ fn sends_session_key() {
{
let mut ctx = TestContext::default();
let (session, _knowledge) = make_validation_session(local_key);
let (session, _knowledge) = make_validation_session(local_key.clone());
protocol.new_validation_session(&mut ctx, parent_hash, session);
assert!(ctx.has_message(peer_a, Message::SessionKey(local_key)));
assert!(ctx.has_message(peer_a, Message::SessionKey(local_key.clone())));
}
{
......@@ -139,15 +139,15 @@ fn fetches_from_those_with_knowledge() {
let peer_a = 1;
let peer_b = 2;
let parent_hash = [0; 32].into();
let local_key = [1; 32].into();
let local_key: ValidatorId = [1; 32].unchecked_into();
let block_data = BlockData(vec![1, 2, 3, 4]);
let block_data_hash = block_data.hash();
let candidate_receipt = CandidateReceipt {
parachain_index: 5.into(),
collator: [255; 32].into(),
collator: [255; 32].unchecked_into(),
head_data: HeadData(vec![9, 9, 9]),
signature: H512::from([1; 64]).into(),
signature: Default::default(),
balance_uploads: Vec::new(),
egress_queue_roots: Vec::new(),
fees: 1_000_000,
......@@ -155,15 +155,15 @@ fn fetches_from_those_with_knowledge() {
};
let candidate_hash = candidate_receipt.hash();
let a_key = [3; 32].into();
let b_key = [4; 32].into();
let a_key: ValidatorId = [3; 32].unchecked_into();
let b_key: ValidatorId = [4; 32].unchecked_into();
let status = Status { collating_for: None };
let (session, knowledge) = make_validation_session(local_key);
let (session, knowledge) = make_validation_session(local_key.clone());
protocol.new_validation_session(&mut TestContext::default(), parent_hash, session);
knowledge.lock().note_statement(a_key, &GenericStatement::Valid(candidate_hash));
knowledge.lock().note_statement(a_key.clone(), &GenericStatement::Valid(candidate_hash));
let recv = protocol.fetch_block_data(&mut TestContext::default(), &candidate_receipt, parent_hash);
// connect peer A
......@@ -176,12 +176,12 @@ fn fetches_from_those_with_knowledge() {
// peer A gives session key and gets asked for data.
{
let mut ctx = TestContext::default();
on_message(&mut protocol, &mut ctx, peer_a, Message::SessionKey(a_key));
on_message(&mut protocol, &mut ctx, peer_a, Message::SessionKey(a_key.clone()));
assert!(protocol.validators.contains_key(&a_key));
assert!(ctx.has_message(peer_a, Message::RequestBlockData(1, parent_hash, candidate_hash)));
}