Allow many attestation instances to live at once in network (#46)

* multiple consensus sessions in network

* tests compile, add a test for RecentSessionKeys

* track recently received session keys from validators

* add a test for desired key-sending behavior
This commit is contained in:
Robert Habermeier
2018-11-28 15:14:06 +01:00
committed by Gav Wood
parent 7b46856159
commit e008813f8b
6 changed files with 437 additions and 156 deletions
+55 -12
View File
@@ -16,11 +16,12 @@
//! Tests for polkadot and consensus network.
use super::{PolkadotProtocol, Status, CurrentConsensus, Knowledge, Message, FullStatus};
use super::{PolkadotProtocol, Status, Message, FullStatus};
use consensus::{CurrentConsensus, Knowledge};
use parking_lot::Mutex;
use polkadot_consensus::GenericStatement;
use polkadot_primitives::{Block, Hash, SessionKey};
use polkadot_primitives::{Block, SessionKey};
use polkadot_primitives::parachain::{CandidateReceipt, HeadData, BlockData};
use substrate_primitives::H512;
use codec::Encode;
@@ -84,13 +85,9 @@ fn make_status(status: &Status, roles: Roles) -> FullStatus {
}
}
fn make_consensus(parent_hash: Hash, local_key: SessionKey) -> (CurrentConsensus, Arc<Mutex<Knowledge>>) {
fn make_consensus(local_key: SessionKey) -> (CurrentConsensus, Arc<Mutex<Knowledge>>) {
let knowledge = Arc::new(Mutex::new(Knowledge::new()));
let c = CurrentConsensus {
knowledge: knowledge.clone(),
parent_hash,
local_session_key: local_key,
};
let c = CurrentConsensus::new(knowledge.clone(), local_key);
(c, knowledge)
}
@@ -120,8 +117,8 @@ fn sends_session_key() {
{
let mut ctx = TestContext::default();
let (consensus, _knowledge) = make_consensus(parent_hash, local_key);
protocol.new_consensus(&mut ctx, consensus);
let (consensus, _knowledge) = make_consensus(local_key);
protocol.new_consensus(&mut ctx, parent_hash, consensus);
assert!(ctx.has_message(peer_a, Message::SessionKey(local_key)));
}
@@ -160,8 +157,8 @@ fn fetches_from_those_with_knowledge() {
let status = Status { collating_for: None };
let (consensus, knowledge) = make_consensus(parent_hash, local_key);
protocol.new_consensus(&mut TestContext::default(), consensus);
let (consensus, knowledge) = make_consensus(local_key);
protocol.new_consensus(&mut TestContext::default(), parent_hash, consensus);
knowledge.lock().note_statement(a_key, &GenericStatement::Valid(candidate_hash));
let recv = protocol.fetch_block_data(&mut TestContext::default(), &candidate_receipt, parent_hash);
@@ -279,3 +276,49 @@ fn remove_bad_collator() {
assert!(ctx.disabled.contains(&who));
}
}
#[test]
fn many_session_keys() {
let mut protocol = PolkadotProtocol::new(None);
let parent_a = [1; 32].into();
let parent_b = [2; 32].into();
let local_key_a = [3; 32].into();
let local_key_b = [4; 32].into();
let (consensus_a, _knowledge_a) = make_consensus(local_key_a);
let (consensus_b, _knowledge_b) = make_consensus(local_key_b);
protocol.new_consensus(&mut TestContext::default(), parent_a, consensus_a);
protocol.new_consensus(&mut TestContext::default(), parent_b, consensus_b);
assert_eq!(protocol.live_consensus.recent_keys(), &[local_key_a, local_key_b]);
let peer_a = 1;
// when connecting a peer, we should get both those keys.
{
let mut ctx = TestContext::default();
let status = Status { collating_for: None };
protocol.on_connect(&mut ctx, peer_a, make_status(&status, Roles::AUTHORITY));
assert!(ctx.has_message(peer_a, Message::SessionKey(local_key_a)));
assert!(ctx.has_message(peer_a, Message::SessionKey(local_key_b)));
}
let peer_b = 2;
protocol.remove_consensus(&parent_a);
{
let mut ctx = TestContext::default();
let status = Status { collating_for: None };
protocol.on_connect(&mut ctx, peer_b, make_status(&status, Roles::AUTHORITY));
assert!(!ctx.has_message(peer_b, Message::SessionKey(local_key_a)));
assert!(ctx.has_message(peer_b, Message::SessionKey(local_key_b)));
}
}