diff --git a/polkadot/node/collation-generation/src/lib.rs b/polkadot/node/collation-generation/src/lib.rs
index e1893b6fb1..c52dcc846c 100644
--- a/polkadot/node/collation-generation/src/lib.rs
+++ b/polkadot/node/collation-generation/src/lib.rs
@@ -49,6 +49,9 @@ use std::sync::Arc;
mod error;
+#[cfg(test)]
+mod tests;
+
const LOG_TARGET: &'static str = "parachain::collation-generation";
/// Collation Generation Subsystem
@@ -506,6 +509,3 @@ impl metrics::Metrics for Metrics {
Ok(Metrics(Some(metrics)))
}
}
-
-#[cfg(test)]
-mod tests;
diff --git a/polkadot/node/collation-generation/src/tests.rs b/polkadot/node/collation-generation/src/tests.rs
index 7f13205c52..8c663e7f7b 100644
--- a/polkadot/node/collation-generation/src/tests.rs
+++ b/polkadot/node/collation-generation/src/tests.rs
@@ -15,358 +15,358 @@
// along with Polkadot. If not, see .
mod handle_new_activations {
- use super::super::*;
- use futures::{
- lock::Mutex,
- task::{Context as FuturesContext, Poll},
- Future,
- };
- use polkadot_node_primitives::{Collation, CollationResult, BlockData, PoV, POV_BOMB_LIMIT};
- use polkadot_node_subsystem::messages::{
- AllMessages, RuntimeApiMessage, RuntimeApiRequest,
- };
- use polkadot_node_subsystem_test_helpers::{
- subsystem_test_harness, TestSubsystemContextHandle,
- };
- use polkadot_primitives::v1::{
- CollatorPair, Id as ParaId, PersistedValidationData, ScheduledCore, ValidationCode,
- };
- use std::pin::Pin;
+ use super::super::*;
+ use futures::{
+ lock::Mutex,
+ task::{Context as FuturesContext, Poll},
+ Future,
+ };
+ use polkadot_node_primitives::{Collation, CollationResult, BlockData, PoV, POV_BOMB_LIMIT};
+ use polkadot_node_subsystem::messages::{
+ AllMessages, RuntimeApiMessage, RuntimeApiRequest,
+ };
+ use polkadot_node_subsystem_test_helpers::{
+ subsystem_test_harness, TestSubsystemContextHandle,
+ };
+ use polkadot_primitives::v1::{
+ CollatorPair, Id as ParaId, PersistedValidationData, ScheduledCore, ValidationCode,
+ };
+ use std::pin::Pin;
- fn test_collation() -> Collation {
- Collation {
- upward_messages: Default::default(),
- horizontal_messages: Default::default(),
- new_validation_code: Default::default(),
- head_data: Default::default(),
- proof_of_validity: PoV {
- block_data: BlockData(Vec::new()),
- },
- processed_downward_messages: Default::default(),
- hrmp_watermark: Default::default(),
- }
- }
+ fn test_collation() -> Collation {
+ Collation {
+ upward_messages: Default::default(),
+ horizontal_messages: Default::default(),
+ new_validation_code: Default::default(),
+ head_data: Default::default(),
+ proof_of_validity: PoV {
+ block_data: BlockData(Vec::new()),
+ },
+ processed_downward_messages: Default::default(),
+ hrmp_watermark: Default::default(),
+ }
+ }
- fn test_collation_compressed() -> Collation {
- let mut collation = test_collation();
- let compressed = PoV {
- block_data: BlockData(sp_maybe_compressed_blob::compress(
- &collation.proof_of_validity.block_data.0,
- POV_BOMB_LIMIT,
- ).unwrap())
- };
- collation.proof_of_validity = compressed;
- collation
- }
+ fn test_collation_compressed() -> Collation {
+ let mut collation = test_collation();
+ let compressed = PoV {
+ block_data: BlockData(sp_maybe_compressed_blob::compress(
+ &collation.proof_of_validity.block_data.0,
+ POV_BOMB_LIMIT,
+ ).unwrap())
+ };
+ collation.proof_of_validity = compressed;
+ collation
+ }
- fn test_validation_data() -> PersistedValidationData {
- let mut persisted_validation_data: PersistedValidationData = Default::default();
- persisted_validation_data.max_pov_size = 1024;
- persisted_validation_data
- }
+ fn test_validation_data() -> PersistedValidationData {
+ let mut persisted_validation_data: PersistedValidationData = Default::default();
+ persisted_validation_data.max_pov_size = 1024;
+ persisted_validation_data
+ }
- // Box + Unpin + Send
- struct TestCollator;
+ // Box + Unpin + Send
+ struct TestCollator;
- impl Future for TestCollator {
- type Output = Option;
+ impl Future for TestCollator {
+ type Output = Option;
- fn poll(self: Pin<&mut Self>, _cx: &mut FuturesContext) -> Poll {
- Poll::Ready(Some(CollationResult { collation: test_collation(), result_sender: None }))
- }
- }
+ fn poll(self: Pin<&mut Self>, _cx: &mut FuturesContext) -> Poll {
+ Poll::Ready(Some(CollationResult { collation: test_collation(), result_sender: None }))
+ }
+ }
- impl Unpin for TestCollator {}
+ impl Unpin for TestCollator {}
- fn test_config>(para_id: Id) -> Arc {
- Arc::new(CollationGenerationConfig {
- key: CollatorPair::generate().0,
- collator: Box::new(|_: Hash, _vd: &PersistedValidationData| {
- TestCollator.boxed()
- }),
- para_id: para_id.into(),
- })
- }
+ fn test_config>(para_id: Id) -> Arc {
+ Arc::new(CollationGenerationConfig {
+ key: CollatorPair::generate().0,
+ collator: Box::new(|_: Hash, _vd: &PersistedValidationData| {
+ TestCollator.boxed()
+ }),
+ para_id: para_id.into(),
+ })
+ }
- fn scheduled_core_for>(para_id: Id) -> ScheduledCore {
- ScheduledCore {
- para_id: para_id.into(),
- collator: None,
- }
- }
+ fn scheduled_core_for>(para_id: Id) -> ScheduledCore {
+ ScheduledCore {
+ para_id: para_id.into(),
+ collator: None,
+ }
+ }
- #[test]
- fn requests_availability_per_relay_parent() {
- let activated_hashes: Vec = vec![
- [1; 32].into(),
- [4; 32].into(),
- [9; 32].into(),
- [16; 32].into(),
- ];
+ #[test]
+ fn requests_availability_per_relay_parent() {
+ let activated_hashes: Vec = vec![
+ [1; 32].into(),
+ [4; 32].into(),
+ [9; 32].into(),
+ [16; 32].into(),
+ ];
- let requested_availability_cores = Arc::new(Mutex::new(Vec::new()));
+ let requested_availability_cores = Arc::new(Mutex::new(Vec::new()));
- let overseer_requested_availability_cores = requested_availability_cores.clone();
- let overseer = |mut handle: TestSubsystemContextHandle| async move {
- loop {
- match handle.try_recv().await {
- None => break,
- Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request(hash, RuntimeApiRequest::AvailabilityCores(tx)))) => {
- overseer_requested_availability_cores.lock().await.push(hash);
- tx.send(Ok(vec![])).unwrap();
- }
- Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request(_hash, RuntimeApiRequest::Validators(tx)))) => {
- tx.send(Ok(vec![Default::default(); 3])).unwrap();
- }
- Some(msg) => panic!("didn't expect any other overseer requests given no availability cores; got {:?}", msg),
- }
- }
- };
+ let overseer_requested_availability_cores = requested_availability_cores.clone();
+ let overseer = |mut handle: TestSubsystemContextHandle| async move {
+ loop {
+ match handle.try_recv().await {
+ None => break,
+ Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request(hash, RuntimeApiRequest::AvailabilityCores(tx)))) => {
+ overseer_requested_availability_cores.lock().await.push(hash);
+ tx.send(Ok(vec![])).unwrap();
+ }
+ Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request(_hash, RuntimeApiRequest::Validators(tx)))) => {
+ tx.send(Ok(vec![Default::default(); 3])).unwrap();
+ }
+ Some(msg) => panic!("didn't expect any other overseer requests given no availability cores; got {:?}", msg),
+ }
+ }
+ };
- let (tx, _rx) = mpsc::channel(0);
+ let (tx, _rx) = mpsc::channel(0);
- let subsystem_activated_hashes = activated_hashes.clone();
- subsystem_test_harness(overseer, |mut ctx| async move {
- handle_new_activations(
- test_config(123u32),
- subsystem_activated_hashes,
- &mut ctx,
- Metrics(None),
- &tx,
- )
- .await
- .unwrap();
- });
+ let subsystem_activated_hashes = activated_hashes.clone();
+ subsystem_test_harness(overseer, |mut ctx| async move {
+ handle_new_activations(
+ test_config(123u32),
+ subsystem_activated_hashes,
+ &mut ctx,
+ Metrics(None),
+ &tx,
+ )
+ .await
+ .unwrap();
+ });
- let mut requested_availability_cores = Arc::try_unwrap(requested_availability_cores)
- .expect("overseer should have shut down by now")
- .into_inner();
- requested_availability_cores.sort();
+ let mut requested_availability_cores = Arc::try_unwrap(requested_availability_cores)
+ .expect("overseer should have shut down by now")
+ .into_inner();
+ requested_availability_cores.sort();
- assert_eq!(requested_availability_cores, activated_hashes);
- }
+ assert_eq!(requested_availability_cores, activated_hashes);
+ }
- #[test]
- fn requests_validation_data_for_scheduled_matches() {
- let activated_hashes: Vec = vec![
- Hash::repeat_byte(1),
- Hash::repeat_byte(4),
- Hash::repeat_byte(9),
- Hash::repeat_byte(16),
- ];
+ #[test]
+ fn requests_validation_data_for_scheduled_matches() {
+ let activated_hashes: Vec = vec![
+ Hash::repeat_byte(1),
+ Hash::repeat_byte(4),
+ Hash::repeat_byte(9),
+ Hash::repeat_byte(16),
+ ];
- let requested_validation_data = Arc::new(Mutex::new(Vec::new()));
+ let requested_validation_data = Arc::new(Mutex::new(Vec::new()));
- let overseer_requested_validation_data = requested_validation_data.clone();
- let overseer = |mut handle: TestSubsystemContextHandle| async move {
- loop {
- match handle.try_recv().await {
- None => break,
- Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request(
- hash,
- RuntimeApiRequest::AvailabilityCores(tx),
- ))) => {
- tx.send(Ok(vec![
- CoreState::Free,
- // this is weird, see explanation below
- CoreState::Scheduled(scheduled_core_for(
- (hash.as_fixed_bytes()[0] * 4) as u32,
- )),
- CoreState::Scheduled(scheduled_core_for(
- (hash.as_fixed_bytes()[0] * 5) as u32,
- )),
- ]))
- .unwrap();
- }
- Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request(
- hash,
- RuntimeApiRequest::PersistedValidationData(
- _para_id,
- _occupied_core_assumption,
- tx,
- ),
- ))) => {
- overseer_requested_validation_data
- .lock()
- .await
- .push(hash);
- tx.send(Ok(Default::default())).unwrap();
- }
- Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request(
- _hash,
- RuntimeApiRequest::Validators(tx),
- ))) => {
- tx.send(Ok(vec![Default::default(); 3])).unwrap();
- }
- Some(msg) => {
- panic!("didn't expect any other overseer requests; got {:?}", msg)
- }
- }
- }
- };
+ let overseer_requested_validation_data = requested_validation_data.clone();
+ let overseer = |mut handle: TestSubsystemContextHandle| async move {
+ loop {
+ match handle.try_recv().await {
+ None => break,
+ Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request(
+ hash,
+ RuntimeApiRequest::AvailabilityCores(tx),
+ ))) => {
+ tx.send(Ok(vec![
+ CoreState::Free,
+ // this is weird, see explanation below
+ CoreState::Scheduled(scheduled_core_for(
+ (hash.as_fixed_bytes()[0] * 4) as u32,
+ )),
+ CoreState::Scheduled(scheduled_core_for(
+ (hash.as_fixed_bytes()[0] * 5) as u32,
+ )),
+ ]))
+ .unwrap();
+ }
+ Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request(
+ hash,
+ RuntimeApiRequest::PersistedValidationData(
+ _para_id,
+ _occupied_core_assumption,
+ tx,
+ ),
+ ))) => {
+ overseer_requested_validation_data
+ .lock()
+ .await
+ .push(hash);
+ tx.send(Ok(Default::default())).unwrap();
+ }
+ Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request(
+ _hash,
+ RuntimeApiRequest::Validators(tx),
+ ))) => {
+ tx.send(Ok(vec![Default::default(); 3])).unwrap();
+ }
+ Some(msg) => {
+ panic!("didn't expect any other overseer requests; got {:?}", msg)
+ }
+ }
+ }
+ };
- let (tx, _rx) = mpsc::channel(0);
+ let (tx, _rx) = mpsc::channel(0);
- subsystem_test_harness(overseer, |mut ctx| async move {
- handle_new_activations(test_config(16), activated_hashes, &mut ctx, Metrics(None), &tx)
- .await
- .unwrap();
- });
+ subsystem_test_harness(overseer, |mut ctx| async move {
+ handle_new_activations(test_config(16), activated_hashes, &mut ctx, Metrics(None), &tx)
+ .await
+ .unwrap();
+ });
- let requested_validation_data = Arc::try_unwrap(requested_validation_data)
- .expect("overseer should have shut down by now")
- .into_inner();
+ let requested_validation_data = Arc::try_unwrap(requested_validation_data)
+ .expect("overseer should have shut down by now")
+ .into_inner();
- // the only activated hash should be from the 4 hash:
- // each activated hash generates two scheduled cores: one with its value * 4, one with its value * 5
- // given that the test configuration has a para_id of 16, there's only one way to get that value: with the 4
- // hash.
- assert_eq!(requested_validation_data, vec![[4; 32].into()]);
- }
+ // the only activated hash should be from the 4 hash:
+ // each activated hash generates two scheduled cores: one with its value * 4, one with its value * 5
+ // given that the test configuration has a para_id of 16, there's only one way to get that value: with the 4
+ // hash.
+ assert_eq!(requested_validation_data, vec![[4; 32].into()]);
+ }
- #[test]
- fn sends_distribute_collation_message() {
- let activated_hashes: Vec = vec![
- Hash::repeat_byte(1),
- Hash::repeat_byte(4),
- Hash::repeat_byte(9),
- Hash::repeat_byte(16),
- ];
+ #[test]
+ fn sends_distribute_collation_message() {
+ let activated_hashes: Vec = vec![
+ Hash::repeat_byte(1),
+ Hash::repeat_byte(4),
+ Hash::repeat_byte(9),
+ Hash::repeat_byte(16),
+ ];
- let overseer = |mut handle: TestSubsystemContextHandle| async move {
- loop {
- match handle.try_recv().await {
- None => break,
- Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request(
- hash,
- RuntimeApiRequest::AvailabilityCores(tx),
- ))) => {
- tx.send(Ok(vec![
- CoreState::Free,
- // this is weird, see explanation below
- CoreState::Scheduled(scheduled_core_for(
- (hash.as_fixed_bytes()[0] * 4) as u32,
- )),
- CoreState::Scheduled(scheduled_core_for(
- (hash.as_fixed_bytes()[0] * 5) as u32,
- )),
- ]))
- .unwrap();
- }
- Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request(
- _hash,
- RuntimeApiRequest::PersistedValidationData(
- _para_id,
- _occupied_core_assumption,
- tx,
- ),
- ))) => {
- tx.send(Ok(Some(test_validation_data()))).unwrap();
- }
- Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request(
- _hash,
- RuntimeApiRequest::Validators(tx),
- ))) => {
- tx.send(Ok(vec![Default::default(); 3])).unwrap();
- }
- Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request(
- _hash,
- RuntimeApiRequest::ValidationCode(
- _para_id,
- OccupiedCoreAssumption::Free,
- tx,
- ),
- ))) => {
- tx.send(Ok(Some(ValidationCode(vec![1, 2, 3])))).unwrap();
- }
- Some(msg) => {
- panic!("didn't expect any other overseer requests; got {:?}", msg)
- }
- }
- }
- };
+ let overseer = |mut handle: TestSubsystemContextHandle| async move {
+ loop {
+ match handle.try_recv().await {
+ None => break,
+ Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request(
+ hash,
+ RuntimeApiRequest::AvailabilityCores(tx),
+ ))) => {
+ tx.send(Ok(vec![
+ CoreState::Free,
+ // this is weird, see explanation below
+ CoreState::Scheduled(scheduled_core_for(
+ (hash.as_fixed_bytes()[0] * 4) as u32,
+ )),
+ CoreState::Scheduled(scheduled_core_for(
+ (hash.as_fixed_bytes()[0] * 5) as u32,
+ )),
+ ]))
+ .unwrap();
+ }
+ Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request(
+ _hash,
+ RuntimeApiRequest::PersistedValidationData(
+ _para_id,
+ _occupied_core_assumption,
+ tx,
+ ),
+ ))) => {
+ tx.send(Ok(Some(test_validation_data()))).unwrap();
+ }
+ Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request(
+ _hash,
+ RuntimeApiRequest::Validators(tx),
+ ))) => {
+ tx.send(Ok(vec![Default::default(); 3])).unwrap();
+ }
+ Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request(
+ _hash,
+ RuntimeApiRequest::ValidationCode(
+ _para_id,
+ OccupiedCoreAssumption::Free,
+ tx,
+ ),
+ ))) => {
+ tx.send(Ok(Some(ValidationCode(vec![1, 2, 3])))).unwrap();
+ }
+ Some(msg) => {
+ panic!("didn't expect any other overseer requests; got {:?}", msg)
+ }
+ }
+ }
+ };
- let config = test_config(16);
- let subsystem_config = config.clone();
+ let config = test_config(16);
+ let subsystem_config = config.clone();
- let (tx, rx) = mpsc::channel(0);
+ let (tx, rx) = mpsc::channel(0);
- // empty vec doesn't allocate on the heap, so it's ok we throw it away
- let sent_messages = Arc::new(Mutex::new(Vec::new()));
- let subsystem_sent_messages = sent_messages.clone();
- subsystem_test_harness(overseer, |mut ctx| async move {
- handle_new_activations(subsystem_config, activated_hashes, &mut ctx, Metrics(None), &tx)
- .await
- .unwrap();
+ // empty vec doesn't allocate on the heap, so it's ok we throw it away
+ let sent_messages = Arc::new(Mutex::new(Vec::new()));
+ let subsystem_sent_messages = sent_messages.clone();
+ subsystem_test_harness(overseer, |mut ctx| async move {
+ handle_new_activations(subsystem_config, activated_hashes, &mut ctx, Metrics(None), &tx)
+ .await
+ .unwrap();
- std::mem::drop(tx);
+ std::mem::drop(tx);
- // collect all sent messages
- *subsystem_sent_messages.lock().await = rx.collect().await;
- });
+ // collect all sent messages
+ *subsystem_sent_messages.lock().await = rx.collect().await;
+ });
- let sent_messages = Arc::try_unwrap(sent_messages)
- .expect("subsystem should have shut down by now")
- .into_inner();
+ let sent_messages = Arc::try_unwrap(sent_messages)
+ .expect("subsystem should have shut down by now")
+ .into_inner();
- // we expect a single message to be sent, containing a candidate receipt.
- // we don't care too much about the commitments_hash right now, but let's ensure that we've calculated the
- // correct descriptor
- let expect_pov_hash = test_collation_compressed().proof_of_validity.hash();
- let expect_validation_data_hash = test_validation_data().hash();
- let expect_relay_parent = Hash::repeat_byte(4);
- let expect_validation_code_hash = ValidationCode(vec![1, 2, 3]).hash();
- let expect_payload = collator_signature_payload(
- &expect_relay_parent,
- &config.para_id,
- &expect_validation_data_hash,
- &expect_pov_hash,
- &expect_validation_code_hash,
- );
- let expect_descriptor = CandidateDescriptor {
- signature: config.key.sign(&expect_payload),
- para_id: config.para_id,
- relay_parent: expect_relay_parent,
- collator: config.key.public(),
- persisted_validation_data_hash: expect_validation_data_hash,
- pov_hash: expect_pov_hash,
- erasure_root: Default::default(), // this isn't something we're checking right now
- para_head: test_collation().head_data.hash(),
- validation_code_hash: expect_validation_code_hash,
- };
+ // we expect a single message to be sent, containing a candidate receipt.
+ // we don't care too much about the commitments_hash right now, but let's ensure that we've calculated the
+ // correct descriptor
+ let expect_pov_hash = test_collation_compressed().proof_of_validity.hash();
+ let expect_validation_data_hash = test_validation_data().hash();
+ let expect_relay_parent = Hash::repeat_byte(4);
+ let expect_validation_code_hash = ValidationCode(vec![1, 2, 3]).hash();
+ let expect_payload = collator_signature_payload(
+ &expect_relay_parent,
+ &config.para_id,
+ &expect_validation_data_hash,
+ &expect_pov_hash,
+ &expect_validation_code_hash,
+ );
+ let expect_descriptor = CandidateDescriptor {
+ signature: config.key.sign(&expect_payload),
+ para_id: config.para_id,
+ relay_parent: expect_relay_parent,
+ collator: config.key.public(),
+ persisted_validation_data_hash: expect_validation_data_hash,
+ pov_hash: expect_pov_hash,
+ erasure_root: Default::default(), // this isn't something we're checking right now
+ para_head: test_collation().head_data.hash(),
+ validation_code_hash: expect_validation_code_hash,
+ };
- assert_eq!(sent_messages.len(), 1);
- match &sent_messages[0] {
- AllMessages::CollatorProtocol(CollatorProtocolMessage::DistributeCollation(
- CandidateReceipt { descriptor, .. },
- _pov,
- ..
- )) => {
- // signature generation is non-deterministic, so we can't just assert that the
- // expected descriptor is correct. What we can do is validate that the produced
- // descriptor has a valid signature, then just copy in the generated signature
- // and check the rest of the fields for equality.
- assert!(CollatorPair::verify(
- &descriptor.signature,
- &collator_signature_payload(
- &descriptor.relay_parent,
- &descriptor.para_id,
- &descriptor.persisted_validation_data_hash,
- &descriptor.pov_hash,
- &descriptor.validation_code_hash,
- )
- .as_ref(),
- &descriptor.collator,
- ));
- let expect_descriptor = {
- let mut expect_descriptor = expect_descriptor;
- expect_descriptor.signature = descriptor.signature.clone();
- expect_descriptor.erasure_root = descriptor.erasure_root.clone();
- expect_descriptor
- };
- assert_eq!(descriptor, &expect_descriptor);
- }
- _ => panic!("received wrong message type"),
- }
- }
+ assert_eq!(sent_messages.len(), 1);
+ match &sent_messages[0] {
+ AllMessages::CollatorProtocol(CollatorProtocolMessage::DistributeCollation(
+ CandidateReceipt { descriptor, .. },
+ _pov,
+ ..
+ )) => {
+ // signature generation is non-deterministic, so we can't just assert that the
+ // expected descriptor is correct. What we can do is validate that the produced
+ // descriptor has a valid signature, then just copy in the generated signature
+ // and check the rest of the fields for equality.
+ assert!(CollatorPair::verify(
+ &descriptor.signature,
+ &collator_signature_payload(
+ &descriptor.relay_parent,
+ &descriptor.para_id,
+ &descriptor.persisted_validation_data_hash,
+ &descriptor.pov_hash,
+ &descriptor.validation_code_hash,
+ )
+ .as_ref(),
+ &descriptor.collator,
+ ));
+ let expect_descriptor = {
+ let mut expect_descriptor = expect_descriptor;
+ expect_descriptor.signature = descriptor.signature.clone();
+ expect_descriptor.erasure_root = descriptor.erasure_root.clone();
+ expect_descriptor
+ };
+ assert_eq!(descriptor, &expect_descriptor);
+ }
+ _ => panic!("received wrong message type"),
+ }
+ }
}
diff --git a/polkadot/node/core/provisioner/src/lib.rs b/polkadot/node/core/provisioner/src/lib.rs
index dd13621597..7a730aa8cf 100644
--- a/polkadot/node/core/provisioner/src/lib.rs
+++ b/polkadot/node/core/provisioner/src/lib.rs
@@ -43,6 +43,9 @@ use std::{pin::Pin, collections::BTreeMap, sync::Arc};
use thiserror::Error;
use futures_timer::Delay;
+#[cfg(test)]
+mod tests;
+
/// How long to wait before proposing.
const PRE_PROPOSE_TIMEOUT: std::time::Duration = core::time::Duration::from_millis(2000);
@@ -599,6 +602,3 @@ impl metrics::Metrics for Metrics {
/// The provisioning subsystem.
pub type ProvisioningSubsystem = JobSubsystem;
-
-#[cfg(test)]
-mod tests;
diff --git a/polkadot/node/core/runtime-api/src/lib.rs b/polkadot/node/core/runtime-api/src/lib.rs
index 31d0471fe3..839cbfa393 100644
--- a/polkadot/node/core/runtime-api/src/lib.rs
+++ b/polkadot/node/core/runtime-api/src/lib.rs
@@ -44,6 +44,9 @@ use cache::{RequestResult, RequestResultCache};
mod cache;
+#[cfg(test)]
+mod tests;
+
const LOG_TARGET: &str = "parachain::runtime-api";
/// The number of maximum runtime api requests can be executed in parallel. Further requests will be buffered.
@@ -411,6 +414,3 @@ impl metrics::Metrics for Metrics {
Ok(Metrics(Some(metrics)))
}
}
-
-#[cfg(test)]
-mod tests;
diff --git a/polkadot/node/network/approval-distribution/src/lib.rs b/polkadot/node/network/approval-distribution/src/lib.rs
index 6492caa2b1..04cc835e21 100644
--- a/polkadot/node/network/approval-distribution/src/lib.rs
+++ b/polkadot/node/network/approval-distribution/src/lib.rs
@@ -20,10 +20,6 @@
#![warn(missing_docs)]
-#[cfg(test)]
-mod tests;
-
-
use std::collections::{BTreeMap, HashMap, HashSet, hash_map};
use futures::{channel::oneshot, FutureExt as _};
use polkadot_primitives::v1::{
@@ -47,6 +43,9 @@ use polkadot_node_network_protocol::{
PeerId, View, v1 as protocol_v1, UnifiedReputationChange as Rep,
};
+#[cfg(test)]
+mod tests;
+
const LOG_TARGET: &str = "parachain::approval-distribution";
const COST_UNEXPECTED_MESSAGE: Rep = Rep::CostMinor("Peer sent an out-of-view assignment or approval");
diff --git a/polkadot/node/network/availability-recovery/src/lib.rs b/polkadot/node/network/availability-recovery/src/lib.rs
index 4a4efc66bf..711c191c81 100644
--- a/polkadot/node/network/availability-recovery/src/lib.rs
+++ b/polkadot/node/network/availability-recovery/src/lib.rs
@@ -51,6 +51,7 @@ use polkadot_node_network_protocol::{
};
use polkadot_node_subsystem_util::request_session_info;
use polkadot_erasure_coding::{branches, branch_hash, recovery_threshold, obtain_chunks_v1};
+
mod error;
#[cfg(test)]
diff --git a/polkadot/node/network/bridge/src/lib.rs b/polkadot/node/network/bridge/src/lib.rs
index 8618d06d14..8635dbe501 100644
--- a/polkadot/node/network/bridge/src/lib.rs
+++ b/polkadot/node/network/bridge/src/lib.rs
@@ -64,6 +64,8 @@ use network::{Network, send_message};
mod multiplexer;
pub use multiplexer::RequestMultiplexer;
+#[cfg(test)]
+mod tests;
/// The maximum amount of heads a peer is allowed to have in their view at any time.
///
@@ -1131,9 +1133,3 @@ async fn dispatch_collation_events_to_all(
ctx.send_messages(events.into_iter().flat_map(messages_for)).await
}
-
-
-
-
-#[cfg(test)]
-mod tests;
diff --git a/polkadot/node/network/bridge/src/tests.rs b/polkadot/node/network/bridge/src/tests.rs
index 4fceeb212c..74ca4501e1 100644
--- a/polkadot/node/network/bridge/src/tests.rs
+++ b/polkadot/node/network/bridge/src/tests.rs
@@ -31,12 +31,12 @@ use sc_network::{Event as NetworkEvent, IfDisconnected};
use polkadot_subsystem::{jaeger, ActiveLeavesUpdate, FromOverseer, OverseerSignal, LeafStatus};
use polkadot_subsystem::messages::{
- ApprovalDistributionMessage,
- BitfieldDistributionMessage,
- StatementDistributionMessage
+ ApprovalDistributionMessage,
+ BitfieldDistributionMessage,
+ StatementDistributionMessage
};
use polkadot_node_subsystem_test_helpers::{
- SingleItemSink, SingleItemStream, TestSubsystemContextHandle,
+ SingleItemSink, SingleItemStream, TestSubsystemContextHandle,
};
use polkadot_node_subsystem_util::metered;
use polkadot_node_network_protocol::view;
@@ -52,9 +52,9 @@ use crate::validator_discovery::AuthorityDiscovery;
// The subsystem's view of the network - only supports a single call to `event_stream`.
#[derive(Clone)]
struct TestNetwork {
- net_events: Arc>>>,
- action_tx: metered::UnboundedMeteredSender,
- _req_configs: Vec,
+ net_events: Arc>>>,
+ action_tx: metered::UnboundedMeteredSender,
+ _req_configs: Vec,
}
#[derive(Clone)]
@@ -63,1253 +63,1253 @@ struct TestAuthorityDiscovery;
// The test's view of the network. This receives updates from the subsystem in the form
// of `NetworkAction`s.
struct TestNetworkHandle {
- action_rx: metered::UnboundedMeteredReceiver,
- net_tx: SingleItemSink,
+ action_rx: metered::UnboundedMeteredReceiver,
+ net_tx: SingleItemSink,
}
fn new_test_network(req_configs: Vec) -> (
- TestNetwork,
- TestNetworkHandle,
- TestAuthorityDiscovery,
+ TestNetwork,
+ TestNetworkHandle,
+ TestAuthorityDiscovery,
) {
- let (net_tx, net_rx) = polkadot_node_subsystem_test_helpers::single_item_sink();
- let (action_tx, action_rx) = metered::unbounded();
+ let (net_tx, net_rx) = polkadot_node_subsystem_test_helpers::single_item_sink();
+ let (action_tx, action_rx) = metered::unbounded();
- (
- TestNetwork {
- net_events: Arc::new(Mutex::new(Some(net_rx))),
- action_tx,
- _req_configs: req_configs,
- },
- TestNetworkHandle {
- action_rx,
- net_tx,
- },
- TestAuthorityDiscovery,
- )
+ (
+ TestNetwork {
+ net_events: Arc::new(Mutex::new(Some(net_rx))),
+ action_tx,
+ _req_configs: req_configs,
+ },
+ TestNetworkHandle {
+ action_rx,
+ net_tx,
+ },
+ TestAuthorityDiscovery,
+ )
}
#[async_trait]
impl Network for TestNetwork {
- fn event_stream(&mut self) -> BoxStream<'static, NetworkEvent> {
- self.net_events.lock()
- .take()
- .expect("Subsystem made more than one call to `event_stream`")
- .boxed()
- }
+ fn event_stream(&mut self) -> BoxStream<'static, NetworkEvent> {
+ self.net_events.lock()
+ .take()
+ .expect("Subsystem made more than one call to `event_stream`")
+ .boxed()
+ }
- async fn add_to_peers_set(&mut self, _protocol: Cow<'static, str>, _: HashSet) -> Result<(), String> {
- Ok(())
- }
+ async fn add_to_peers_set(&mut self, _protocol: Cow<'static, str>, _: HashSet) -> Result<(), String> {
+ Ok(())
+ }
- async fn remove_from_peers_set(&mut self, _protocol: Cow<'static, str>, _: HashSet) -> Result<(), String> {
- Ok(())
- }
+ async fn remove_from_peers_set(&mut self, _protocol: Cow<'static, str>, _: HashSet) -> Result<(), String> {
+ Ok(())
+ }
- fn action_sink<'a>(&'a mut self)
- -> Pin + Send + 'a>>
- {
- Box::pin((&mut self.action_tx).sink_map_err(Into::into))
- }
+ fn action_sink<'a>(&'a mut self)
+ -> Pin + Send + 'a>>
+ {
+ Box::pin((&mut self.action_tx).sink_map_err(Into::into))
+ }
- async fn start_request(&self, _: &mut AD, _: Requests, _: IfDisconnected) {
- }
+ async fn start_request(&self, _: &mut AD, _: Requests, _: IfDisconnected) {
+ }
}
#[async_trait]
impl validator_discovery::AuthorityDiscovery for TestAuthorityDiscovery {
- async fn get_addresses_by_authority_id(&mut self, _authority: AuthorityDiscoveryId) -> Option> {
- None
- }
+ async fn get_addresses_by_authority_id(&mut self, _authority: AuthorityDiscoveryId) -> Option> {
+ None
+ }
- async fn get_authority_id_by_peer_id(&mut self, _peer_id: PeerId) -> Option {
- None
- }
+ async fn get_authority_id_by_peer_id(&mut self, _peer_id: PeerId) -> Option {
+ None
+ }
}
impl TestNetworkHandle {
- // Get the next network action.
- async fn next_network_action(&mut self) -> NetworkAction {
- self.action_rx.next().await.expect("subsystem concluded early")
- }
+ // Get the next network action.
+ async fn next_network_action(&mut self) -> NetworkAction {
+ self.action_rx.next().await.expect("subsystem concluded early")
+ }
- // Wait for the next N network actions.
- async fn next_network_actions(&mut self, n: usize) -> Vec {
- let mut v = Vec::with_capacity(n);
- for _ in 0..n {
- v.push(self.next_network_action().await);
- }
+ // Wait for the next N network actions.
+ async fn next_network_actions(&mut self, n: usize) -> Vec {
+ let mut v = Vec::with_capacity(n);
+ for _ in 0..n {
+ v.push(self.next_network_action().await);
+ }
- v
- }
+ v
+ }
- async fn connect_peer(&mut self, peer: PeerId, peer_set: PeerSet, role: ObservedRole) {
- self.send_network_event(NetworkEvent::NotificationStreamOpened {
- remote: peer,
- protocol: peer_set.into_protocol_name(),
- negotiated_fallback: None,
- role: role.into(),
- }).await;
- }
+ async fn connect_peer(&mut self, peer: PeerId, peer_set: PeerSet, role: ObservedRole) {
+ self.send_network_event(NetworkEvent::NotificationStreamOpened {
+ remote: peer,
+ protocol: peer_set.into_protocol_name(),
+ negotiated_fallback: None,
+ role: role.into(),
+ }).await;
+ }
- async fn disconnect_peer(&mut self, peer: PeerId, peer_set: PeerSet) {
- self.send_network_event(NetworkEvent::NotificationStreamClosed {
- remote: peer,
- protocol: peer_set.into_protocol_name(),
- }).await;
- }
+ async fn disconnect_peer(&mut self, peer: PeerId, peer_set: PeerSet) {
+ self.send_network_event(NetworkEvent::NotificationStreamClosed {
+ remote: peer,
+ protocol: peer_set.into_protocol_name(),
+ }).await;
+ }
- async fn peer_message(&mut self, peer: PeerId, peer_set: PeerSet, message: Vec) {
- self.send_network_event(NetworkEvent::NotificationsReceived {
- remote: peer,
- messages: vec![(peer_set.into_protocol_name(), message.into())],
- }).await;
- }
+ async fn peer_message(&mut self, peer: PeerId, peer_set: PeerSet, message: Vec) {
+ self.send_network_event(NetworkEvent::NotificationsReceived {
+ remote: peer,
+ messages: vec![(peer_set.into_protocol_name(), message.into())],
+ }).await;
+ }
- async fn send_network_event(&mut self, event: NetworkEvent) {
- self.net_tx.send(event).await.expect("subsystem concluded early");
- }
+ async fn send_network_event(&mut self, event: NetworkEvent) {
+ self.net_tx.send(event).await.expect("subsystem concluded early");
+ }
}
/// Assert that the given actions contain the given `action`.
fn assert_network_actions_contains(actions: &[NetworkAction], action: &NetworkAction) {
- if !actions.iter().any(|x| x == action) {
- panic!("Could not find `{:?}` in `{:?}`", action, actions);
- }
+ if !actions.iter().any(|x| x == action) {
+ panic!("Could not find `{:?}` in `{:?}`", action, actions);
+ }
}
#[derive(Clone)]
struct TestSyncOracle {
- flag: Arc,
- done_syncing_sender: Arc>>>,
+ flag: Arc,
+ done_syncing_sender: Arc>>>,
}
struct TestSyncOracleHandle {
- done_syncing_receiver: oneshot::Receiver<()>,
- flag: Arc,
+ done_syncing_receiver: oneshot::Receiver<()>,
+ flag: Arc,
}
impl TestSyncOracleHandle {
- fn set_done(&self) {
- self.flag.store(false, Ordering::SeqCst);
- }
+ fn set_done(&self) {
+ self.flag.store(false, Ordering::SeqCst);
+ }
- async fn await_mode_switch(self) {
- let _ = self.done_syncing_receiver.await;
- }
+ async fn await_mode_switch(self) {
+ let _ = self.done_syncing_receiver.await;
+ }
}
impl SyncOracle for TestSyncOracle {
- fn is_major_syncing(&mut self) -> bool {
- let is_major_syncing = self.flag.load(Ordering::SeqCst);
+ fn is_major_syncing(&mut self) -> bool {
+ let is_major_syncing = self.flag.load(Ordering::SeqCst);
- if !is_major_syncing {
- if let Some(sender) = self.done_syncing_sender.lock().take() {
- let _ = sender.send(());
- }
- }
+ if !is_major_syncing {
+ if let Some(sender) = self.done_syncing_sender.lock().take() {
+ let _ = sender.send(());
+ }
+ }
- is_major_syncing
- }
+ is_major_syncing
+ }
- fn is_offline(&mut self) -> bool {
- unimplemented!("not used in network bridge")
- }
+ fn is_offline(&mut self) -> bool {
+ unimplemented!("not used in network bridge")
+ }
}
// val - result of `is_major_syncing`.
fn make_sync_oracle(val: bool) -> (TestSyncOracle, TestSyncOracleHandle) {
- let (tx, rx) = oneshot::channel();
- let flag = Arc::new(AtomicBool::new(val));
+ let (tx, rx) = oneshot::channel();
+ let flag = Arc::new(AtomicBool::new(val));
- (
- TestSyncOracle {
- flag: flag.clone(),
- done_syncing_sender: Arc::new(Mutex::new(Some(tx))),
- },
- TestSyncOracleHandle {
- flag,
- done_syncing_receiver: rx,
- }
- )
+ (
+ TestSyncOracle {
+ flag: flag.clone(),
+ done_syncing_sender: Arc::new(Mutex::new(Some(tx))),
+ },
+ TestSyncOracleHandle {
+ flag,
+ done_syncing_receiver: rx,
+ }
+ )
}
fn done_syncing_oracle() -> Box {
- let (oracle, _) = make_sync_oracle(false);
- Box::new(oracle)
+ let (oracle, _) = make_sync_oracle(false);
+ Box::new(oracle)
}
type VirtualOverseer = TestSubsystemContextHandle;
struct TestHarness {
- network_handle: TestNetworkHandle,
- virtual_overseer: VirtualOverseer,
+ network_handle: TestNetworkHandle,
+ virtual_overseer: VirtualOverseer,
}
fn test_harness>(
- sync_oracle: Box,
- test: impl FnOnce(TestHarness) -> T,
+ sync_oracle: Box,
+ test: impl FnOnce(TestHarness) -> T,
) {
- let pool = sp_core::testing::TaskExecutor::new();
- let (request_multiplexer, req_configs) = RequestMultiplexer::new();
- let (mut network, network_handle, discovery) = new_test_network(req_configs);
- let (context, virtual_overseer) = polkadot_node_subsystem_test_helpers::make_subsystem_context(pool);
- let network_stream = network.event_stream();
+ let pool = sp_core::testing::TaskExecutor::new();
+ let (request_multiplexer, req_configs) = RequestMultiplexer::new();
+ let (mut network, network_handle, discovery) = new_test_network(req_configs);
+ let (context, virtual_overseer) = polkadot_node_subsystem_test_helpers::make_subsystem_context(pool);
+ let network_stream = network.event_stream();
- let bridge = NetworkBridge {
- network_service: network,
- authority_discovery_service: discovery,
- request_multiplexer,
- metrics: Metrics(None),
- sync_oracle,
- };
+ let bridge = NetworkBridge {
+ network_service: network,
+ authority_discovery_service: discovery,
+ request_multiplexer,
+ metrics: Metrics(None),
+ sync_oracle,
+ };
- let network_bridge = run_network(
- bridge,
- context,
- network_stream,
- )
- .map_err(|_| panic!("subsystem execution failed"))
- .map(|_| ());
+ let network_bridge = run_network(
+ bridge,
+ context,
+ network_stream,
+ )
+ .map_err(|_| panic!("subsystem execution failed"))
+ .map(|_| ());
- let test_fut = test(TestHarness {
- network_handle,
- virtual_overseer,
- });
+ let test_fut = test(TestHarness {
+ network_handle,
+ virtual_overseer,
+ });
- futures::pin_mut!(test_fut);
- futures::pin_mut!(network_bridge);
+ futures::pin_mut!(test_fut);
+ futures::pin_mut!(network_bridge);
- let _ = executor::block_on(future::join(async move {
- let mut virtual_overseer = test_fut.await;
- virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await;
- }, network_bridge));
+ let _ = executor::block_on(future::join(async move {
+ let mut virtual_overseer = test_fut.await;
+ virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await;
+ }, network_bridge));
}
async fn assert_sends_validation_event_to_all(
- event: NetworkBridgeEvent,
- virtual_overseer: &mut TestSubsystemContextHandle,
+ event: NetworkBridgeEvent,
+ virtual_overseer: &mut TestSubsystemContextHandle,
) {
- // Ordering must match the enum variant order
- // in `AllMessages`.
- assert_matches!(
- virtual_overseer.recv().await,
- AllMessages::StatementDistribution(
- StatementDistributionMessage::NetworkBridgeUpdateV1(e)
- ) if e == event.focus().expect("could not focus message")
- );
+ // Ordering must match the enum variant order
+ // in `AllMessages`.
+ assert_matches!(
+ virtual_overseer.recv().await,
+ AllMessages::StatementDistribution(
+ StatementDistributionMessage::NetworkBridgeUpdateV1(e)
+ ) if e == event.focus().expect("could not focus message")
+ );
- assert_matches!(
- virtual_overseer.recv().await,
- AllMessages::BitfieldDistribution(
- BitfieldDistributionMessage::NetworkBridgeUpdateV1(e)
- ) if e == event.focus().expect("could not focus message")
- );
+ assert_matches!(
+ virtual_overseer.recv().await,
+ AllMessages::BitfieldDistribution(
+ BitfieldDistributionMessage::NetworkBridgeUpdateV1(e)
+ ) if e == event.focus().expect("could not focus message")
+ );
- assert_matches!(
- virtual_overseer.recv().await,
- AllMessages::ApprovalDistribution(
- ApprovalDistributionMessage::NetworkBridgeUpdateV1(e)
- ) if e == event.focus().expect("could not focus message")
- );
+ assert_matches!(
+ virtual_overseer.recv().await,
+ AllMessages::ApprovalDistribution(
+ ApprovalDistributionMessage::NetworkBridgeUpdateV1(e)
+ ) if e == event.focus().expect("could not focus message")
+ );
}
async fn assert_sends_collation_event_to_all(
- event: NetworkBridgeEvent,
- virtual_overseer: &mut TestSubsystemContextHandle,
+ event: NetworkBridgeEvent,
+ virtual_overseer: &mut TestSubsystemContextHandle,
) {
- assert_matches!(
- virtual_overseer.recv().await,
- AllMessages::CollatorProtocol(
- CollatorProtocolMessage::NetworkBridgeUpdateV1(e)
- ) if e == event.focus().expect("could not focus message")
- )
+ assert_matches!(
+ virtual_overseer.recv().await,
+ AllMessages::CollatorProtocol(
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(e)
+ ) if e == event.focus().expect("could not focus message")
+ )
}
#[test]
fn send_our_view_upon_connection() {
- let (oracle, handle) = make_sync_oracle(false);
- test_harness(Box::new(oracle), |test_harness| async move {
- let TestHarness {
- mut network_handle,
- mut virtual_overseer,
- } = test_harness;
+ let (oracle, handle) = make_sync_oracle(false);
+ test_harness(Box::new(oracle), |test_harness| async move {
+ let TestHarness {
+ mut network_handle,
+ mut virtual_overseer,
+ } = test_harness;
- let peer = PeerId::random();
+ let peer = PeerId::random();
- let head = Hash::repeat_byte(1);
- virtual_overseer.send(
- FromOverseer::Signal(OverseerSignal::ActiveLeaves(
- ActiveLeavesUpdate::start_work(ActivatedLeaf {
- hash: head,
- number: 1,
- status: LeafStatus::Fresh,
- span: Arc::new(jaeger::Span::Disabled),
- })
- ))
- ).await;
+ let head = Hash::repeat_byte(1);
+ virtual_overseer.send(
+ FromOverseer::Signal(OverseerSignal::ActiveLeaves(
+ ActiveLeavesUpdate::start_work(ActivatedLeaf {
+ hash: head,
+ number: 1,
+ status: LeafStatus::Fresh,
+ span: Arc::new(jaeger::Span::Disabled),
+ })
+ ))
+ ).await;
- handle.await_mode_switch().await;
+ handle.await_mode_switch().await;
- network_handle.connect_peer(peer.clone(), PeerSet::Validation, ObservedRole::Full).await;
- network_handle.connect_peer(peer.clone(), PeerSet::Collation, ObservedRole::Full).await;
+ network_handle.connect_peer(peer.clone(), PeerSet::Validation, ObservedRole::Full).await;
+ network_handle.connect_peer(peer.clone(), PeerSet::Collation, ObservedRole::Full).await;
- let view = view![head];
- let actions = network_handle.next_network_actions(2).await;
- assert_network_actions_contains(
- &actions,
- &NetworkAction::WriteNotification(
- peer.clone(),
- PeerSet::Validation,
- WireMessage::::ViewUpdate(
- view.clone(),
- ).encode(),
- ),
- );
- assert_network_actions_contains(
- &actions,
- &NetworkAction::WriteNotification(
- peer.clone(),
- PeerSet::Collation,
- WireMessage::::ViewUpdate(
- view.clone(),
- ).encode(),
- ),
- );
- virtual_overseer
- });
+ let view = view![head];
+ let actions = network_handle.next_network_actions(2).await;
+ assert_network_actions_contains(
+ &actions,
+ &NetworkAction::WriteNotification(
+ peer.clone(),
+ PeerSet::Validation,
+ WireMessage::::ViewUpdate(
+ view.clone(),
+ ).encode(),
+ ),
+ );
+ assert_network_actions_contains(
+ &actions,
+ &NetworkAction::WriteNotification(
+ peer.clone(),
+ PeerSet::Collation,
+ WireMessage::::ViewUpdate(
+ view.clone(),
+ ).encode(),
+ ),
+ );
+ virtual_overseer
+ });
}
#[test]
fn sends_view_updates_to_peers() {
- let (oracle, handle) = make_sync_oracle(false);
- test_harness(Box::new(oracle), |test_harness| async move {
- let TestHarness { mut network_handle, mut virtual_overseer } = test_harness;
+ let (oracle, handle) = make_sync_oracle(false);
+ test_harness(Box::new(oracle), |test_harness| async move {
+ let TestHarness { mut network_handle, mut virtual_overseer } = test_harness;
- let peer_a = PeerId::random();
- let peer_b = PeerId::random();
+ let peer_a = PeerId::random();
+ let peer_b = PeerId::random();
- virtual_overseer.send(
- FromOverseer::Signal(OverseerSignal::ActiveLeaves(
- ActiveLeavesUpdate {
- activated: Default::default(),
- deactivated: Default::default(),
- }
- ))
- ).await;
+ virtual_overseer.send(
+ FromOverseer::Signal(OverseerSignal::ActiveLeaves(
+ ActiveLeavesUpdate {
+ activated: Default::default(),
+ deactivated: Default::default(),
+ }
+ ))
+ ).await;
- handle.await_mode_switch().await;
+ handle.await_mode_switch().await;
- network_handle.connect_peer(
- peer_a.clone(),
- PeerSet::Validation,
- ObservedRole::Full,
- ).await;
- network_handle.connect_peer(
- peer_b.clone(),
- PeerSet::Collation,
- ObservedRole::Full,
- ).await;
+ network_handle.connect_peer(
+ peer_a.clone(),
+ PeerSet::Validation,
+ ObservedRole::Full,
+ ).await;
+ network_handle.connect_peer(
+ peer_b.clone(),
+ PeerSet::Collation,
+ ObservedRole::Full,
+ ).await;
- let actions = network_handle.next_network_actions(2).await;
- let wire_message = WireMessage::::ViewUpdate(
- View::default(),
- ).encode();
+ let actions = network_handle.next_network_actions(2).await;
+ let wire_message = WireMessage::::ViewUpdate(
+ View::default(),
+ ).encode();
- assert_network_actions_contains(
- &actions,
- &NetworkAction::WriteNotification(
- peer_a,
- PeerSet::Validation,
- wire_message.clone(),
- ),
- );
+ assert_network_actions_contains(
+ &actions,
+ &NetworkAction::WriteNotification(
+ peer_a,
+ PeerSet::Validation,
+ wire_message.clone(),
+ ),
+ );
- assert_network_actions_contains(
- &actions,
- &NetworkAction::WriteNotification(
- peer_b,
- PeerSet::Collation,
- wire_message.clone(),
- ),
- );
+ assert_network_actions_contains(
+ &actions,
+ &NetworkAction::WriteNotification(
+ peer_b,
+ PeerSet::Collation,
+ wire_message.clone(),
+ ),
+ );
- let hash_a = Hash::repeat_byte(1);
+ let hash_a = Hash::repeat_byte(1);
- virtual_overseer.send(
- FromOverseer::Signal(OverseerSignal::ActiveLeaves(
- ActiveLeavesUpdate::start_work(ActivatedLeaf {
- hash: hash_a,
- number: 1,
- status: LeafStatus::Fresh,
- span: Arc::new(jaeger::Span::Disabled),
- })
- ))
- ).await;
+ virtual_overseer.send(
+ FromOverseer::Signal(OverseerSignal::ActiveLeaves(
+ ActiveLeavesUpdate::start_work(ActivatedLeaf {
+ hash: hash_a,
+ number: 1,
+ status: LeafStatus::Fresh,
+ span: Arc::new(jaeger::Span::Disabled),
+ })
+ ))
+ ).await;
- let actions = network_handle.next_network_actions(2).await;
- let wire_message = WireMessage::::ViewUpdate(
- view![hash_a]
- ).encode();
+ let actions = network_handle.next_network_actions(2).await;
+ let wire_message = WireMessage::::ViewUpdate(
+ view![hash_a]
+ ).encode();
- assert_network_actions_contains(
- &actions,
- &NetworkAction::WriteNotification(
- peer_a,
- PeerSet::Validation,
- wire_message.clone(),
- ),
- );
+ assert_network_actions_contains(
+ &actions,
+ &NetworkAction::WriteNotification(
+ peer_a,
+ PeerSet::Validation,
+ wire_message.clone(),
+ ),
+ );
- assert_network_actions_contains(
- &actions,
- &NetworkAction::WriteNotification(
- peer_b,
- PeerSet::Collation,
- wire_message.clone(),
- ),
- );
- virtual_overseer
- });
+ assert_network_actions_contains(
+ &actions,
+ &NetworkAction::WriteNotification(
+ peer_b,
+ PeerSet::Collation,
+ wire_message.clone(),
+ ),
+ );
+ virtual_overseer
+ });
}
#[test]
fn do_not_send_view_update_until_synced() {
- let (oracle, handle) = make_sync_oracle(true);
- test_harness(Box::new(oracle), |test_harness| async move {
- let TestHarness { mut network_handle, mut virtual_overseer } = test_harness;
+ let (oracle, handle) = make_sync_oracle(true);
+ test_harness(Box::new(oracle), |test_harness| async move {
+ let TestHarness { mut network_handle, mut virtual_overseer } = test_harness;
- let peer_a = PeerId::random();
- let peer_b = PeerId::random();
+ let peer_a = PeerId::random();
+ let peer_b = PeerId::random();
- network_handle.connect_peer(
- peer_a.clone(),
- PeerSet::Validation,
- ObservedRole::Full,
- ).await;
- network_handle.connect_peer(
- peer_b.clone(),
- PeerSet::Collation,
- ObservedRole::Full,
- ).await;
+ network_handle.connect_peer(
+ peer_a.clone(),
+ PeerSet::Validation,
+ ObservedRole::Full,
+ ).await;
+ network_handle.connect_peer(
+ peer_b.clone(),
+ PeerSet::Collation,
+ ObservedRole::Full,
+ ).await;
- {
- let actions = network_handle.next_network_actions(2).await;
- let wire_message = WireMessage::::ViewUpdate(
- View::default(),
- ).encode();
+ {
+ let actions = network_handle.next_network_actions(2).await;
+ let wire_message = WireMessage::::ViewUpdate(
+ View::default(),
+ ).encode();
- assert_network_actions_contains(
- &actions,
- &NetworkAction::WriteNotification(
- peer_a,
- PeerSet::Validation,
- wire_message.clone(),
- ),
- );
+ assert_network_actions_contains(
+ &actions,
+ &NetworkAction::WriteNotification(
+ peer_a,
+ PeerSet::Validation,
+ wire_message.clone(),
+ ),
+ );
- assert_network_actions_contains(
- &actions,
- &NetworkAction::WriteNotification(
- peer_b,
- PeerSet::Collation,
- wire_message.clone(),
- ),
- );
- }
+ assert_network_actions_contains(
+ &actions,
+ &NetworkAction::WriteNotification(
+ peer_b,
+ PeerSet::Collation,
+ wire_message.clone(),
+ ),
+ );
+ }
- let hash_a = Hash::repeat_byte(1);
- let hash_b = Hash::repeat_byte(1);
+ let hash_a = Hash::repeat_byte(1);
+ let hash_b = Hash::repeat_byte(1);
- virtual_overseer.send(
- FromOverseer::Signal(OverseerSignal::ActiveLeaves(
- ActiveLeavesUpdate::start_work(ActivatedLeaf {
- hash: hash_a,
- number: 1,
- status: LeafStatus::Fresh,
- span: Arc::new(jaeger::Span::Disabled),
- })
- ))
- ).await;
+ virtual_overseer.send(
+ FromOverseer::Signal(OverseerSignal::ActiveLeaves(
+ ActiveLeavesUpdate::start_work(ActivatedLeaf {
+ hash: hash_a,
+ number: 1,
+ status: LeafStatus::Fresh,
+ span: Arc::new(jaeger::Span::Disabled),
+ })
+ ))
+ ).await;
- // delay until the previous update has certainly been processed.
- futures_timer::Delay::new(std::time::Duration::from_millis(100)).await;
+ // delay until the previous update has certainly been processed.
+ futures_timer::Delay::new(std::time::Duration::from_millis(100)).await;
- handle.set_done();
+ handle.set_done();
- virtual_overseer.send(
- FromOverseer::Signal(OverseerSignal::ActiveLeaves(
- ActiveLeavesUpdate::start_work(ActivatedLeaf {
- hash: hash_b,
- number: 1,
- status: LeafStatus::Fresh,
- span: Arc::new(jaeger::Span::Disabled),
- })
- ))
- ).await;
+ virtual_overseer.send(
+ FromOverseer::Signal(OverseerSignal::ActiveLeaves(
+ ActiveLeavesUpdate::start_work(ActivatedLeaf {
+ hash: hash_b,
+ number: 1,
+ status: LeafStatus::Fresh,
+ span: Arc::new(jaeger::Span::Disabled),
+ })
+ ))
+ ).await;
- handle.await_mode_switch().await;
+ handle.await_mode_switch().await;
- // There should be a mode switch only for the second view update.
- {
- let actions = network_handle.next_network_actions(2).await;
- let wire_message = WireMessage::::ViewUpdate(
- view![hash_a, hash_b]
- ).encode();
+ // There should be a mode switch only for the second view update.
+ {
+ let actions = network_handle.next_network_actions(2).await;
+ let wire_message = WireMessage::::ViewUpdate(
+ view![hash_a, hash_b]
+ ).encode();
- assert_network_actions_contains(
- &actions,
- &NetworkAction::WriteNotification(
- peer_a,
- PeerSet::Validation,
- wire_message.clone(),
- ),
- );
+ assert_network_actions_contains(
+ &actions,
+ &NetworkAction::WriteNotification(
+ peer_a,
+ PeerSet::Validation,
+ wire_message.clone(),
+ ),
+ );
- assert_network_actions_contains(
- &actions,
- &NetworkAction::WriteNotification(
- peer_b,
- PeerSet::Collation,
- wire_message.clone(),
- ),
- );
- }
- virtual_overseer
- });
+ assert_network_actions_contains(
+ &actions,
+ &NetworkAction::WriteNotification(
+ peer_b,
+ PeerSet::Collation,
+ wire_message.clone(),
+ ),
+ );
+ }
+ virtual_overseer
+ });
}
#[test]
fn do_not_send_view_update_when_only_finalized_block_changed() {
- test_harness(done_syncing_oracle(), |test_harness| async move {
- let TestHarness { mut network_handle, mut virtual_overseer } = test_harness;
+ test_harness(done_syncing_oracle(), |test_harness| async move {
+ let TestHarness { mut network_handle, mut virtual_overseer } = test_harness;
- let peer_a = PeerId::random();
- let peer_b = PeerId::random();
+ let peer_a = PeerId::random();
+ let peer_b = PeerId::random();
- network_handle.connect_peer(
- peer_a.clone(),
- PeerSet::Validation,
- ObservedRole::Full,
- ).await;
- network_handle.connect_peer(
- peer_b.clone(),
- PeerSet::Validation,
- ObservedRole::Full,
- ).await;
+ network_handle.connect_peer(
+ peer_a.clone(),
+ PeerSet::Validation,
+ ObservedRole::Full,
+ ).await;
+ network_handle.connect_peer(
+ peer_b.clone(),
+ PeerSet::Validation,
+ ObservedRole::Full,
+ ).await;
- let hash_a = Hash::repeat_byte(1);
+ let hash_a = Hash::repeat_byte(1);
- virtual_overseer.send(FromOverseer::Signal(OverseerSignal::BlockFinalized(Hash::random(), 5))).await;
+ virtual_overseer.send(FromOverseer::Signal(OverseerSignal::BlockFinalized(Hash::random(), 5))).await;
- // Send some empty active leaves update
- //
- // This should not trigger a view update to our peers.
- virtual_overseer.send(
- FromOverseer::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::default()))
- ).await;
+ // Send some empty active leaves update
+ //
+ // This should not trigger a view update to our peers.
+ virtual_overseer.send(
+ FromOverseer::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::default()))
+ ).await;
- // This should trigger the view update to our peers.
- virtual_overseer.send(
- FromOverseer::Signal(OverseerSignal::ActiveLeaves(
- ActiveLeavesUpdate::start_work(ActivatedLeaf {
- hash: hash_a,
- number: 1,
- status: LeafStatus::Fresh,
- span: Arc::new(jaeger::Span::Disabled),
- })
- ))
- ).await;
+ // This should trigger the view update to our peers.
+ virtual_overseer.send(
+ FromOverseer::Signal(OverseerSignal::ActiveLeaves(
+ ActiveLeavesUpdate::start_work(ActivatedLeaf {
+ hash: hash_a,
+ number: 1,
+ status: LeafStatus::Fresh,
+ span: Arc::new(jaeger::Span::Disabled),
+ })
+ ))
+ ).await;
- let actions = network_handle.next_network_actions(4).await;
- let wire_message = WireMessage::::ViewUpdate(
- View::new(vec![hash_a], 5)
- ).encode();
+ let actions = network_handle.next_network_actions(4).await;
+ let wire_message = WireMessage::::ViewUpdate(
+ View::new(vec![hash_a], 5)
+ ).encode();
- assert_network_actions_contains(
- &actions,
- &NetworkAction::WriteNotification(
- peer_a,
- PeerSet::Validation,
- wire_message.clone(),
- ),
- );
+ assert_network_actions_contains(
+ &actions,
+ &NetworkAction::WriteNotification(
+ peer_a,
+ PeerSet::Validation,
+ wire_message.clone(),
+ ),
+ );
- assert_network_actions_contains(
- &actions,
- &NetworkAction::WriteNotification(
- peer_b,
- PeerSet::Validation,
- wire_message.clone(),
- ),
- );
- virtual_overseer
- });
+ assert_network_actions_contains(
+ &actions,
+ &NetworkAction::WriteNotification(
+ peer_b,
+ PeerSet::Validation,
+ wire_message.clone(),
+ ),
+ );
+ virtual_overseer
+ });
}
#[test]
fn peer_view_updates_sent_via_overseer() {
- test_harness(done_syncing_oracle(), |test_harness| async move {
- let TestHarness {
- mut network_handle,
- mut virtual_overseer,
- } = test_harness;
+ test_harness(done_syncing_oracle(), |test_harness| async move {
+ let TestHarness {
+ mut network_handle,
+ mut virtual_overseer,
+ } = test_harness;
- let peer = PeerId::random();
+ let peer = PeerId::random();
- network_handle.connect_peer(peer.clone(), PeerSet::Validation, ObservedRole::Full).await;
+ network_handle.connect_peer(peer.clone(), PeerSet::Validation, ObservedRole::Full).await;
- let view = view![Hash::repeat_byte(1)];
+ let view = view![Hash::repeat_byte(1)];
- assert_matches!(
- virtual_overseer.recv().await,
- AllMessages::StatementDistribution(
- StatementDistributionMessage::StatementFetchingReceiver(_)
- )
- );
+ assert_matches!(
+ virtual_overseer.recv().await,
+ AllMessages::StatementDistribution(
+ StatementDistributionMessage::StatementFetchingReceiver(_)
+ )
+ );
- // bridge will inform about all connected peers.
- {
- assert_sends_validation_event_to_all(
- NetworkBridgeEvent::PeerConnected(peer.clone(), ObservedRole::Full, None),
- &mut virtual_overseer,
- ).await;
+ // bridge will inform about all connected peers.
+ {
+ assert_sends_validation_event_to_all(
+ NetworkBridgeEvent::PeerConnected(peer.clone(), ObservedRole::Full, None),
+ &mut virtual_overseer,
+ ).await;
- assert_sends_validation_event_to_all(
- NetworkBridgeEvent::PeerViewChange(peer.clone(), View::default()),
- &mut virtual_overseer,
- ).await;
- }
+ assert_sends_validation_event_to_all(
+ NetworkBridgeEvent::PeerViewChange(peer.clone(), View::default()),
+ &mut virtual_overseer,
+ ).await;
+ }
- network_handle.peer_message(
- peer.clone(),
- PeerSet::Validation,
- WireMessage::::ViewUpdate(
- view.clone(),
- ).encode(),
- ).await;
+ network_handle.peer_message(
+ peer.clone(),
+ PeerSet::Validation,
+ WireMessage::::ViewUpdate(
+ view.clone(),
+ ).encode(),
+ ).await;
- assert_sends_validation_event_to_all(
- NetworkBridgeEvent::PeerViewChange(peer.clone(), view),
- &mut virtual_overseer,
- ).await;
- virtual_overseer
- });
+ assert_sends_validation_event_to_all(
+ NetworkBridgeEvent::PeerViewChange(peer.clone(), view),
+ &mut virtual_overseer,
+ ).await;
+ virtual_overseer
+ });
}
#[test]
fn peer_messages_sent_via_overseer() {
- test_harness(done_syncing_oracle(), |test_harness| async move {
- let TestHarness {
- mut network_handle,
- mut virtual_overseer,
- } = test_harness;
+ test_harness(done_syncing_oracle(), |test_harness| async move {
+ let TestHarness {
+ mut network_handle,
+ mut virtual_overseer,
+ } = test_harness;
- let peer = PeerId::random();
+ let peer = PeerId::random();
- network_handle.connect_peer(
- peer.clone(),
- PeerSet::Validation,
- ObservedRole::Full,
- ).await;
+ network_handle.connect_peer(
+ peer.clone(),
+ PeerSet::Validation,
+ ObservedRole::Full,
+ ).await;
- assert_matches!(
- virtual_overseer.recv().await,
- AllMessages::StatementDistribution(
- StatementDistributionMessage::StatementFetchingReceiver(_)
- )
- );
+ assert_matches!(
+ virtual_overseer.recv().await,
+ AllMessages::StatementDistribution(
+ StatementDistributionMessage::StatementFetchingReceiver(_)
+ )
+ );
- // bridge will inform about all connected peers.
- {
- assert_sends_validation_event_to_all(
- NetworkBridgeEvent::PeerConnected(peer.clone(), ObservedRole::Full, None),
- &mut virtual_overseer,
- ).await;
+ // bridge will inform about all connected peers.
+ {
+ assert_sends_validation_event_to_all(
+ NetworkBridgeEvent::PeerConnected(peer.clone(), ObservedRole::Full, None),
+ &mut virtual_overseer,
+ ).await;
- assert_sends_validation_event_to_all(
- NetworkBridgeEvent::PeerViewChange(peer.clone(), View::default()),
- &mut virtual_overseer,
- ).await;
- }
+ assert_sends_validation_event_to_all(
+ NetworkBridgeEvent::PeerViewChange(peer.clone(), View::default()),
+ &mut virtual_overseer,
+ ).await;
+ }
- let approval_distribution_message = protocol_v1::ApprovalDistributionMessage::Approvals(
- Vec::new()
- );
+ let approval_distribution_message = protocol_v1::ApprovalDistributionMessage::Approvals(
+ Vec::new()
+ );
- let message = protocol_v1::ValidationProtocol::ApprovalDistribution(
- approval_distribution_message.clone(),
- );
+ let message = protocol_v1::ValidationProtocol::ApprovalDistribution(
+ approval_distribution_message.clone(),
+ );
- network_handle.peer_message(
- peer.clone(),
- PeerSet::Validation,
- WireMessage::ProtocolMessage(message.clone()).encode(),
- ).await;
+ network_handle.peer_message(
+ peer.clone(),
+ PeerSet::Validation,
+ WireMessage::ProtocolMessage(message.clone()).encode(),
+ ).await;
- network_handle.disconnect_peer(peer.clone(), PeerSet::Validation).await;
+ network_handle.disconnect_peer(peer.clone(), PeerSet::Validation).await;
- // Approval distribution message comes first, and the message is only sent to that subsystem.
- // then a disconnection event arises that is sent to all validation networking subsystems.
+ // Approval distribution message comes first, and the message is only sent to that subsystem.
+ // then a disconnection event arises that is sent to all validation networking subsystems.
- assert_matches!(
- virtual_overseer.recv().await,
- AllMessages::ApprovalDistribution(
- ApprovalDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerMessage(p, m)
- )
- ) => {
- assert_eq!(p, peer);
- assert_eq!(m, approval_distribution_message);
- }
- );
+ assert_matches!(
+ virtual_overseer.recv().await,
+ AllMessages::ApprovalDistribution(
+ ApprovalDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerMessage(p, m)
+ )
+ ) => {
+ assert_eq!(p, peer);
+ assert_eq!(m, approval_distribution_message);
+ }
+ );
- assert_sends_validation_event_to_all(
- NetworkBridgeEvent::PeerDisconnected(peer),
- &mut virtual_overseer,
- ).await;
- virtual_overseer
- });
+ assert_sends_validation_event_to_all(
+ NetworkBridgeEvent::PeerDisconnected(peer),
+ &mut virtual_overseer,
+ ).await;
+ virtual_overseer
+ });
}
#[test]
fn peer_disconnect_from_just_one_peerset() {
- test_harness(done_syncing_oracle(), |test_harness| async move {
- let TestHarness {
- mut network_handle,
- mut virtual_overseer,
- } = test_harness;
+ test_harness(done_syncing_oracle(), |test_harness| async move {
+ let TestHarness {
+ mut network_handle,
+ mut virtual_overseer,
+ } = test_harness;
- let peer = PeerId::random();
+ let peer = PeerId::random();
- network_handle.connect_peer(peer.clone(), PeerSet::Validation, ObservedRole::Full).await;
- network_handle.connect_peer(peer.clone(), PeerSet::Collation, ObservedRole::Full).await;
+ network_handle.connect_peer(peer.clone(), PeerSet::Validation, ObservedRole::Full).await;
+ network_handle.connect_peer(peer.clone(), PeerSet::Collation, ObservedRole::Full).await;
- assert_matches!(
- virtual_overseer.recv().await,
- AllMessages::StatementDistribution(
- StatementDistributionMessage::StatementFetchingReceiver(_)
- )
- );
+ assert_matches!(
+ virtual_overseer.recv().await,
+ AllMessages::StatementDistribution(
+ StatementDistributionMessage::StatementFetchingReceiver(_)
+ )
+ );
- // bridge will inform about all connected peers.
- {
- assert_sends_validation_event_to_all(
- NetworkBridgeEvent::PeerConnected(peer.clone(), ObservedRole::Full, None),
- &mut virtual_overseer,
- ).await;
+ // bridge will inform about all connected peers.
+ {
+ assert_sends_validation_event_to_all(
+ NetworkBridgeEvent::PeerConnected(peer.clone(), ObservedRole::Full, None),
+ &mut virtual_overseer,
+ ).await;
- assert_sends_validation_event_to_all(
- NetworkBridgeEvent::PeerViewChange(peer.clone(), View::default()),
- &mut virtual_overseer,
- ).await;
- }
+ assert_sends_validation_event_to_all(
+ NetworkBridgeEvent::PeerViewChange(peer.clone(), View::default()),
+ &mut virtual_overseer,
+ ).await;
+ }
- {
- assert_sends_collation_event_to_all(
- NetworkBridgeEvent::PeerConnected(peer.clone(), ObservedRole::Full, None),
- &mut virtual_overseer,
- ).await;
+ {
+ assert_sends_collation_event_to_all(
+ NetworkBridgeEvent::PeerConnected(peer.clone(), ObservedRole::Full, None),
+ &mut virtual_overseer,
+ ).await;
- assert_sends_collation_event_to_all(
- NetworkBridgeEvent::PeerViewChange(peer.clone(), View::default()),
- &mut virtual_overseer,
- ).await;
- }
+ assert_sends_collation_event_to_all(
+ NetworkBridgeEvent::PeerViewChange(peer.clone(), View::default()),
+ &mut virtual_overseer,
+ ).await;
+ }
- network_handle.disconnect_peer(peer.clone(), PeerSet::Validation).await;
+ network_handle.disconnect_peer(peer.clone(), PeerSet::Validation).await;
- assert_sends_validation_event_to_all(
- NetworkBridgeEvent::PeerDisconnected(peer.clone()),
- &mut virtual_overseer,
- ).await;
+ assert_sends_validation_event_to_all(
+ NetworkBridgeEvent::PeerDisconnected(peer.clone()),
+ &mut virtual_overseer,
+ ).await;
- // to show that we're still connected on the collation protocol, send a view update.
+ // to show that we're still connected on the collation protocol, send a view update.
- let hash_a = Hash::repeat_byte(1);
+ let hash_a = Hash::repeat_byte(1);
- virtual_overseer.send(
- FromOverseer::Signal(OverseerSignal::ActiveLeaves(
- ActiveLeavesUpdate::start_work(ActivatedLeaf {
- hash: hash_a,
- number: 1,
- status: LeafStatus::Fresh,
- span: Arc::new(jaeger::Span::Disabled),
- })
- ))
- ).await;
+ virtual_overseer.send(
+ FromOverseer::Signal(OverseerSignal::ActiveLeaves(
+ ActiveLeavesUpdate::start_work(ActivatedLeaf {
+ hash: hash_a,
+ number: 1,
+ status: LeafStatus::Fresh,
+ span: Arc::new(jaeger::Span::Disabled),
+ })
+ ))
+ ).await;
- let actions = network_handle.next_network_actions(3).await;
- let wire_message = WireMessage::::ViewUpdate(
- view![hash_a]
- ).encode();
+ let actions = network_handle.next_network_actions(3).await;
+ let wire_message = WireMessage::::ViewUpdate(
+ view![hash_a]
+ ).encode();
- assert_network_actions_contains(
- &actions,
- &NetworkAction::WriteNotification(
- peer.clone(),
- PeerSet::Collation,
- wire_message.clone(),
- ),
- );
- virtual_overseer
- });
+ assert_network_actions_contains(
+ &actions,
+ &NetworkAction::WriteNotification(
+ peer.clone(),
+ PeerSet::Collation,
+ wire_message.clone(),
+ ),
+ );
+ virtual_overseer
+ });
}
#[test]
fn relays_collation_protocol_messages() {
- test_harness(done_syncing_oracle(), |test_harness| async move {
- let TestHarness {
- mut network_handle,
- mut virtual_overseer,
- } = test_harness;
+ test_harness(done_syncing_oracle(), |test_harness| async move {
+ let TestHarness {
+ mut network_handle,
+ mut virtual_overseer,
+ } = test_harness;
- let peer_a = PeerId::random();
- let peer_b = PeerId::random();
+ let peer_a = PeerId::random();
+ let peer_b = PeerId::random();
- assert_matches!(
- virtual_overseer.recv().await,
- AllMessages::StatementDistribution(
- StatementDistributionMessage::StatementFetchingReceiver(_)
- )
- );
+ assert_matches!(
+ virtual_overseer.recv().await,
+ AllMessages::StatementDistribution(
+ StatementDistributionMessage::StatementFetchingReceiver(_)
+ )
+ );
- network_handle.connect_peer(peer_a.clone(), PeerSet::Validation, ObservedRole::Full).await;
- network_handle.connect_peer(peer_b.clone(), PeerSet::Collation, ObservedRole::Full).await;
+ network_handle.connect_peer(peer_a.clone(), PeerSet::Validation, ObservedRole::Full).await;
+ network_handle.connect_peer(peer_b.clone(), PeerSet::Collation, ObservedRole::Full).await;
- // bridge will inform about all connected peers.
- {
- assert_sends_validation_event_to_all(
- NetworkBridgeEvent::PeerConnected(peer_a.clone(), ObservedRole::Full, None),
- &mut virtual_overseer,
- ).await;
+ // bridge will inform about all connected peers.
+ {
+ assert_sends_validation_event_to_all(
+ NetworkBridgeEvent::PeerConnected(peer_a.clone(), ObservedRole::Full, None),
+ &mut virtual_overseer,
+ ).await;
- assert_sends_validation_event_to_all(
- NetworkBridgeEvent::PeerViewChange(peer_a.clone(), View::default()),
- &mut virtual_overseer,
- ).await;
- }
+ assert_sends_validation_event_to_all(
+ NetworkBridgeEvent::PeerViewChange(peer_a.clone(), View::default()),
+ &mut virtual_overseer,
+ ).await;
+ }
- {
- assert_sends_collation_event_to_all(
- NetworkBridgeEvent::PeerConnected(peer_b.clone(), ObservedRole::Full, None),
- &mut virtual_overseer,
- ).await;
+ {
+ assert_sends_collation_event_to_all(
+ NetworkBridgeEvent::PeerConnected(peer_b.clone(), ObservedRole::Full, None),
+ &mut virtual_overseer,
+ ).await;
- assert_sends_collation_event_to_all(
- NetworkBridgeEvent::PeerViewChange(peer_b.clone(), View::default()),
- &mut virtual_overseer,
- ).await;
- }
+ assert_sends_collation_event_to_all(
+ NetworkBridgeEvent::PeerViewChange(peer_b.clone(), View::default()),
+ &mut virtual_overseer,
+ ).await;
+ }
- // peer A gets reported for sending a collation message.
+ // peer A gets reported for sending a collation message.
- let collator_protocol_message = protocol_v1::CollatorProtocolMessage::Declare(
- Sr25519Keyring::Alice.public().into(),
- Default::default(),
- Default::default(),
- );
+ let collator_protocol_message = protocol_v1::CollatorProtocolMessage::Declare(
+ Sr25519Keyring::Alice.public().into(),
+ Default::default(),
+ Default::default(),
+ );
- let message = protocol_v1::CollationProtocol::CollatorProtocol(
- collator_protocol_message.clone()
- );
+ let message = protocol_v1::CollationProtocol::CollatorProtocol(
+ collator_protocol_message.clone()
+ );
- network_handle.peer_message(
- peer_a.clone(),
- PeerSet::Collation,
- WireMessage::ProtocolMessage(message.clone()).encode(),
- ).await;
+ network_handle.peer_message(
+ peer_a.clone(),
+ PeerSet::Collation,
+ WireMessage::ProtocolMessage(message.clone()).encode(),
+ ).await;
- let actions = network_handle.next_network_actions(3).await;
- assert_network_actions_contains(
- &actions,
- &NetworkAction::ReputationChange(
- peer_a.clone(),
- UNCONNECTED_PEERSET_COST,
- ),
- );
+ let actions = network_handle.next_network_actions(3).await;
+ assert_network_actions_contains(
+ &actions,
+ &NetworkAction::ReputationChange(
+ peer_a.clone(),
+ UNCONNECTED_PEERSET_COST,
+ ),
+ );
- // peer B has the message relayed.
+ // peer B has the message relayed.
- network_handle.peer_message(
- peer_b.clone(),
- PeerSet::Collation,
- WireMessage::ProtocolMessage(message.clone()).encode(),
- ).await;
+ network_handle.peer_message(
+ peer_b.clone(),
+ PeerSet::Collation,
+ WireMessage::ProtocolMessage(message.clone()).encode(),
+ ).await;
- assert_matches!(
- virtual_overseer.recv().await,
- AllMessages::CollatorProtocol(
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerMessage(p, m)
- )
- ) => {
- assert_eq!(p, peer_b);
- assert_eq!(m, collator_protocol_message);
- }
- );
- virtual_overseer
- });
+ assert_matches!(
+ virtual_overseer.recv().await,
+ AllMessages::CollatorProtocol(
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerMessage(p, m)
+ )
+ ) => {
+ assert_eq!(p, peer_b);
+ assert_eq!(m, collator_protocol_message);
+ }
+ );
+ virtual_overseer
+ });
}
#[test]
fn different_views_on_different_peer_sets() {
- test_harness(done_syncing_oracle(), |test_harness| async move {
- let TestHarness {
- mut network_handle,
- mut virtual_overseer,
- } = test_harness;
+ test_harness(done_syncing_oracle(), |test_harness| async move {
+ let TestHarness {
+ mut network_handle,
+ mut virtual_overseer,
+ } = test_harness;
- let peer = PeerId::random();
+ let peer = PeerId::random();
- network_handle.connect_peer(peer.clone(), PeerSet::Validation, ObservedRole::Full).await;
- network_handle.connect_peer(peer.clone(), PeerSet::Collation, ObservedRole::Full).await;
+ network_handle.connect_peer(peer.clone(), PeerSet::Validation, ObservedRole::Full).await;
+ network_handle.connect_peer(peer.clone(), PeerSet::Collation, ObservedRole::Full).await;
- assert_matches!(
- virtual_overseer.recv().await,
- AllMessages::StatementDistribution(
- StatementDistributionMessage::StatementFetchingReceiver(_)
- )
- );
+ assert_matches!(
+ virtual_overseer.recv().await,
+ AllMessages::StatementDistribution(
+ StatementDistributionMessage::StatementFetchingReceiver(_)
+ )
+ );
- // bridge will inform about all connected peers.
- {
- assert_sends_validation_event_to_all(
- NetworkBridgeEvent::PeerConnected(peer.clone(), ObservedRole::Full, None),
- &mut virtual_overseer,
- ).await;
+ // bridge will inform about all connected peers.
+ {
+ assert_sends_validation_event_to_all(
+ NetworkBridgeEvent::PeerConnected(peer.clone(), ObservedRole::Full, None),
+ &mut virtual_overseer,
+ ).await;
- assert_sends_validation_event_to_all(
- NetworkBridgeEvent::PeerViewChange(peer.clone(), View::default()),
- &mut virtual_overseer,
- ).await;
- }
+ assert_sends_validation_event_to_all(
+ NetworkBridgeEvent::PeerViewChange(peer.clone(), View::default()),
+ &mut virtual_overseer,
+ ).await;
+ }
- {
- assert_sends_collation_event_to_all(
- NetworkBridgeEvent::PeerConnected(peer.clone(), ObservedRole::Full, None),
- &mut virtual_overseer,
- ).await;
+ {
+ assert_sends_collation_event_to_all(
+ NetworkBridgeEvent::PeerConnected(peer.clone(), ObservedRole::Full, None),
+ &mut virtual_overseer,
+ ).await;
- assert_sends_collation_event_to_all(
- NetworkBridgeEvent::PeerViewChange(peer.clone(), View::default()),
- &mut virtual_overseer,
- ).await;
- }
+ assert_sends_collation_event_to_all(
+ NetworkBridgeEvent::PeerViewChange(peer.clone(), View::default()),
+ &mut virtual_overseer,
+ ).await;
+ }
- let view_a = view![Hash::repeat_byte(1)];
- let view_b = view![Hash::repeat_byte(2)];
+ let view_a = view![Hash::repeat_byte(1)];
+ let view_b = view![Hash::repeat_byte(2)];
- network_handle.peer_message(
- peer.clone(),
- PeerSet::Validation,
- WireMessage::::ViewUpdate(view_a.clone()).encode(),
- ).await;
+ network_handle.peer_message(
+ peer.clone(),
+ PeerSet::Validation,
+ WireMessage::::ViewUpdate(view_a.clone()).encode(),
+ ).await;
- network_handle.peer_message(
- peer.clone(),
- PeerSet::Collation,
- WireMessage::::ViewUpdate(view_b.clone()).encode(),
- ).await;
+ network_handle.peer_message(
+ peer.clone(),
+ PeerSet::Collation,
+ WireMessage::::ViewUpdate(view_b.clone()).encode(),
+ ).await;
- assert_sends_validation_event_to_all(
- NetworkBridgeEvent::PeerViewChange(peer.clone(), view_a.clone()),
- &mut virtual_overseer,
- ).await;
+ assert_sends_validation_event_to_all(
+ NetworkBridgeEvent::PeerViewChange(peer.clone(), view_a.clone()),
+ &mut virtual_overseer,
+ ).await;
- assert_sends_collation_event_to_all(
- NetworkBridgeEvent::PeerViewChange(peer.clone(), view_b.clone()),
- &mut virtual_overseer,
- ).await;
- virtual_overseer
- });
+ assert_sends_collation_event_to_all(
+ NetworkBridgeEvent::PeerViewChange(peer.clone(), view_b.clone()),
+ &mut virtual_overseer,
+ ).await;
+ virtual_overseer
+ });
}
#[test]
fn sent_views_include_finalized_number_update() {
- test_harness(done_syncing_oracle(), |test_harness| async move {
- let TestHarness { mut network_handle, mut virtual_overseer } = test_harness;
+ test_harness(done_syncing_oracle(), |test_harness| async move {
+ let TestHarness { mut network_handle, mut virtual_overseer } = test_harness;
- let peer_a = PeerId::random();
+ let peer_a = PeerId::random();
- network_handle.connect_peer(
- peer_a.clone(),
- PeerSet::Validation,
- ObservedRole::Full,
- ).await;
+ network_handle.connect_peer(
+ peer_a.clone(),
+ PeerSet::Validation,
+ ObservedRole::Full,
+ ).await;
- let hash_a = Hash::repeat_byte(1);
- let hash_b = Hash::repeat_byte(2);
+ let hash_a = Hash::repeat_byte(1);
+ let hash_b = Hash::repeat_byte(2);
- virtual_overseer.send(
- FromOverseer::Signal(OverseerSignal::BlockFinalized(hash_a, 1))
- ).await;
- virtual_overseer.send(
- FromOverseer::Signal(OverseerSignal::ActiveLeaves(
- ActiveLeavesUpdate::start_work(ActivatedLeaf {
- hash: hash_b,
- number: 1,
- status: LeafStatus::Fresh,
- span: Arc::new(jaeger::Span::Disabled),
- })
- ))
- ).await;
+ virtual_overseer.send(
+ FromOverseer::Signal(OverseerSignal::BlockFinalized(hash_a, 1))
+ ).await;
+ virtual_overseer.send(
+ FromOverseer::Signal(OverseerSignal::ActiveLeaves(
+ ActiveLeavesUpdate::start_work(ActivatedLeaf {
+ hash: hash_b,
+ number: 1,
+ status: LeafStatus::Fresh,
+ span: Arc::new(jaeger::Span::Disabled),
+ })
+ ))
+ ).await;
- let actions = network_handle.next_network_actions(2).await;
- let wire_message = WireMessage::::ViewUpdate(
- View::new(vec![hash_b], 1)
- ).encode();
+ let actions = network_handle.next_network_actions(2).await;
+ let wire_message = WireMessage::::ViewUpdate(
+ View::new(vec![hash_b], 1)
+ ).encode();
- assert_network_actions_contains(
- &actions,
- &NetworkAction::WriteNotification(
- peer_a.clone(),
- PeerSet::Validation,
- wire_message.clone(),
- ),
- );
- virtual_overseer
- });
+ assert_network_actions_contains(
+ &actions,
+ &NetworkAction::WriteNotification(
+ peer_a.clone(),
+ PeerSet::Validation,
+ wire_message.clone(),
+ ),
+ );
+ virtual_overseer
+ });
}
#[test]
fn view_finalized_number_can_not_go_down() {
- test_harness(done_syncing_oracle(), |test_harness| async move {
- let TestHarness { mut network_handle, virtual_overseer } = test_harness;
+ test_harness(done_syncing_oracle(), |test_harness| async move {
+ let TestHarness { mut network_handle, virtual_overseer } = test_harness;
- let peer_a = PeerId::random();
+ let peer_a = PeerId::random();
- network_handle.connect_peer(
- peer_a.clone(),
- PeerSet::Validation,
- ObservedRole::Full,
- ).await;
+ network_handle.connect_peer(
+ peer_a.clone(),
+ PeerSet::Validation,
+ ObservedRole::Full,
+ ).await;
- network_handle.peer_message(
- peer_a.clone(),
- PeerSet::Validation,
- WireMessage::::ViewUpdate(
- View::new(vec![Hash::repeat_byte(0x01)], 1),
- ).encode(),
- ).await;
+ network_handle.peer_message(
+ peer_a.clone(),
+ PeerSet::Validation,
+ WireMessage::::ViewUpdate(
+ View::new(vec![Hash::repeat_byte(0x01)], 1),
+ ).encode(),
+ ).await;
- network_handle.peer_message(
- peer_a.clone(),
- PeerSet::Validation,
- WireMessage::::ViewUpdate(
- View::new(vec![], 0),
- ).encode(),
- ).await;
+ network_handle.peer_message(
+ peer_a.clone(),
+ PeerSet::Validation,
+ WireMessage::::ViewUpdate(
+ View::new(vec![], 0),
+ ).encode(),
+ ).await;
- let actions = network_handle.next_network_actions(2).await;
- assert_network_actions_contains(
- &actions,
- &NetworkAction::ReputationChange(
- peer_a.clone(),
- MALFORMED_VIEW_COST,
- ),
- );
- virtual_overseer
- });
+ let actions = network_handle.next_network_actions(2).await;
+ assert_network_actions_contains(
+ &actions,
+ &NetworkAction::ReputationChange(
+ peer_a.clone(),
+ MALFORMED_VIEW_COST,
+ ),
+ );
+ virtual_overseer
+ });
}
#[test]
fn send_messages_to_peers() {
- test_harness(done_syncing_oracle(), |test_harness| async move {
- let TestHarness {
- mut network_handle,
- mut virtual_overseer,
- } = test_harness;
+ test_harness(done_syncing_oracle(), |test_harness| async move {
+ let TestHarness {
+ mut network_handle,
+ mut virtual_overseer,
+ } = test_harness;
- let peer = PeerId::random();
+ let peer = PeerId::random();
- network_handle.connect_peer(peer.clone(), PeerSet::Validation, ObservedRole::Full).await;
- network_handle.connect_peer(peer.clone(), PeerSet::Collation, ObservedRole::Full).await;
+ network_handle.connect_peer(peer.clone(), PeerSet::Validation, ObservedRole::Full).await;
+ network_handle.connect_peer(peer.clone(), PeerSet::Collation, ObservedRole::Full).await;
- assert_matches!(
- virtual_overseer.recv().await,
- AllMessages::StatementDistribution(
- StatementDistributionMessage::StatementFetchingReceiver(_)
- )
- );
+ assert_matches!(
+ virtual_overseer.recv().await,
+ AllMessages::StatementDistribution(
+ StatementDistributionMessage::StatementFetchingReceiver(_)
+ )
+ );
- // bridge will inform about all connected peers.
- {
- assert_sends_validation_event_to_all(
- NetworkBridgeEvent::PeerConnected(peer.clone(), ObservedRole::Full, None),
- &mut virtual_overseer,
- ).await;
+ // bridge will inform about all connected peers.
+ {
+ assert_sends_validation_event_to_all(
+ NetworkBridgeEvent::PeerConnected(peer.clone(), ObservedRole::Full, None),
+ &mut virtual_overseer,
+ ).await;
- assert_sends_validation_event_to_all(
- NetworkBridgeEvent::PeerViewChange(peer.clone(), View::default()),
- &mut virtual_overseer,
- ).await;
- }
+ assert_sends_validation_event_to_all(
+ NetworkBridgeEvent::PeerViewChange(peer.clone(), View::default()),
+ &mut virtual_overseer,
+ ).await;
+ }
- {
- assert_sends_collation_event_to_all(
- NetworkBridgeEvent::PeerConnected(peer.clone(), ObservedRole::Full, None),
- &mut virtual_overseer,
- ).await;
+ {
+ assert_sends_collation_event_to_all(
+ NetworkBridgeEvent::PeerConnected(peer.clone(), ObservedRole::Full, None),
+ &mut virtual_overseer,
+ ).await;
- assert_sends_collation_event_to_all(
- NetworkBridgeEvent::PeerViewChange(peer.clone(), View::default()),
- &mut virtual_overseer,
- ).await;
- }
+ assert_sends_collation_event_to_all(
+ NetworkBridgeEvent::PeerViewChange(peer.clone(), View::default()),
+ &mut virtual_overseer,
+ ).await;
+ }
- // consume peer view changes
- {
- let _peer_view_changes = network_handle.next_network_actions(2).await;
- }
+ // consume peer view changes
+ {
+ let _peer_view_changes = network_handle.next_network_actions(2).await;
+ }
- // send a validation protocol message.
+ // send a validation protocol message.
- {
- let approval_distribution_message = protocol_v1::ApprovalDistributionMessage::Approvals(
- Vec::new()
- );
+ {
+ let approval_distribution_message = protocol_v1::ApprovalDistributionMessage::Approvals(
+ Vec::new()
+ );
- let message = protocol_v1::ValidationProtocol::ApprovalDistribution(
- approval_distribution_message.clone(),
- );
+ let message = protocol_v1::ValidationProtocol::ApprovalDistribution(
+ approval_distribution_message.clone(),
+ );
- virtual_overseer.send(FromOverseer::Communication {
- msg: NetworkBridgeMessage::SendValidationMessage(
- vec![peer.clone()],
- message.clone(),
- )
- }).await;
+ virtual_overseer.send(FromOverseer::Communication {
+ msg: NetworkBridgeMessage::SendValidationMessage(
+ vec![peer.clone()],
+ message.clone(),
+ )
+ }).await;
- assert_eq!(
- network_handle.next_network_action().await,
- NetworkAction::WriteNotification(
- peer.clone(),
- PeerSet::Validation,
- WireMessage::ProtocolMessage(message).encode(),
- )
- );
- }
+ assert_eq!(
+ network_handle.next_network_action().await,
+ NetworkAction::WriteNotification(
+ peer.clone(),
+ PeerSet::Validation,
+ WireMessage::ProtocolMessage(message).encode(),
+ )
+ );
+ }
- // send a collation protocol message.
+ // send a collation protocol message.
- {
- let collator_protocol_message = protocol_v1::CollatorProtocolMessage::Declare(
- Sr25519Keyring::Alice.public().into(),
- Default::default(),
- Default::default(),
- );
+ {
+ let collator_protocol_message = protocol_v1::CollatorProtocolMessage::Declare(
+ Sr25519Keyring::Alice.public().into(),
+ Default::default(),
+ Default::default(),
+ );
- let message = protocol_v1::CollationProtocol::CollatorProtocol(
- collator_protocol_message.clone()
- );
+ let message = protocol_v1::CollationProtocol::CollatorProtocol(
+ collator_protocol_message.clone()
+ );
- virtual_overseer.send(FromOverseer::Communication {
- msg: NetworkBridgeMessage::SendCollationMessage(
- vec![peer.clone()],
- message.clone(),
- )
- }).await;
+ virtual_overseer.send(FromOverseer::Communication {
+ msg: NetworkBridgeMessage::SendCollationMessage(
+ vec![peer.clone()],
+ message.clone(),
+ )
+ }).await;
- assert_eq!(
- network_handle.next_network_action().await,
- NetworkAction::WriteNotification(
- peer.clone(),
- PeerSet::Collation,
- WireMessage::ProtocolMessage(message).encode(),
- )
- );
- }
- virtual_overseer
- });
+ assert_eq!(
+ network_handle.next_network_action().await,
+ NetworkAction::WriteNotification(
+ peer.clone(),
+ PeerSet::Collation,
+ WireMessage::ProtocolMessage(message).encode(),
+ )
+ );
+ }
+ virtual_overseer
+ });
}
#[test]
fn spread_event_to_subsystems_is_up_to_date() {
- // Number of subsystems expected to be interested in a network event,
- // and hence the network event broadcasted to.
- const EXPECTED_COUNT: usize = 3;
+ // Number of subsystems expected to be interested in a network event,
+ // and hence the network event broadcasted to.
+ const EXPECTED_COUNT: usize = 3;
- let mut cnt = 0_usize;
- for msg in AllMessages::dispatch_iter(NetworkBridgeEvent::PeerDisconnected(PeerId::random())) {
- match msg {
- AllMessages::CandidateValidation(_) => unreachable!("Not interested in network events"),
- AllMessages::CandidateBacking(_) => unreachable!("Not interested in network events"),
- AllMessages::ChainApi(_) => unreachable!("Not interested in network events"),
- AllMessages::CollatorProtocol(_) => unreachable!("Not interested in network events"),
- AllMessages::StatementDistribution(_) => { cnt += 1; }
- AllMessages::AvailabilityDistribution(_) => unreachable!("Not interested in network events"),
- AllMessages::AvailabilityRecovery(_) => unreachable!("Not interested in network events"),
- AllMessages::BitfieldDistribution(_) => { cnt += 1; }
- AllMessages::BitfieldSigning(_) => unreachable!("Not interested in network events"),
- AllMessages::Provisioner(_) => unreachable!("Not interested in network events"),
- AllMessages::RuntimeApi(_) => unreachable!("Not interested in network events"),
- AllMessages::AvailabilityStore(_) => unreachable!("Not interested in network events"),
- AllMessages::NetworkBridge(_) => unreachable!("Not interested in network events"),
- AllMessages::CollationGeneration(_) => unreachable!("Not interested in network events"),
- AllMessages::ApprovalVoting(_) => unreachable!("Not interested in network events"),
- AllMessages::ApprovalDistribution(_) => { cnt += 1; }
- AllMessages::GossipSupport(_) => unreachable!("Not interested in network events"),
- // Add variants here as needed, `{ cnt += 1; }` for those that need to be
- // notified, `unreachable!()` for those that should not.
- }
- }
- assert_eq!(cnt, EXPECTED_COUNT);
+ let mut cnt = 0_usize;
+ for msg in AllMessages::dispatch_iter(NetworkBridgeEvent::PeerDisconnected(PeerId::random())) {
+ match msg {
+ AllMessages::CandidateValidation(_) => unreachable!("Not interested in network events"),
+ AllMessages::CandidateBacking(_) => unreachable!("Not interested in network events"),
+ AllMessages::ChainApi(_) => unreachable!("Not interested in network events"),
+ AllMessages::CollatorProtocol(_) => unreachable!("Not interested in network events"),
+ AllMessages::StatementDistribution(_) => { cnt += 1; }
+ AllMessages::AvailabilityDistribution(_) => unreachable!("Not interested in network events"),
+ AllMessages::AvailabilityRecovery(_) => unreachable!("Not interested in network events"),
+ AllMessages::BitfieldDistribution(_) => { cnt += 1; }
+ AllMessages::BitfieldSigning(_) => unreachable!("Not interested in network events"),
+ AllMessages::Provisioner(_) => unreachable!("Not interested in network events"),
+ AllMessages::RuntimeApi(_) => unreachable!("Not interested in network events"),
+ AllMessages::AvailabilityStore(_) => unreachable!("Not interested in network events"),
+ AllMessages::NetworkBridge(_) => unreachable!("Not interested in network events"),
+ AllMessages::CollationGeneration(_) => unreachable!("Not interested in network events"),
+ AllMessages::ApprovalVoting(_) => unreachable!("Not interested in network events"),
+ AllMessages::ApprovalDistribution(_) => { cnt += 1; }
+ AllMessages::GossipSupport(_) => unreachable!("Not interested in network events"),
+ // Add variants here as needed, `{ cnt += 1; }` for those that need to be
+ // notified, `unreachable!()` for those that should not.
+ }
+ }
+ assert_eq!(cnt, EXPECTED_COUNT);
}
#[test]
fn our_view_updates_decreasing_order_and_limited_to_max() {
- test_harness(done_syncing_oracle(), |test_harness| async move {
- let TestHarness {
- mut virtual_overseer,
- ..
- } = test_harness;
+ test_harness(done_syncing_oracle(), |test_harness| async move {
+ let TestHarness {
+ mut virtual_overseer,
+ ..
+ } = test_harness;
- // to show that we're still connected on the collation protocol, send a view update.
+ // to show that we're still connected on the collation protocol, send a view update.
- let hashes = (0..MAX_VIEW_HEADS * 3).map(|i| Hash::repeat_byte(i as u8));
+ let hashes = (0..MAX_VIEW_HEADS * 3).map(|i| Hash::repeat_byte(i as u8));
- virtual_overseer.send(
- FromOverseer::Signal(OverseerSignal::ActiveLeaves(
- // These are in reverse order, so the subsystem must sort internally to
- // get the correct view.
- ActiveLeavesUpdate {
- activated: hashes.enumerate().map(|(i, h)| ActivatedLeaf {
- hash: h,
- number: i as _,
- status: LeafStatus::Fresh,
- span: Arc::new(jaeger::Span::Disabled),
- }).rev().collect(),
- deactivated: Default::default(),
- }
- ))
- ).await;
+ virtual_overseer.send(
+ FromOverseer::Signal(OverseerSignal::ActiveLeaves(
+ // These are in reverse order, so the subsystem must sort internally to
+ // get the correct view.
+ ActiveLeavesUpdate {
+ activated: hashes.enumerate().map(|(i, h)| ActivatedLeaf {
+ hash: h,
+ number: i as _,
+ status: LeafStatus::Fresh,
+ span: Arc::new(jaeger::Span::Disabled),
+ }).rev().collect(),
+ deactivated: Default::default(),
+ }
+ ))
+ ).await;
- let view_heads = (MAX_VIEW_HEADS * 2 .. MAX_VIEW_HEADS * 3).rev()
- .map(|i| (Hash::repeat_byte(i as u8), Arc::new(jaeger::Span::Disabled)) );
+ let view_heads = (MAX_VIEW_HEADS * 2 .. MAX_VIEW_HEADS * 3).rev()
+ .map(|i| (Hash::repeat_byte(i as u8), Arc::new(jaeger::Span::Disabled)) );
- let our_view = OurView::new(
- view_heads,
- 0,
- );
+ let our_view = OurView::new(
+ view_heads,
+ 0,
+ );
- assert_matches!(
- virtual_overseer.recv().await,
- AllMessages::StatementDistribution(
- StatementDistributionMessage::StatementFetchingReceiver(_)
- )
- );
+ assert_matches!(
+ virtual_overseer.recv().await,
+ AllMessages::StatementDistribution(
+ StatementDistributionMessage::StatementFetchingReceiver(_)
+ )
+ );
- assert_sends_validation_event_to_all(
- NetworkBridgeEvent::OurViewChange(our_view.clone()),
- &mut virtual_overseer,
- ).await;
+ assert_sends_validation_event_to_all(
+ NetworkBridgeEvent::OurViewChange(our_view.clone()),
+ &mut virtual_overseer,
+ ).await;
- assert_sends_collation_event_to_all(
- NetworkBridgeEvent::OurViewChange(our_view),
- &mut virtual_overseer,
- ).await;
- virtual_overseer
- });
+ assert_sends_collation_event_to_all(
+ NetworkBridgeEvent::OurViewChange(our_view),
+ &mut virtual_overseer,
+ ).await;
+ virtual_overseer
+ });
}
diff --git a/polkadot/node/network/collator-protocol/src/collator_side/mod.rs b/polkadot/node/network/collator-protocol/src/collator_side/mod.rs
index 4e1d3bdbd0..5ddbc8f561 100644
--- a/polkadot/node/network/collator-protocol/src/collator_side/mod.rs
+++ b/polkadot/node/network/collator-protocol/src/collator_side/mod.rs
@@ -44,6 +44,9 @@ use polkadot_node_primitives::{SignedFullStatement, Statement, PoV};
use crate::error::{Fatal, NonFatal, log_error};
use super::{LOG_TARGET, Result};
+#[cfg(test)]
+mod tests;
+
const COST_UNEXPECTED_MESSAGE: Rep = Rep::CostMinor("An unexpected message");
#[derive(Clone, Default)]
@@ -866,6 +869,3 @@ pub(crate) async fn run(
}
}
}
-
-#[cfg(test)]
-mod tests;
diff --git a/polkadot/node/network/collator-protocol/src/validator_side/mod.rs b/polkadot/node/network/collator-protocol/src/validator_side/mod.rs
index a9b6ebe5d5..19f6fffebb 100644
--- a/polkadot/node/network/collator-protocol/src/validator_side/mod.rs
+++ b/polkadot/node/network/collator-protocol/src/validator_side/mod.rs
@@ -50,6 +50,9 @@ use polkadot_subsystem::{
use super::{modify_reputation, Result, LOG_TARGET};
+#[cfg(test)]
+mod tests;
+
const COLLATION_FETCH_TIMEOUT: Duration = Duration::from_secs(2);
const COST_UNEXPECTED_MESSAGE: Rep = Rep::CostMinor("An unexpected message");
@@ -1244,6 +1247,3 @@ where
false
}
}
-
-#[cfg(test)]
-mod tests;
diff --git a/polkadot/node/network/collator-protocol/src/validator_side/tests.rs b/polkadot/node/network/collator-protocol/src/validator_side/tests.rs
index 6ab0b1eb28..a6cfde80ba 100644
--- a/polkadot/node/network/collator-protocol/src/validator_side/tests.rs
+++ b/polkadot/node/network/collator-protocol/src/validator_side/tests.rs
@@ -25,15 +25,15 @@ use sp_keyring::Sr25519Keyring;
use assert_matches::assert_matches;
use polkadot_primitives::v1::{
- CollatorPair, ValidatorId, ValidatorIndex, CoreState, CandidateDescriptor,
- GroupRotationInfo, ScheduledCore, OccupiedCore, GroupIndex,
+ CollatorPair, ValidatorId, ValidatorIndex, CoreState, CandidateDescriptor,
+ GroupRotationInfo, ScheduledCore, OccupiedCore, GroupIndex,
};
use polkadot_node_primitives::BlockData;
use polkadot_node_subsystem_util::TimeoutExt;
use polkadot_subsystem_testhelpers as test_helpers;
use polkadot_subsystem::messages::{RuntimeApiMessage, RuntimeApiRequest};
use polkadot_node_network_protocol::{our_view, ObservedRole,
- request_response::Requests
+ request_response::Requests
};
const ACTIVITY_TIMEOUT: Duration = Duration::from_millis(50);
@@ -41,442 +41,442 @@ const DECLARE_TIMEOUT: Duration = Duration::from_millis(25);
#[derive(Clone)]
struct TestState {
- chain_ids: Vec,
- relay_parent: Hash,
- collators: Vec,
- validators: Vec,
- validator_public: Vec,
- validator_groups: Vec>,
- group_rotation_info: GroupRotationInfo,
- cores: Vec,
+ chain_ids: Vec,
+ relay_parent: Hash,
+ collators: Vec,
+ validators: Vec,
+ validator_public: Vec,
+ validator_groups: Vec>,
+ group_rotation_info: GroupRotationInfo,
+ cores: Vec,
}
impl Default for TestState {
- fn default() -> Self {
- let chain_a = ParaId::from(1);
- let chain_b = ParaId::from(2);
+ fn default() -> Self {
+ let chain_a = ParaId::from(1);
+ let chain_b = ParaId::from(2);
- let chain_ids = vec![chain_a, chain_b];
- let relay_parent = Hash::repeat_byte(0x05);
- let collators = iter::repeat(())
- .map(|_| CollatorPair::generate().0)
- .take(4)
- .collect();
+ let chain_ids = vec![chain_a, chain_b];
+ let relay_parent = Hash::repeat_byte(0x05);
+ let collators = iter::repeat(())
+ .map(|_| CollatorPair::generate().0)
+ .take(4)
+ .collect();
- let validators = vec![
- Sr25519Keyring::Alice,
- Sr25519Keyring::Bob,
- Sr25519Keyring::Charlie,
- Sr25519Keyring::Dave,
- Sr25519Keyring::Eve,
- ];
+ let validators = vec![
+ Sr25519Keyring::Alice,
+ Sr25519Keyring::Bob,
+ Sr25519Keyring::Charlie,
+ Sr25519Keyring::Dave,
+ Sr25519Keyring::Eve,
+ ];
- let validator_public = validators.iter().map(|k| k.public().into()).collect();
- let validator_groups = vec![
- vec![ValidatorIndex(0), ValidatorIndex(1)],
- vec![ValidatorIndex(2), ValidatorIndex(3)],
- vec![ValidatorIndex(4)],
- ];
+ let validator_public = validators.iter().map(|k| k.public().into()).collect();
+ let validator_groups = vec![
+ vec![ValidatorIndex(0), ValidatorIndex(1)],
+ vec![ValidatorIndex(2), ValidatorIndex(3)],
+ vec![ValidatorIndex(4)],
+ ];
- let group_rotation_info = GroupRotationInfo {
- session_start_block: 0,
- group_rotation_frequency: 1,
- now: 0,
- };
+ let group_rotation_info = GroupRotationInfo {
+ session_start_block: 0,
+ group_rotation_frequency: 1,
+ now: 0,
+ };
- let cores = vec![
- CoreState::Scheduled(ScheduledCore {
- para_id: chain_ids[0],
- collator: None,
- }),
- CoreState::Free,
- CoreState::Occupied(OccupiedCore {
- next_up_on_available: None,
- occupied_since: 0,
- time_out_at: 1,
- next_up_on_time_out: None,
- availability: Default::default(),
- group_responsible: GroupIndex(0),
- candidate_hash: Default::default(),
- candidate_descriptor: {
- let mut d = CandidateDescriptor::default();
- d.para_id = chain_ids[1];
+ let cores = vec![
+ CoreState::Scheduled(ScheduledCore {
+ para_id: chain_ids[0],
+ collator: None,
+ }),
+ CoreState::Free,
+ CoreState::Occupied(OccupiedCore {
+ next_up_on_available: None,
+ occupied_since: 0,
+ time_out_at: 1,
+ next_up_on_time_out: None,
+ availability: Default::default(),
+ group_responsible: GroupIndex(0),
+ candidate_hash: Default::default(),
+ candidate_descriptor: {
+ let mut d = CandidateDescriptor::default();
+ d.para_id = chain_ids[1];
- d
- },
- }),
- ];
+ d
+ },
+ }),
+ ];
- Self {
- chain_ids,
- relay_parent,
- collators,
- validators,
- validator_public,
- validator_groups,
- group_rotation_info,
- cores,
- }
- }
+ Self {
+ chain_ids,
+ relay_parent,
+ collators,
+ validators,
+ validator_public,
+ validator_groups,
+ group_rotation_info,
+ cores,
+ }
+ }
}
type VirtualOverseer = test_helpers::TestSubsystemContextHandle;
struct TestHarness {
- virtual_overseer: VirtualOverseer,
+ virtual_overseer: VirtualOverseer,
}
fn test_harness>(test: impl FnOnce(TestHarness) -> T) {
- let _ = env_logger::builder()
- .is_test(true)
- .filter(
- Some("polkadot_collator_protocol"),
- log::LevelFilter::Trace,
- )
- .filter(
- Some(LOG_TARGET),
- log::LevelFilter::Trace,
- )
- .try_init();
+ let _ = env_logger::builder()
+ .is_test(true)
+ .filter(
+ Some("polkadot_collator_protocol"),
+ log::LevelFilter::Trace,
+ )
+ .filter(
+ Some(LOG_TARGET),
+ log::LevelFilter::Trace,
+ )
+ .try_init();
- let pool = sp_core::testing::TaskExecutor::new();
+ let pool = sp_core::testing::TaskExecutor::new();
- let (context, virtual_overseer) = test_helpers::make_subsystem_context(pool.clone());
+ let (context, virtual_overseer) = test_helpers::make_subsystem_context(pool.clone());
- let keystore = TestKeyStore::new();
- keystore.sr25519_generate_new(
- polkadot_primitives::v1::PARACHAIN_KEY_TYPE_ID,
- Some(&Sr25519Keyring::Alice.to_seed()),
- ).unwrap();
+ let keystore = TestKeyStore::new();
+ keystore.sr25519_generate_new(
+ polkadot_primitives::v1::PARACHAIN_KEY_TYPE_ID,
+ Some(&Sr25519Keyring::Alice.to_seed()),
+ ).unwrap();
- let subsystem = run(
- context,
- Arc::new(keystore),
- crate::CollatorEvictionPolicy {
- inactive_collator: ACTIVITY_TIMEOUT,
- undeclared: DECLARE_TIMEOUT,
- },
- Metrics::default(),
- );
+ let subsystem = run(
+ context,
+ Arc::new(keystore),
+ crate::CollatorEvictionPolicy {
+ inactive_collator: ACTIVITY_TIMEOUT,
+ undeclared: DECLARE_TIMEOUT,
+ },
+ Metrics::default(),
+ );
- let test_fut = test(TestHarness { virtual_overseer });
+ let test_fut = test(TestHarness { virtual_overseer });
- futures::pin_mut!(test_fut);
- futures::pin_mut!(subsystem);
+ futures::pin_mut!(test_fut);
+ futures::pin_mut!(subsystem);
- executor::block_on(future::join(async move {
- let mut overseer = test_fut.await;
- overseer_signal(&mut overseer, OverseerSignal::Conclude).await;
- }, subsystem)).1.unwrap();
+ executor::block_on(future::join(async move {
+ let mut overseer = test_fut.await;
+ overseer_signal(&mut overseer, OverseerSignal::Conclude).await;
+ }, subsystem)).1.unwrap();
}
const TIMEOUT: Duration = Duration::from_millis(200);
async fn overseer_send(
- overseer: &mut VirtualOverseer,
- msg: CollatorProtocolMessage,
+ overseer: &mut VirtualOverseer,
+ msg: CollatorProtocolMessage,
) {
- tracing::trace!("Sending message:\n{:?}", &msg);
- overseer
- .send(FromOverseer::Communication { msg })
- .timeout(TIMEOUT)
- .await
- .expect(&format!("{:?} is enough for sending messages.", TIMEOUT));
+ tracing::trace!("Sending message:\n{:?}", &msg);
+ overseer
+ .send(FromOverseer::Communication { msg })
+ .timeout(TIMEOUT)
+ .await
+ .expect(&format!("{:?} is enough for sending messages.", TIMEOUT));
}
async fn overseer_recv(
- overseer: &mut VirtualOverseer,
+ overseer: &mut VirtualOverseer,
) -> AllMessages {
- let msg = overseer_recv_with_timeout(overseer, TIMEOUT)
- .await
- .expect(&format!("{:?} is enough to receive messages.", TIMEOUT));
+ let msg = overseer_recv_with_timeout(overseer, TIMEOUT)
+ .await
+ .expect(&format!("{:?} is enough to receive messages.", TIMEOUT));
- tracing::trace!("Received message:\n{:?}", &msg);
+ tracing::trace!("Received message:\n{:?}", &msg);
- msg
+ msg
}
async fn overseer_recv_with_timeout(
- overseer: &mut VirtualOverseer,
- timeout: Duration,
+ overseer: &mut VirtualOverseer,
+ timeout: Duration,
) -> Option {
- tracing::trace!("Waiting for message...");
- overseer
- .recv()
- .timeout(timeout)
- .await
+ tracing::trace!("Waiting for message...");
+ overseer
+ .recv()
+ .timeout(timeout)
+ .await
}
async fn overseer_signal(
- overseer: &mut VirtualOverseer,
- signal: OverseerSignal,
+ overseer: &mut VirtualOverseer,
+ signal: OverseerSignal,
) {
- overseer
- .send(FromOverseer::Signal(signal))
- .timeout(TIMEOUT)
- .await
- .expect(&format!("{:?} is more than enough for sending signals.", TIMEOUT));
+ overseer
+ .send(FromOverseer::Signal(signal))
+ .timeout(TIMEOUT)
+ .await
+ .expect(&format!("{:?} is more than enough for sending signals.", TIMEOUT));
}
async fn respond_to_core_info_queries(
- virtual_overseer: &mut VirtualOverseer,
- test_state: &TestState,
+ virtual_overseer: &mut VirtualOverseer,
+ test_state: &TestState,
) {
- assert_matches!(
- overseer_recv(virtual_overseer).await,
- AllMessages::RuntimeApi(RuntimeApiMessage::Request(
- _,
- RuntimeApiRequest::Validators(tx),
- )) => {
- let _ = tx.send(Ok(test_state.validator_public.clone()));
- }
- );
+ assert_matches!(
+ overseer_recv(virtual_overseer).await,
+ AllMessages::RuntimeApi(RuntimeApiMessage::Request(
+ _,
+ RuntimeApiRequest::Validators(tx),
+ )) => {
+ let _ = tx.send(Ok(test_state.validator_public.clone()));
+ }
+ );
- assert_matches!(
- overseer_recv(virtual_overseer).await,
- AllMessages::RuntimeApi(RuntimeApiMessage::Request(
- _,
- RuntimeApiRequest::ValidatorGroups(tx),
- )) => {
- let _ = tx.send(Ok((
- test_state.validator_groups.clone(),
- test_state.group_rotation_info.clone(),
- )));
- }
- );
+ assert_matches!(
+ overseer_recv(virtual_overseer).await,
+ AllMessages::RuntimeApi(RuntimeApiMessage::Request(
+ _,
+ RuntimeApiRequest::ValidatorGroups(tx),
+ )) => {
+ let _ = tx.send(Ok((
+ test_state.validator_groups.clone(),
+ test_state.group_rotation_info.clone(),
+ )));
+ }
+ );
- assert_matches!(
- overseer_recv(virtual_overseer).await,
- AllMessages::RuntimeApi(RuntimeApiMessage::Request(
- _,
- RuntimeApiRequest::AvailabilityCores(tx),
- )) => {
- let _ = tx.send(Ok(test_state.cores.clone()));
- }
- );
+ assert_matches!(
+ overseer_recv(virtual_overseer).await,
+ AllMessages::RuntimeApi(RuntimeApiMessage::Request(
+ _,
+ RuntimeApiRequest::AvailabilityCores(tx),
+ )) => {
+ let _ = tx.send(Ok(test_state.cores.clone()));
+ }
+ );
}
// As we receive a relevant advertisement act on it and issue a collation request.
#[test]
fn act_on_advertisement() {
- let test_state = TestState::default();
+ let test_state = TestState::default();
- test_harness(|test_harness| async move {
- let TestHarness {
- mut virtual_overseer,
- } = test_harness;
+ test_harness(|test_harness| async move {
+ let TestHarness {
+ mut virtual_overseer,
+ } = test_harness;
- let pair = CollatorPair::generate().0;
- tracing::trace!("activating");
+ let pair = CollatorPair::generate().0;
+ tracing::trace!("activating");
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent])
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent])
+ )
+ ).await;
- respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
+ respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
- let peer_b = PeerId::random();
+ let peer_b = PeerId::random();
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerConnected(
- peer_b,
- ObservedRole::Full,
- None,
- ),
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerConnected(
+ peer_b,
+ ObservedRole::Full,
+ None,
+ ),
+ )
+ ).await;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerMessage(
- peer_b.clone(),
- protocol_v1::CollatorProtocolMessage::Declare(
- pair.public(),
- test_state.chain_ids[0],
- pair.sign(&protocol_v1::declare_signature_payload(&peer_b)),
- )
- )
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerMessage(
+ peer_b.clone(),
+ protocol_v1::CollatorProtocolMessage::Declare(
+ pair.public(),
+ test_state.chain_ids[0],
+ pair.sign(&protocol_v1::declare_signature_payload(&peer_b)),
+ )
+ )
+ )
+ ).await;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerMessage(
- peer_b.clone(),
- protocol_v1::CollatorProtocolMessage::AdvertiseCollation(
- test_state.relay_parent,
- )
- )
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerMessage(
+ peer_b.clone(),
+ protocol_v1::CollatorProtocolMessage::AdvertiseCollation(
+ test_state.relay_parent,
+ )
+ )
+ )
+ ).await;
- assert_matches!(
- overseer_recv(&mut virtual_overseer).await,
- AllMessages::NetworkBridge(NetworkBridgeMessage::SendRequests(reqs, IfDisconnected::ImmediateError)
- ) => {
- let req = reqs.into_iter().next()
- .expect("There should be exactly one request");
- match req {
- Requests::CollationFetching(req) => {
- let payload = req.payload;
- assert_eq!(payload.relay_parent, test_state.relay_parent);
- assert_eq!(payload.para_id, test_state.chain_ids[0]);
- }
- _ => panic!("Unexpected request"),
- }
- });
+ assert_matches!(
+ overseer_recv(&mut virtual_overseer).await,
+ AllMessages::NetworkBridge(NetworkBridgeMessage::SendRequests(reqs, IfDisconnected::ImmediateError)
+ ) => {
+ let req = reqs.into_iter().next()
+ .expect("There should be exactly one request");
+ match req {
+ Requests::CollationFetching(req) => {
+ let payload = req.payload;
+ assert_eq!(payload.relay_parent, test_state.relay_parent);
+ assert_eq!(payload.para_id, test_state.chain_ids[0]);
+ }
+ _ => panic!("Unexpected request"),
+ }
+ });
- virtual_overseer
- });
+ virtual_overseer
+ });
}
// Test that other subsystems may modify collators' reputations.
#[test]
fn collator_reporting_works() {
- let test_state = TestState::default();
+ let test_state = TestState::default();
- test_harness(|test_harness| async move {
- let TestHarness {
- mut virtual_overseer,
- } = test_harness;
+ test_harness(|test_harness| async move {
+ let TestHarness {
+ mut virtual_overseer,
+ } = test_harness;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent])
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent])
+ )
+ ).await;
- respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
+ respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
- let peer_b = PeerId::random();
- let peer_c = PeerId::random();
+ let peer_b = PeerId::random();
+ let peer_c = PeerId::random();
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerConnected(
- peer_b,
- ObservedRole::Full,
- None,
- ),
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerConnected(
+ peer_b,
+ ObservedRole::Full,
+ None,
+ ),
+ )
+ ).await;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerConnected(
- peer_c,
- ObservedRole::Full,
- None,
- ),
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerConnected(
+ peer_c,
+ ObservedRole::Full,
+ None,
+ ),
+ )
+ ).await;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerMessage(
- peer_b.clone(),
- protocol_v1::CollatorProtocolMessage::Declare(
- test_state.collators[0].public(),
- test_state.chain_ids[0],
- test_state.collators[0].sign(&protocol_v1::declare_signature_payload(&peer_b)),
- ),
- )
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerMessage(
+ peer_b.clone(),
+ protocol_v1::CollatorProtocolMessage::Declare(
+ test_state.collators[0].public(),
+ test_state.chain_ids[0],
+ test_state.collators[0].sign(&protocol_v1::declare_signature_payload(&peer_b)),
+ ),
+ )
+ )
+ ).await;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerMessage(
- peer_c.clone(),
- protocol_v1::CollatorProtocolMessage::Declare(
- test_state.collators[1].public(),
- test_state.chain_ids[0],
- test_state.collators[1].sign(&protocol_v1::declare_signature_payload(&peer_c)),
- ),
- )
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerMessage(
+ peer_c.clone(),
+ protocol_v1::CollatorProtocolMessage::Declare(
+ test_state.collators[1].public(),
+ test_state.chain_ids[0],
+ test_state.collators[1].sign(&protocol_v1::declare_signature_payload(&peer_c)),
+ ),
+ )
+ )
+ ).await;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::ReportCollator(test_state.collators[0].public()),
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::ReportCollator(test_state.collators[0].public()),
+ ).await;
- assert_matches!(
- overseer_recv(&mut virtual_overseer).await,
- AllMessages::NetworkBridge(
- NetworkBridgeMessage::ReportPeer(peer, rep),
- ) => {
- assert_eq!(peer, peer_b);
- assert_eq!(rep, COST_REPORT_BAD);
- }
- );
+ assert_matches!(
+ overseer_recv(&mut virtual_overseer).await,
+ AllMessages::NetworkBridge(
+ NetworkBridgeMessage::ReportPeer(peer, rep),
+ ) => {
+ assert_eq!(peer, peer_b);
+ assert_eq!(rep, COST_REPORT_BAD);
+ }
+ );
- virtual_overseer
- });
+ virtual_overseer
+ });
}
// Test that we verify the signatures on `Declare` and `AdvertiseCollation` messages.
#[test]
fn collator_authentication_verification_works() {
- let test_state = TestState::default();
+ let test_state = TestState::default();
- test_harness(|test_harness| async move {
- let TestHarness {
- mut virtual_overseer,
- } = test_harness;
+ test_harness(|test_harness| async move {
+ let TestHarness {
+ mut virtual_overseer,
+ } = test_harness;
- let peer_b = PeerId::random();
+ let peer_b = PeerId::random();
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerConnected(
- peer_b,
- ObservedRole::Full,
- None,
- ),
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerConnected(
+ peer_b,
+ ObservedRole::Full,
+ None,
+ ),
+ )
+ ).await;
- // the peer sends a declare message but sign the wrong payload
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerMessage(
- peer_b.clone(),
- protocol_v1::CollatorProtocolMessage::Declare(
- test_state.collators[0].public(),
- test_state.chain_ids[0],
- test_state.collators[0].sign(&[42]),
- ),
- )),
- )
- .await;
+ // the peer sends a declare message but sign the wrong payload
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerMessage(
+ peer_b.clone(),
+ protocol_v1::CollatorProtocolMessage::Declare(
+ test_state.collators[0].public(),
+ test_state.chain_ids[0],
+ test_state.collators[0].sign(&[42]),
+ ),
+ )),
+ )
+ .await;
- // it should be reported for sending a message with an invalid signature
- assert_matches!(
- overseer_recv(&mut virtual_overseer).await,
- AllMessages::NetworkBridge(
- NetworkBridgeMessage::ReportPeer(peer, rep),
- ) => {
- assert_eq!(peer, peer_b);
- assert_eq!(rep, COST_INVALID_SIGNATURE);
- }
- );
- virtual_overseer
- });
+ // it should be reported for sending a message with an invalid signature
+ assert_matches!(
+ overseer_recv(&mut virtual_overseer).await,
+ AllMessages::NetworkBridge(
+ NetworkBridgeMessage::ReportPeer(peer, rep),
+ ) => {
+ assert_eq!(peer, peer_b);
+ assert_eq!(rep, COST_INVALID_SIGNATURE);
+ }
+ );
+ virtual_overseer
+ });
}
// A test scenario that takes the following steps
@@ -490,635 +490,635 @@ fn collator_authentication_verification_works() {
// - Collations are fetched correctly.
#[test]
fn fetch_collations_works() {
- let test_state = TestState::default();
+ let test_state = TestState::default();
- test_harness(|test_harness| async move {
- let TestHarness {
- mut virtual_overseer,
- } = test_harness;
+ test_harness(|test_harness| async move {
+ let TestHarness {
+ mut virtual_overseer,
+ } = test_harness;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent])
- ),
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent])
+ ),
+ ).await;
- respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
+ respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
- let peer_b = PeerId::random();
- let peer_c = PeerId::random();
+ let peer_b = PeerId::random();
+ let peer_c = PeerId::random();
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerConnected(
- peer_b,
- ObservedRole::Full,
- None,
- ),
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerConnected(
+ peer_b,
+ ObservedRole::Full,
+ None,
+ ),
+ )
+ ).await;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerConnected(
- peer_c,
- ObservedRole::Full,
- None,
- ),
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerConnected(
+ peer_c,
+ ObservedRole::Full,
+ None,
+ ),
+ )
+ ).await;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerMessage(
- peer_b.clone(),
- protocol_v1::CollatorProtocolMessage::Declare(
- test_state.collators[0].public(),
- test_state.chain_ids[0],
- test_state.collators[0].sign(&protocol_v1::declare_signature_payload(&peer_b)),
- )
- )
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerMessage(
+ peer_b.clone(),
+ protocol_v1::CollatorProtocolMessage::Declare(
+ test_state.collators[0].public(),
+ test_state.chain_ids[0],
+ test_state.collators[0].sign(&protocol_v1::declare_signature_payload(&peer_b)),
+ )
+ )
+ )
+ ).await;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerMessage(
- peer_c.clone(),
- protocol_v1::CollatorProtocolMessage::Declare(
- test_state.collators[1].public(),
- test_state.chain_ids[0],
- test_state.collators[1].sign(&protocol_v1::declare_signature_payload(&peer_c)),
- )
- )
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerMessage(
+ peer_c.clone(),
+ protocol_v1::CollatorProtocolMessage::Declare(
+ test_state.collators[1].public(),
+ test_state.chain_ids[0],
+ test_state.collators[1].sign(&protocol_v1::declare_signature_payload(&peer_c)),
+ )
+ )
+ )
+ ).await;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerMessage(
- peer_b.clone(),
- protocol_v1::CollatorProtocolMessage::AdvertiseCollation(
- test_state.relay_parent,
- )
- )
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerMessage(
+ peer_b.clone(),
+ protocol_v1::CollatorProtocolMessage::AdvertiseCollation(
+ test_state.relay_parent,
+ )
+ )
+ )
+ ).await;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerMessage(
- peer_c.clone(),
- protocol_v1::CollatorProtocolMessage::AdvertiseCollation(
- test_state.relay_parent,
- )
- )
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerMessage(
+ peer_c.clone(),
+ protocol_v1::CollatorProtocolMessage::AdvertiseCollation(
+ test_state.relay_parent,
+ )
+ )
+ )
+ ).await;
- let response_channel = assert_matches!(
- overseer_recv(&mut virtual_overseer).await,
- AllMessages::NetworkBridge(NetworkBridgeMessage::SendRequests(reqs, IfDisconnected::ImmediateError)
- ) => {
- let req = reqs.into_iter().next()
- .expect("There should be exactly one request");
- match req {
- Requests::CollationFetching(req) => {
- let payload = req.payload;
- assert_eq!(payload.relay_parent, test_state.relay_parent);
- assert_eq!(payload.para_id, test_state.chain_ids[0]);
- req.pending_response
- }
- _ => panic!("Unexpected request"),
- }
- });
+ let response_channel = assert_matches!(
+ overseer_recv(&mut virtual_overseer).await,
+ AllMessages::NetworkBridge(NetworkBridgeMessage::SendRequests(reqs, IfDisconnected::ImmediateError)
+ ) => {
+ let req = reqs.into_iter().next()
+ .expect("There should be exactly one request");
+ match req {
+ Requests::CollationFetching(req) => {
+ let payload = req.payload;
+ assert_eq!(payload.relay_parent, test_state.relay_parent);
+ assert_eq!(payload.para_id, test_state.chain_ids[0]);
+ req.pending_response
+ }
+ _ => panic!("Unexpected request"),
+ }
+ });
- let mut candidate_a = CandidateReceipt::default();
- candidate_a.descriptor.para_id = test_state.chain_ids[0];
- candidate_a.descriptor.relay_parent = test_state.relay_parent;
- response_channel.send(Ok(
- CollationFetchingResponse::Collation(
- candidate_a.clone(),
- PoV {
- block_data: BlockData(vec![]),
- },
- ).encode()
- )).expect("Sending response should succeed");
+ let mut candidate_a = CandidateReceipt::default();
+ candidate_a.descriptor.para_id = test_state.chain_ids[0];
+ candidate_a.descriptor.relay_parent = test_state.relay_parent;
+ response_channel.send(Ok(
+ CollationFetchingResponse::Collation(
+ candidate_a.clone(),
+ PoV {
+ block_data: BlockData(vec![]),
+ },
+ ).encode()
+ )).expect("Sending response should succeed");
- let _ = assert_matches!(
- overseer_recv(&mut virtual_overseer).await,
- AllMessages::NetworkBridge(NetworkBridgeMessage::SendRequests(reqs, IfDisconnected::ImmediateError)
- ) => {
- let req = reqs.into_iter().next()
- .expect("There should be exactly one request");
- match req {
- Requests::CollationFetching(req) => {
- let payload = req.payload;
- assert_eq!(payload.relay_parent, test_state.relay_parent);
- assert_eq!(payload.para_id, test_state.chain_ids[0]);
- req.pending_response
- }
- _ => panic!("Unexpected request"),
- }
- });
+ let _ = assert_matches!(
+ overseer_recv(&mut virtual_overseer).await,
+ AllMessages::NetworkBridge(NetworkBridgeMessage::SendRequests(reqs, IfDisconnected::ImmediateError)
+ ) => {
+ let req = reqs.into_iter().next()
+ .expect("There should be exactly one request");
+ match req {
+ Requests::CollationFetching(req) => {
+ let payload = req.payload;
+ assert_eq!(payload.relay_parent, test_state.relay_parent);
+ assert_eq!(payload.para_id, test_state.chain_ids[0]);
+ req.pending_response
+ }
+ _ => panic!("Unexpected request"),
+ }
+ });
- virtual_overseer
- });
+ virtual_overseer
+ });
}
#[test]
fn inactive_disconnected() {
- let test_state = TestState::default();
+ let test_state = TestState::default();
- test_harness(|test_harness| async move {
- let TestHarness {
- mut virtual_overseer,
- } = test_harness;
+ test_harness(|test_harness| async move {
+ let TestHarness {
+ mut virtual_overseer,
+ } = test_harness;
- let pair = CollatorPair::generate().0;
+ let pair = CollatorPair::generate().0;
- let hash_a = test_state.relay_parent;
+ let hash_a = test_state.relay_parent;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::OurViewChange(our_view![hash_a])
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::OurViewChange(our_view![hash_a])
+ )
+ ).await;
- respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
+ respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
- let peer_b = PeerId::random();
+ let peer_b = PeerId::random();
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerConnected(
- peer_b.clone(),
- ObservedRole::Full,
- None,
- )
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerConnected(
+ peer_b.clone(),
+ ObservedRole::Full,
+ None,
+ )
+ )
+ ).await;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerMessage(
- peer_b.clone(),
- protocol_v1::CollatorProtocolMessage::Declare(
- pair.public(),
- test_state.chain_ids[0],
- pair.sign(&protocol_v1::declare_signature_payload(&peer_b)),
- )
- )
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerMessage(
+ peer_b.clone(),
+ protocol_v1::CollatorProtocolMessage::Declare(
+ pair.public(),
+ test_state.chain_ids[0],
+ pair.sign(&protocol_v1::declare_signature_payload(&peer_b)),
+ )
+ )
+ )
+ ).await;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerMessage(
- peer_b.clone(),
- protocol_v1::CollatorProtocolMessage::AdvertiseCollation(
- test_state.relay_parent,
- )
- )
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerMessage(
+ peer_b.clone(),
+ protocol_v1::CollatorProtocolMessage::AdvertiseCollation(
+ test_state.relay_parent,
+ )
+ )
+ )
+ ).await;
- let _ = assert_matches!(
- overseer_recv(&mut virtual_overseer).await,
- AllMessages::NetworkBridge(NetworkBridgeMessage::SendRequests(reqs, IfDisconnected::ImmediateError)
- ) => {
- let req = reqs.into_iter().next()
- .expect("There should be exactly one request");
- match req {
- Requests::CollationFetching(req) => {
- let payload = req.payload;
- assert_eq!(payload.relay_parent, test_state.relay_parent);
- assert_eq!(payload.para_id, test_state.chain_ids[0]);
- req.pending_response
- }
- _ => panic!("Unexpected request"),
- }
- });
+ let _ = assert_matches!(
+ overseer_recv(&mut virtual_overseer).await,
+ AllMessages::NetworkBridge(NetworkBridgeMessage::SendRequests(reqs, IfDisconnected::ImmediateError)
+ ) => {
+ let req = reqs.into_iter().next()
+ .expect("There should be exactly one request");
+ match req {
+ Requests::CollationFetching(req) => {
+ let payload = req.payload;
+ assert_eq!(payload.relay_parent, test_state.relay_parent);
+ assert_eq!(payload.para_id, test_state.chain_ids[0]);
+ req.pending_response
+ }
+ _ => panic!("Unexpected request"),
+ }
+ });
- Delay::new(ACTIVITY_TIMEOUT * 3).await;
+ Delay::new(ACTIVITY_TIMEOUT * 3).await;
- assert_matches!(
- overseer_recv(&mut virtual_overseer).await,
- AllMessages::NetworkBridge(NetworkBridgeMessage::ReportPeer(
- peer,
- rep,
- )) => {
- assert_eq!(peer, peer_b);
- assert_eq!(rep, COST_REQUEST_TIMED_OUT);
- }
- );
+ assert_matches!(
+ overseer_recv(&mut virtual_overseer).await,
+ AllMessages::NetworkBridge(NetworkBridgeMessage::ReportPeer(
+ peer,
+ rep,
+ )) => {
+ assert_eq!(peer, peer_b);
+ assert_eq!(rep, COST_REQUEST_TIMED_OUT);
+ }
+ );
- assert_matches!(
- overseer_recv(&mut virtual_overseer).await,
- AllMessages::NetworkBridge(NetworkBridgeMessage::DisconnectPeer(
- peer,
- peer_set,
- )) => {
- assert_eq!(peer, peer_b);
- assert_eq!(peer_set, PeerSet::Collation);
- }
- );
- virtual_overseer
- });
+ assert_matches!(
+ overseer_recv(&mut virtual_overseer).await,
+ AllMessages::NetworkBridge(NetworkBridgeMessage::DisconnectPeer(
+ peer,
+ peer_set,
+ )) => {
+ assert_eq!(peer, peer_b);
+ assert_eq!(peer_set, PeerSet::Collation);
+ }
+ );
+ virtual_overseer
+ });
}
#[test]
fn activity_extends_life() {
- let test_state = TestState::default();
+ let test_state = TestState::default();
- test_harness(|test_harness| async move {
- let TestHarness {
- mut virtual_overseer,
- } = test_harness;
+ test_harness(|test_harness| async move {
+ let TestHarness {
+ mut virtual_overseer,
+ } = test_harness;
- let pair = CollatorPair::generate().0;
+ let pair = CollatorPair::generate().0;
- let hash_a = test_state.relay_parent;
- let hash_b = Hash::repeat_byte(1);
- let hash_c = Hash::repeat_byte(2);
+ let hash_a = test_state.relay_parent;
+ let hash_b = Hash::repeat_byte(1);
+ let hash_c = Hash::repeat_byte(2);
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::OurViewChange(our_view![hash_a, hash_b, hash_c])
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::OurViewChange(our_view![hash_a, hash_b, hash_c])
+ )
+ ).await;
- // 3 heads, 3 times.
- respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
- respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
- respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
+ // 3 heads, 3 times.
+ respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
+ respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
+ respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
- let peer_b = PeerId::random();
+ let peer_b = PeerId::random();
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerConnected(
- peer_b.clone(),
- ObservedRole::Full,
- None,
- )
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerConnected(
+ peer_b.clone(),
+ ObservedRole::Full,
+ None,
+ )
+ )
+ ).await;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerMessage(
- peer_b.clone(),
- protocol_v1::CollatorProtocolMessage::Declare(
- pair.public(),
- test_state.chain_ids[0],
- pair.sign(&protocol_v1::declare_signature_payload(&peer_b)),
- )
- )
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerMessage(
+ peer_b.clone(),
+ protocol_v1::CollatorProtocolMessage::Declare(
+ pair.public(),
+ test_state.chain_ids[0],
+ pair.sign(&protocol_v1::declare_signature_payload(&peer_b)),
+ )
+ )
+ )
+ ).await;
- Delay::new(ACTIVITY_TIMEOUT * 2 / 3).await;
+ Delay::new(ACTIVITY_TIMEOUT * 2 / 3).await;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerMessage(
- peer_b.clone(),
- protocol_v1::CollatorProtocolMessage::AdvertiseCollation(
- hash_a,
- )
- )
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerMessage(
+ peer_b.clone(),
+ protocol_v1::CollatorProtocolMessage::AdvertiseCollation(
+ hash_a,
+ )
+ )
+ )
+ ).await;
- assert_matches!(
- overseer_recv(&mut virtual_overseer).await,
- AllMessages::NetworkBridge(NetworkBridgeMessage::SendRequests(reqs, IfDisconnected::ImmediateError)
- ) => {
- let req = reqs.into_iter().next()
- .expect("There should be exactly one request");
- match req {
- Requests::CollationFetching(req) => {
- let payload = req.payload;
- assert_eq!(payload.relay_parent, hash_a);
- assert_eq!(payload.para_id, test_state.chain_ids[0]);
- }
- _ => panic!("Unexpected request"),
- }
- });
+ assert_matches!(
+ overseer_recv(&mut virtual_overseer).await,
+ AllMessages::NetworkBridge(NetworkBridgeMessage::SendRequests(reqs, IfDisconnected::ImmediateError)
+ ) => {
+ let req = reqs.into_iter().next()
+ .expect("There should be exactly one request");
+ match req {
+ Requests::CollationFetching(req) => {
+ let payload = req.payload;
+ assert_eq!(payload.relay_parent, hash_a);
+ assert_eq!(payload.para_id, test_state.chain_ids[0]);
+ }
+ _ => panic!("Unexpected request"),
+ }
+ });
- Delay::new(ACTIVITY_TIMEOUT * 2 / 3).await;
+ Delay::new(ACTIVITY_TIMEOUT * 2 / 3).await;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerMessage(
- peer_b.clone(),
- protocol_v1::CollatorProtocolMessage::AdvertiseCollation(
- hash_b
- )
- )
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerMessage(
+ peer_b.clone(),
+ protocol_v1::CollatorProtocolMessage::AdvertiseCollation(
+ hash_b
+ )
+ )
+ )
+ ).await;
- assert_matches!(
- overseer_recv(&mut virtual_overseer).await,
- AllMessages::NetworkBridge(NetworkBridgeMessage::ReportPeer(
- peer,
- rep,
- )) => {
- assert_eq!(peer, peer_b);
- assert_eq!(rep, COST_REQUEST_TIMED_OUT);
- }
- );
+ assert_matches!(
+ overseer_recv(&mut virtual_overseer).await,
+ AllMessages::NetworkBridge(NetworkBridgeMessage::ReportPeer(
+ peer,
+ rep,
+ )) => {
+ assert_eq!(peer, peer_b);
+ assert_eq!(rep, COST_REQUEST_TIMED_OUT);
+ }
+ );
- assert_matches!(
- overseer_recv(&mut virtual_overseer).await,
- AllMessages::NetworkBridge(NetworkBridgeMessage::SendRequests(reqs, IfDisconnected::ImmediateError)
- ) => {
- let req = reqs.into_iter().next()
- .expect("There should be exactly one request");
- match req {
- Requests::CollationFetching(req) => {
- let payload = req.payload;
- assert_eq!(payload.relay_parent, hash_b);
- assert_eq!(payload.para_id, test_state.chain_ids[0]);
- }
- _ => panic!("Unexpected request"),
- }
- });
+ assert_matches!(
+ overseer_recv(&mut virtual_overseer).await,
+ AllMessages::NetworkBridge(NetworkBridgeMessage::SendRequests(reqs, IfDisconnected::ImmediateError)
+ ) => {
+ let req = reqs.into_iter().next()
+ .expect("There should be exactly one request");
+ match req {
+ Requests::CollationFetching(req) => {
+ let payload = req.payload;
+ assert_eq!(payload.relay_parent, hash_b);
+ assert_eq!(payload.para_id, test_state.chain_ids[0]);
+ }
+ _ => panic!("Unexpected request"),
+ }
+ });
- Delay::new(ACTIVITY_TIMEOUT * 2 / 3).await;
+ Delay::new(ACTIVITY_TIMEOUT * 2 / 3).await;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerMessage(
- peer_b.clone(),
- protocol_v1::CollatorProtocolMessage::AdvertiseCollation(
- hash_c,
- )
- )
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerMessage(
+ peer_b.clone(),
+ protocol_v1::CollatorProtocolMessage::AdvertiseCollation(
+ hash_c,
+ )
+ )
+ )
+ ).await;
- assert_matches!(
- overseer_recv(&mut virtual_overseer).await,
- AllMessages::NetworkBridge(NetworkBridgeMessage::ReportPeer(
- peer,
- rep,
- )) => {
- assert_eq!(peer, peer_b);
- assert_eq!(rep, COST_REQUEST_TIMED_OUT);
- }
- );
+ assert_matches!(
+ overseer_recv(&mut virtual_overseer).await,
+ AllMessages::NetworkBridge(NetworkBridgeMessage::ReportPeer(
+ peer,
+ rep,
+ )) => {
+ assert_eq!(peer, peer_b);
+ assert_eq!(rep, COST_REQUEST_TIMED_OUT);
+ }
+ );
- assert_matches!(
- overseer_recv(&mut virtual_overseer).await,
- AllMessages::NetworkBridge(NetworkBridgeMessage::SendRequests(reqs, IfDisconnected::ImmediateError)
- ) => {
- let req = reqs.into_iter().next()
- .expect("There should be exactly one request");
- match req {
- Requests::CollationFetching(req) => {
- let payload = req.payload;
- assert_eq!(payload.relay_parent, hash_c);
- assert_eq!(payload.para_id, test_state.chain_ids[0]);
- }
- _ => panic!("Unexpected request"),
- }
- });
+ assert_matches!(
+ overseer_recv(&mut virtual_overseer).await,
+ AllMessages::NetworkBridge(NetworkBridgeMessage::SendRequests(reqs, IfDisconnected::ImmediateError)
+ ) => {
+ let req = reqs.into_iter().next()
+ .expect("There should be exactly one request");
+ match req {
+ Requests::CollationFetching(req) => {
+ let payload = req.payload;
+ assert_eq!(payload.relay_parent, hash_c);
+ assert_eq!(payload.para_id, test_state.chain_ids[0]);
+ }
+ _ => panic!("Unexpected request"),
+ }
+ });
- Delay::new(ACTIVITY_TIMEOUT * 3 / 2).await;
+ Delay::new(ACTIVITY_TIMEOUT * 3 / 2).await;
- assert_matches!(
- overseer_recv(&mut virtual_overseer).await,
- AllMessages::NetworkBridge(NetworkBridgeMessage::ReportPeer(
- peer,
- rep,
- )) => {
- assert_eq!(peer, peer_b);
- assert_eq!(rep, COST_REQUEST_TIMED_OUT);
- }
- );
+ assert_matches!(
+ overseer_recv(&mut virtual_overseer).await,
+ AllMessages::NetworkBridge(NetworkBridgeMessage::ReportPeer(
+ peer,
+ rep,
+ )) => {
+ assert_eq!(peer, peer_b);
+ assert_eq!(rep, COST_REQUEST_TIMED_OUT);
+ }
+ );
- assert_matches!(
- overseer_recv(&mut virtual_overseer).await,
- AllMessages::NetworkBridge(NetworkBridgeMessage::DisconnectPeer(
- peer,
- peer_set,
- )) => {
- assert_eq!(peer, peer_b);
- assert_eq!(peer_set, PeerSet::Collation);
- }
- );
- virtual_overseer
- });
+ assert_matches!(
+ overseer_recv(&mut virtual_overseer).await,
+ AllMessages::NetworkBridge(NetworkBridgeMessage::DisconnectPeer(
+ peer,
+ peer_set,
+ )) => {
+ assert_eq!(peer, peer_b);
+ assert_eq!(peer_set, PeerSet::Collation);
+ }
+ );
+ virtual_overseer
+ });
}
#[test]
fn disconnect_if_no_declare() {
- let test_state = TestState::default();
+ let test_state = TestState::default();
- test_harness(|test_harness| async move {
- let TestHarness {
- mut virtual_overseer,
- } = test_harness;
+ test_harness(|test_harness| async move {
+ let TestHarness {
+ mut virtual_overseer,
+ } = test_harness;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent])
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent])
+ )
+ ).await;
- respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
+ respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
- let peer_b = PeerId::random();
+ let peer_b = PeerId::random();
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerConnected(
- peer_b.clone(),
- ObservedRole::Full,
- None,
- )
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerConnected(
+ peer_b.clone(),
+ ObservedRole::Full,
+ None,
+ )
+ )
+ ).await;
- assert_matches!(
- overseer_recv(&mut virtual_overseer).await,
- AllMessages::NetworkBridge(NetworkBridgeMessage::DisconnectPeer(
- peer,
- peer_set,
- )) => {
- assert_eq!(peer, peer_b);
- assert_eq!(peer_set, PeerSet::Collation);
- }
- );
- virtual_overseer
- })
+ assert_matches!(
+ overseer_recv(&mut virtual_overseer).await,
+ AllMessages::NetworkBridge(NetworkBridgeMessage::DisconnectPeer(
+ peer,
+ peer_set,
+ )) => {
+ assert_eq!(peer, peer_b);
+ assert_eq!(peer_set, PeerSet::Collation);
+ }
+ );
+ virtual_overseer
+ })
}
#[test]
fn disconnect_if_wrong_declare() {
- let test_state = TestState::default();
+ let test_state = TestState::default();
- test_harness(|test_harness| async move {
- let TestHarness {
- mut virtual_overseer,
- } = test_harness;
+ test_harness(|test_harness| async move {
+ let TestHarness {
+ mut virtual_overseer,
+ } = test_harness;
- let pair = CollatorPair::generate().0;
+ let pair = CollatorPair::generate().0;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent])
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent])
+ )
+ ).await;
- respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
+ respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
- let peer_b = PeerId::random();
+ let peer_b = PeerId::random();
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerConnected(
- peer_b.clone(),
- ObservedRole::Full,
- None,
- )
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerConnected(
+ peer_b.clone(),
+ ObservedRole::Full,
+ None,
+ )
+ )
+ ).await;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerMessage(
- peer_b.clone(),
- protocol_v1::CollatorProtocolMessage::Declare(
- pair.public(),
- ParaId::from(69),
- pair.sign(&protocol_v1::declare_signature_payload(&peer_b)),
- )
- )
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerMessage(
+ peer_b.clone(),
+ protocol_v1::CollatorProtocolMessage::Declare(
+ pair.public(),
+ ParaId::from(69),
+ pair.sign(&protocol_v1::declare_signature_payload(&peer_b)),
+ )
+ )
+ )
+ ).await;
- assert_matches!(
- overseer_recv(&mut virtual_overseer).await,
- AllMessages::NetworkBridge(NetworkBridgeMessage::ReportPeer(
- peer,
- rep,
- )) => {
- assert_eq!(peer, peer_b);
- assert_eq!(rep, COST_UNNEEDED_COLLATOR);
- }
- );
+ assert_matches!(
+ overseer_recv(&mut virtual_overseer).await,
+ AllMessages::NetworkBridge(NetworkBridgeMessage::ReportPeer(
+ peer,
+ rep,
+ )) => {
+ assert_eq!(peer, peer_b);
+ assert_eq!(rep, COST_UNNEEDED_COLLATOR);
+ }
+ );
- assert_matches!(
- overseer_recv(&mut virtual_overseer).await,
- AllMessages::NetworkBridge(NetworkBridgeMessage::DisconnectPeer(
- peer,
- peer_set,
- )) => {
- assert_eq!(peer, peer_b);
- assert_eq!(peer_set, PeerSet::Collation);
- }
- );
- virtual_overseer
- })
+ assert_matches!(
+ overseer_recv(&mut virtual_overseer).await,
+ AllMessages::NetworkBridge(NetworkBridgeMessage::DisconnectPeer(
+ peer,
+ peer_set,
+ )) => {
+ assert_eq!(peer, peer_b);
+ assert_eq!(peer_set, PeerSet::Collation);
+ }
+ );
+ virtual_overseer
+ })
}
#[test]
fn view_change_clears_old_collators() {
- let mut test_state = TestState::default();
+ let mut test_state = TestState::default();
- test_harness(|test_harness| async move {
- let TestHarness {
- mut virtual_overseer,
- } = test_harness;
+ test_harness(|test_harness| async move {
+ let TestHarness {
+ mut virtual_overseer,
+ } = test_harness;
- let pair = CollatorPair::generate().0;
+ let pair = CollatorPair::generate().0;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent])
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent])
+ )
+ ).await;
- respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
+ respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
- let peer_b = PeerId::random();
+ let peer_b = PeerId::random();
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerConnected(
- peer_b.clone(),
- ObservedRole::Full,
- None,
- )
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerConnected(
+ peer_b.clone(),
+ ObservedRole::Full,
+ None,
+ )
+ )
+ ).await;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerMessage(
- peer_b.clone(),
- protocol_v1::CollatorProtocolMessage::Declare(
- pair.public(),
- test_state.chain_ids[0],
- pair.sign(&protocol_v1::declare_signature_payload(&peer_b)),
- )
- )
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerMessage(
+ peer_b.clone(),
+ protocol_v1::CollatorProtocolMessage::Declare(
+ pair.public(),
+ test_state.chain_ids[0],
+ pair.sign(&protocol_v1::declare_signature_payload(&peer_b)),
+ )
+ )
+ )
+ ).await;
- let hash_b = Hash::repeat_byte(69);
+ let hash_b = Hash::repeat_byte(69);
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::OurViewChange(our_view![hash_b])
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::OurViewChange(our_view![hash_b])
+ )
+ ).await;
- test_state.group_rotation_info = test_state.group_rotation_info.bump_rotation();
- respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
+ test_state.group_rotation_info = test_state.group_rotation_info.bump_rotation();
+ respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
- assert_matches!(
- overseer_recv(&mut virtual_overseer).await,
- AllMessages::NetworkBridge(NetworkBridgeMessage::DisconnectPeer(
- peer,
- peer_set,
- )) => {
- assert_eq!(peer, peer_b);
- assert_eq!(peer_set, PeerSet::Collation);
- }
- );
- virtual_overseer
- })
+ assert_matches!(
+ overseer_recv(&mut virtual_overseer).await,
+ AllMessages::NetworkBridge(NetworkBridgeMessage::DisconnectPeer(
+ peer,
+ peer_set,
+ )) => {
+ assert_eq!(peer, peer_b);
+ assert_eq!(peer_set, PeerSet::Collation);
+ }
+ );
+ virtual_overseer
+ })
}
// A test scenario that takes the following steps
@@ -1132,177 +1132,177 @@ fn view_change_clears_old_collators() {
// - Collations are fetched correctly.
#[test]
fn seconding_works() {
- let test_state = TestState::default();
+ let test_state = TestState::default();
- test_harness(|test_harness| async move {
- let TestHarness {
- mut virtual_overseer,
- } = test_harness;
+ test_harness(|test_harness| async move {
+ let TestHarness {
+ mut virtual_overseer,
+ } = test_harness;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent])
- ),
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent])
+ ),
+ ).await;
- respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
+ respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
- let peer_b = PeerId::random();
- let peer_c = PeerId::random();
+ let peer_b = PeerId::random();
+ let peer_c = PeerId::random();
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerConnected(
- peer_b,
- ObservedRole::Full,
- None,
- ),
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerConnected(
+ peer_b,
+ ObservedRole::Full,
+ None,
+ ),
+ )
+ ).await;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerConnected(
- peer_c,
- ObservedRole::Full,
- None,
- ),
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerConnected(
+ peer_c,
+ ObservedRole::Full,
+ None,
+ ),
+ )
+ ).await;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerMessage(
- peer_b.clone(),
- protocol_v1::CollatorProtocolMessage::Declare(
- test_state.collators[0].public(),
- test_state.chain_ids[0],
- test_state.collators[0].sign(&protocol_v1::declare_signature_payload(&peer_b)),
- )
- )
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerMessage(
+ peer_b.clone(),
+ protocol_v1::CollatorProtocolMessage::Declare(
+ test_state.collators[0].public(),
+ test_state.chain_ids[0],
+ test_state.collators[0].sign(&protocol_v1::declare_signature_payload(&peer_b)),
+ )
+ )
+ )
+ ).await;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerMessage(
- peer_c.clone(),
- protocol_v1::CollatorProtocolMessage::Declare(
- test_state.collators[1].public(),
- test_state.chain_ids[0],
- test_state.collators[1].sign(&protocol_v1::declare_signature_payload(&peer_c)),
- )
- )
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerMessage(
+ peer_c.clone(),
+ protocol_v1::CollatorProtocolMessage::Declare(
+ test_state.collators[1].public(),
+ test_state.chain_ids[0],
+ test_state.collators[1].sign(&protocol_v1::declare_signature_payload(&peer_c)),
+ )
+ )
+ )
+ ).await;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerMessage(
- peer_b.clone(),
- protocol_v1::CollatorProtocolMessage::AdvertiseCollation(
- test_state.relay_parent,
- )
- )
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerMessage(
+ peer_b.clone(),
+ protocol_v1::CollatorProtocolMessage::AdvertiseCollation(
+ test_state.relay_parent,
+ )
+ )
+ )
+ ).await;
- overseer_send(
- &mut virtual_overseer,
- CollatorProtocolMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerMessage(
- peer_c.clone(),
- protocol_v1::CollatorProtocolMessage::AdvertiseCollation(
- test_state.relay_parent,
- )
- )
- )
- ).await;
+ overseer_send(
+ &mut virtual_overseer,
+ CollatorProtocolMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerMessage(
+ peer_c.clone(),
+ protocol_v1::CollatorProtocolMessage::AdvertiseCollation(
+ test_state.relay_parent,
+ )
+ )
+ )
+ ).await;
- let response_channel = assert_matches!(
- overseer_recv(&mut virtual_overseer).await,
- AllMessages::NetworkBridge(NetworkBridgeMessage::SendRequests(reqs, IfDisconnected::ImmediateError)
- ) => {
- let req = reqs.into_iter().next()
- .expect("There should be exactly one request");
- match req {
- Requests::CollationFetching(req) => {
- let payload = req.payload;
- assert_eq!(payload.relay_parent, test_state.relay_parent);
- assert_eq!(payload.para_id, test_state.chain_ids[0]);
- req.pending_response
- }
- _ => panic!("Unexpected request"),
- }
- });
+ let response_channel = assert_matches!(
+ overseer_recv(&mut virtual_overseer).await,
+ AllMessages::NetworkBridge(NetworkBridgeMessage::SendRequests(reqs, IfDisconnected::ImmediateError)
+ ) => {
+ let req = reqs.into_iter().next()
+ .expect("There should be exactly one request");
+ match req {
+ Requests::CollationFetching(req) => {
+ let payload = req.payload;
+ assert_eq!(payload.relay_parent, test_state.relay_parent);
+ assert_eq!(payload.para_id, test_state.chain_ids[0]);
+ req.pending_response
+ }
+ _ => panic!("Unexpected request"),
+ }
+ });
- let mut candidate_a = CandidateReceipt::default();
- // Memoize PoV data to ensure we receive the right one
- let pov = PoV {
- block_data: BlockData(vec![1, 2, 3, 4, 5]),
- };
- candidate_a.descriptor.para_id = test_state.chain_ids[0];
- candidate_a.descriptor.relay_parent = test_state.relay_parent;
- response_channel.send(Ok(
- CollationFetchingResponse::Collation(
- candidate_a.clone(),
- pov.clone(),
- ).encode()
- )).expect("Sending response should succeed");
+ let mut candidate_a = CandidateReceipt::default();
+ // Memoize PoV data to ensure we receive the right one
+ let pov = PoV {
+ block_data: BlockData(vec![1, 2, 3, 4, 5]),
+ };
+ candidate_a.descriptor.para_id = test_state.chain_ids[0];
+ candidate_a.descriptor.relay_parent = test_state.relay_parent;
+ response_channel.send(Ok(
+ CollationFetchingResponse::Collation(
+ candidate_a.clone(),
+ pov.clone(),
+ ).encode()
+ )).expect("Sending response should succeed");
- let response_channel = assert_matches!(
- overseer_recv(&mut virtual_overseer).await,
- AllMessages::NetworkBridge(NetworkBridgeMessage::SendRequests(reqs, IfDisconnected::ImmediateError)
- ) => {
- let req = reqs.into_iter().next()
- .expect("There should be exactly one request");
- match req {
- Requests::CollationFetching(req) => {
- let payload = req.payload;
- assert_eq!(payload.relay_parent, test_state.relay_parent);
- assert_eq!(payload.para_id, test_state.chain_ids[0]);
- req.pending_response
- }
- _ => panic!("Unexpected request"),
- }
- });
+ let response_channel = assert_matches!(
+ overseer_recv(&mut virtual_overseer).await,
+ AllMessages::NetworkBridge(NetworkBridgeMessage::SendRequests(reqs, IfDisconnected::ImmediateError)
+ ) => {
+ let req = reqs.into_iter().next()
+ .expect("There should be exactly one request");
+ match req {
+ Requests::CollationFetching(req) => {
+ let payload = req.payload;
+ assert_eq!(payload.relay_parent, test_state.relay_parent);
+ assert_eq!(payload.para_id, test_state.chain_ids[0]);
+ req.pending_response
+ }
+ _ => panic!("Unexpected request"),
+ }
+ });
- assert_matches!(
- overseer_recv(&mut virtual_overseer).await,
- AllMessages::CandidateBacking(CandidateBackingMessage::Second(relay_parent, candidate_receipt, incoming_pov)
- ) => {
- assert_eq!(relay_parent, test_state.relay_parent);
- assert_eq!(candidate_receipt.descriptor.para_id, test_state.chain_ids[0]);
- assert_eq!(incoming_pov, pov);
- });
+ assert_matches!(
+ overseer_recv(&mut virtual_overseer).await,
+ AllMessages::CandidateBacking(CandidateBackingMessage::Second(relay_parent, candidate_receipt, incoming_pov)
+ ) => {
+ assert_eq!(relay_parent, test_state.relay_parent);
+ assert_eq!(candidate_receipt.descriptor.para_id, test_state.chain_ids[0]);
+ assert_eq!(incoming_pov, pov);
+ });
- let mut candidate_b = CandidateReceipt::default();
- candidate_b.descriptor.para_id = test_state.chain_ids[0];
- candidate_b.descriptor.relay_parent = test_state.relay_parent;
+ let mut candidate_b = CandidateReceipt::default();
+ candidate_b.descriptor.para_id = test_state.chain_ids[0];
+ candidate_b.descriptor.relay_parent = test_state.relay_parent;
- // Send second collation to ensure first collation gets seconded
- response_channel.send(Ok(
- CollationFetchingResponse::Collation(
- candidate_b.clone(),
- PoV {
- block_data: BlockData(vec![]),
- },
- ).encode()
- )).expect("Sending response should succeed after seconding");
+ // Send second collation to ensure first collation gets seconded
+ response_channel.send(Ok(
+ CollationFetchingResponse::Collation(
+ candidate_b.clone(),
+ PoV {
+ block_data: BlockData(vec![]),
+ },
+ ).encode()
+ )).expect("Sending response should succeed after seconding");
- // Ensure we don't receive any message related to candidate backing
- // All Peers should get disconnected after successful Candidate Backing Message
- assert_matches!(
- overseer_recv(&mut virtual_overseer).await,
- AllMessages::NetworkBridge(NetworkBridgeMessage::DisconnectPeer(_, _)
- ) => {});
+ // Ensure we don't receive any message related to candidate backing
+ // All Peers should get disconnected after successful Candidate Backing Message
+ assert_matches!(
+ overseer_recv(&mut virtual_overseer).await,
+ AllMessages::NetworkBridge(NetworkBridgeMessage::DisconnectPeer(_, _)
+ ) => {});
- virtual_overseer
- });
+ virtual_overseer
+ });
}
diff --git a/polkadot/node/network/gossip-support/src/lib.rs b/polkadot/node/network/gossip-support/src/lib.rs
index 51438a23cc..8a12896bc7 100644
--- a/polkadot/node/network/gossip-support/src/lib.rs
+++ b/polkadot/node/network/gossip-support/src/lib.rs
@@ -18,9 +18,6 @@
//! and issuing a connection request to the validators relevant to
//! the gossiping subsystems on every new session.
-#[cfg(test)]
-mod tests;
-
use std::time::{Duration, Instant};
use futures::{channel::oneshot, FutureExt as _};
use polkadot_node_subsystem::{
@@ -38,6 +35,9 @@ use polkadot_node_network_protocol::peer_set::PeerSet;
use sp_keystore::{CryptoStore, SyncCryptoStorePtr};
use sp_application_crypto::{Public, AppKey};
+#[cfg(test)]
+mod tests;
+
const LOG_TARGET: &str = "parachain::gossip-support";
// How much time should we wait since the last
// authority discovery resolution failure.
diff --git a/polkadot/node/network/statement-distribution/src/lib.rs b/polkadot/node/network/statement-distribution/src/lib.rs
index ba7b8483a7..f2e570a6b7 100644
--- a/polkadot/node/network/statement-distribution/src/lib.rs
+++ b/polkadot/node/network/statement-distribution/src/lib.rs
@@ -71,6 +71,9 @@ use requester::{RequesterMessage, fetch};
mod responder;
use responder::{ResponderMessage, respond};
+#[cfg(test)]
+mod tests;
+
const COST_UNEXPECTED_STATEMENT: Rep = Rep::CostMinor("Unexpected Statement");
const COST_FETCH_FAIL: Rep = Rep::CostMinor("Requesting `CommittedCandidateReceipt` from peer failed");
const COST_INVALID_SIGNATURE: Rep = Rep::CostMajor("Invalid Statement Signature");
@@ -2044,6 +2047,3 @@ impl metrics::Metrics for Metrics {
Ok(Metrics(Some(metrics)))
}
}
-
-#[cfg(test)]
-mod tests;
diff --git a/polkadot/node/network/statement-distribution/src/tests.rs b/polkadot/node/network/statement-distribution/src/tests.rs
index 26438ed477..b2baa428a5 100644
--- a/polkadot/node/network/statement-distribution/src/tests.rs
+++ b/polkadot/node/network/statement-distribution/src/tests.rs
@@ -29,1682 +29,1682 @@ use sp_keystore::{CryptoStore, SyncCryptoStorePtr, SyncCryptoStore};
use sc_keystore::LocalKeystore;
use polkadot_node_network_protocol::{view, ObservedRole, request_response::Recipient};
use polkadot_subsystem::{
- jaeger, ActivatedLeaf, messages::{RuntimeApiMessage, RuntimeApiRequest}, LeafStatus,
+ jaeger, ActivatedLeaf, messages::{RuntimeApiMessage, RuntimeApiRequest}, LeafStatus,
};
use polkadot_node_network_protocol::request_response::{
- Requests,
- v1::{
- StatementFetchingRequest,
- StatementFetchingResponse,
- },
+ Requests,
+ v1::{
+ StatementFetchingRequest,
+ StatementFetchingResponse,
+ },
};
#[test]
fn active_head_accepts_only_2_seconded_per_validator() {
- let validators = vec![
- Sr25519Keyring::Alice.public().into(),
- Sr25519Keyring::Bob.public().into(),
- Sr25519Keyring::Charlie.public().into(),
- ];
- let parent_hash: Hash = [1; 32].into();
+ let validators = vec![
+ Sr25519Keyring::Alice.public().into(),
+ Sr25519Keyring::Bob.public().into(),
+ Sr25519Keyring::Charlie.public().into(),
+ ];
+ let parent_hash: Hash = [1; 32].into();
- let session_index = 1;
- let signing_context = SigningContext {
- parent_hash,
- session_index,
- };
+ let session_index = 1;
+ let signing_context = SigningContext {
+ parent_hash,
+ session_index,
+ };
- let candidate_a = {
- let mut c = CommittedCandidateReceipt::default();
- c.descriptor.relay_parent = parent_hash;
- c.descriptor.para_id = 1.into();
- c
- };
+ let candidate_a = {
+ let mut c = CommittedCandidateReceipt::default();
+ c.descriptor.relay_parent = parent_hash;
+ c.descriptor.para_id = 1.into();
+ c
+ };
- let candidate_b = {
- let mut c = CommittedCandidateReceipt::default();
- c.descriptor.relay_parent = parent_hash;
- c.descriptor.para_id = 2.into();
- c
- };
+ let candidate_b = {
+ let mut c = CommittedCandidateReceipt::default();
+ c.descriptor.relay_parent = parent_hash;
+ c.descriptor.para_id = 2.into();
+ c
+ };
- let candidate_c = {
- let mut c = CommittedCandidateReceipt::default();
- c.descriptor.relay_parent = parent_hash;
- c.descriptor.para_id = 3.into();
- c
- };
+ let candidate_c = {
+ let mut c = CommittedCandidateReceipt::default();
+ c.descriptor.relay_parent = parent_hash;
+ c.descriptor.para_id = 3.into();
+ c
+ };
- let mut head_data = ActiveHeadData::new(
- validators,
- session_index,
- PerLeafSpan::new(Arc::new(jaeger::Span::Disabled), "test"),
- );
+ let mut head_data = ActiveHeadData::new(
+ validators,
+ session_index,
+ PerLeafSpan::new(Arc::new(jaeger::Span::Disabled), "test"),
+ );
- let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory());
- let alice_public = SyncCryptoStore::sr25519_generate_new(
- &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Alice.to_seed())
- ).unwrap();
- let bob_public = SyncCryptoStore::sr25519_generate_new(
- &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Bob.to_seed())
- ).unwrap();
+ let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory());
+ let alice_public = SyncCryptoStore::sr25519_generate_new(
+ &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Alice.to_seed())
+ ).unwrap();
+ let bob_public = SyncCryptoStore::sr25519_generate_new(
+ &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Bob.to_seed())
+ ).unwrap();
- // note A
- let a_seconded_val_0 = block_on(SignedFullStatement::sign(
- &keystore,
- Statement::Seconded(candidate_a.clone()),
- &signing_context,
- ValidatorIndex(0),
- &alice_public.into(),
- )).ok().flatten().expect("should be signed");
- assert!(head_data.check_useful_or_unknown(&a_seconded_val_0.clone().into()).is_ok());
- let noted = head_data.note_statement(a_seconded_val_0.clone());
+ // note A
+ let a_seconded_val_0 = block_on(SignedFullStatement::sign(
+ &keystore,
+ Statement::Seconded(candidate_a.clone()),
+ &signing_context,
+ ValidatorIndex(0),
+ &alice_public.into(),
+ )).ok().flatten().expect("should be signed");
+ assert!(head_data.check_useful_or_unknown(&a_seconded_val_0.clone().into()).is_ok());
+ let noted = head_data.note_statement(a_seconded_val_0.clone());
- assert_matches!(noted, NotedStatement::Fresh(_));
+ assert_matches!(noted, NotedStatement::Fresh(_));
- // note A (duplicate)
- assert_eq!(
- head_data.check_useful_or_unknown(&a_seconded_val_0.clone().into()),
- Err(DeniedStatement::UsefulButKnown),
- );
- let noted = head_data.note_statement(a_seconded_val_0);
+ // note A (duplicate)
+ assert_eq!(
+ head_data.check_useful_or_unknown(&a_seconded_val_0.clone().into()),
+ Err(DeniedStatement::UsefulButKnown),
+ );
+ let noted = head_data.note_statement(a_seconded_val_0);
- assert_matches!(noted, NotedStatement::UsefulButKnown);
+ assert_matches!(noted, NotedStatement::UsefulButKnown);
- // note B
- let statement = block_on(SignedFullStatement::sign(
- &keystore,
- Statement::Seconded(candidate_b.clone()),
- &signing_context,
- ValidatorIndex(0),
- &alice_public.into(),
- )).ok().flatten().expect("should be signed");
- assert!(head_data.check_useful_or_unknown(&statement.clone().into()).is_ok());
- let noted = head_data.note_statement(statement);
- assert_matches!(noted, NotedStatement::Fresh(_));
+ // note B
+ let statement = block_on(SignedFullStatement::sign(
+ &keystore,
+ Statement::Seconded(candidate_b.clone()),
+ &signing_context,
+ ValidatorIndex(0),
+ &alice_public.into(),
+ )).ok().flatten().expect("should be signed");
+ assert!(head_data.check_useful_or_unknown(&statement.clone().into()).is_ok());
+ let noted = head_data.note_statement(statement);
+ assert_matches!(noted, NotedStatement::Fresh(_));
- // note C (beyond 2 - ignored)
- let statement = block_on(SignedFullStatement::sign(
- &keystore,
- Statement::Seconded(candidate_c.clone()),
- &signing_context,
- ValidatorIndex(0),
- &alice_public.into(),
- )).ok().flatten().expect("should be signed");
- assert_eq!(
- head_data.check_useful_or_unknown(&statement.clone().into()),
- Err(DeniedStatement::NotUseful),
- );
- let noted = head_data.note_statement(statement);
- assert_matches!(noted, NotedStatement::NotUseful);
+ // note C (beyond 2 - ignored)
+ let statement = block_on(SignedFullStatement::sign(
+ &keystore,
+ Statement::Seconded(candidate_c.clone()),
+ &signing_context,
+ ValidatorIndex(0),
+ &alice_public.into(),
+ )).ok().flatten().expect("should be signed");
+ assert_eq!(
+ head_data.check_useful_or_unknown(&statement.clone().into()),
+ Err(DeniedStatement::NotUseful),
+ );
+ let noted = head_data.note_statement(statement);
+ assert_matches!(noted, NotedStatement::NotUseful);
- // note B (new validator)
- let statement = block_on(SignedFullStatement::sign(
- &keystore,
- Statement::Seconded(candidate_b.clone()),
- &signing_context,
- ValidatorIndex(1),
- &bob_public.into(),
- )).ok().flatten().expect("should be signed");
- assert!(head_data.check_useful_or_unknown(&statement.clone().into()).is_ok());
- let noted = head_data.note_statement(statement);
- assert_matches!(noted, NotedStatement::Fresh(_));
+ // note B (new validator)
+ let statement = block_on(SignedFullStatement::sign(
+ &keystore,
+ Statement::Seconded(candidate_b.clone()),
+ &signing_context,
+ ValidatorIndex(1),
+ &bob_public.into(),
+ )).ok().flatten().expect("should be signed");
+ assert!(head_data.check_useful_or_unknown(&statement.clone().into()).is_ok());
+ let noted = head_data.note_statement(statement);
+ assert_matches!(noted, NotedStatement::Fresh(_));
- // note C (new validator)
- let statement = block_on(SignedFullStatement::sign(
- &keystore,
- Statement::Seconded(candidate_c.clone()),
- &signing_context,
- ValidatorIndex(1),
- &bob_public.into(),
- )).ok().flatten().expect("should be signed");
- assert!(head_data.check_useful_or_unknown(&statement.clone().into()).is_ok());
- let noted = head_data.note_statement(statement);
- assert_matches!(noted, NotedStatement::Fresh(_));
+ // note C (new validator)
+ let statement = block_on(SignedFullStatement::sign(
+ &keystore,
+ Statement::Seconded(candidate_c.clone()),
+ &signing_context,
+ ValidatorIndex(1),
+ &bob_public.into(),
+ )).ok().flatten().expect("should be signed");
+ assert!(head_data.check_useful_or_unknown(&statement.clone().into()).is_ok());
+ let noted = head_data.note_statement(statement);
+ assert_matches!(noted, NotedStatement::Fresh(_));
}
#[test]
fn note_local_works() {
- let hash_a = CandidateHash([1; 32].into());
- let hash_b = CandidateHash([2; 32].into());
+ let hash_a = CandidateHash([1; 32].into());
+ let hash_b = CandidateHash([2; 32].into());
- let mut per_peer_tracker = VcPerPeerTracker::default();
- per_peer_tracker.note_local(hash_a.clone());
- per_peer_tracker.note_local(hash_b.clone());
+ let mut per_peer_tracker = VcPerPeerTracker::default();
+ per_peer_tracker.note_local(hash_a.clone());
+ per_peer_tracker.note_local(hash_b.clone());
- assert!(per_peer_tracker.local_observed.contains(&hash_a));
- assert!(per_peer_tracker.local_observed.contains(&hash_b));
+ assert!(per_peer_tracker.local_observed.contains(&hash_a));
+ assert!(per_peer_tracker.local_observed.contains(&hash_b));
- assert!(!per_peer_tracker.remote_observed.contains(&hash_a));
- assert!(!per_peer_tracker.remote_observed.contains(&hash_b));
+ assert!(!per_peer_tracker.remote_observed.contains(&hash_a));
+ assert!(!per_peer_tracker.remote_observed.contains(&hash_b));
}
#[test]
fn note_remote_works() {
- let hash_a = CandidateHash([1; 32].into());
- let hash_b = CandidateHash([2; 32].into());
- let hash_c = CandidateHash([3; 32].into());
+ let hash_a = CandidateHash([1; 32].into());
+ let hash_b = CandidateHash([2; 32].into());
+ let hash_c = CandidateHash([3; 32].into());
- let mut per_peer_tracker = VcPerPeerTracker::default();
- assert!(per_peer_tracker.note_remote(hash_a.clone()));
- assert!(per_peer_tracker.note_remote(hash_b.clone()));
- assert!(!per_peer_tracker.note_remote(hash_c.clone()));
+ let mut per_peer_tracker = VcPerPeerTracker::default();
+ assert!(per_peer_tracker.note_remote(hash_a.clone()));
+ assert!(per_peer_tracker.note_remote(hash_b.clone()));
+ assert!(!per_peer_tracker.note_remote(hash_c.clone()));
- assert!(per_peer_tracker.remote_observed.contains(&hash_a));
- assert!(per_peer_tracker.remote_observed.contains(&hash_b));
- assert!(!per_peer_tracker.remote_observed.contains(&hash_c));
+ assert!(per_peer_tracker.remote_observed.contains(&hash_a));
+ assert!(per_peer_tracker.remote_observed.contains(&hash_b));
+ assert!(!per_peer_tracker.remote_observed.contains(&hash_c));
- assert!(!per_peer_tracker.local_observed.contains(&hash_a));
- assert!(!per_peer_tracker.local_observed.contains(&hash_b));
- assert!(!per_peer_tracker.local_observed.contains(&hash_c));
+ assert!(!per_peer_tracker.local_observed.contains(&hash_a));
+ assert!(!per_peer_tracker.local_observed.contains(&hash_b));
+ assert!(!per_peer_tracker.local_observed.contains(&hash_c));
}
#[test]
fn per_peer_relay_parent_knowledge_send() {
- let mut knowledge = PeerRelayParentKnowledge::default();
+ let mut knowledge = PeerRelayParentKnowledge::default();
- let hash_a = CandidateHash([1; 32].into());
+ let hash_a = CandidateHash([1; 32].into());
- // Sending an un-pinned statement should not work and should have no effect.
- assert!(!knowledge.can_send(&(CompactStatement::Valid(hash_a), ValidatorIndex(0))));
- assert!(!knowledge.is_known_candidate(&hash_a));
- assert!(knowledge.sent_statements.is_empty());
- assert!(knowledge.received_statements.is_empty());
- assert!(knowledge.seconded_counts.is_empty());
- assert!(knowledge.received_message_count.is_empty());
+ // Sending an un-pinned statement should not work and should have no effect.
+ assert!(!knowledge.can_send(&(CompactStatement::Valid(hash_a), ValidatorIndex(0))));
+ assert!(!knowledge.is_known_candidate(&hash_a));
+ assert!(knowledge.sent_statements.is_empty());
+ assert!(knowledge.received_statements.is_empty());
+ assert!(knowledge.seconded_counts.is_empty());
+ assert!(knowledge.received_message_count.is_empty());
- // Make the peer aware of the candidate.
- assert_eq!(knowledge.send(&(CompactStatement::Seconded(hash_a), ValidatorIndex(0))), true);
- assert_eq!(knowledge.send(&(CompactStatement::Seconded(hash_a), ValidatorIndex(1))), false);
- assert!(knowledge.is_known_candidate(&hash_a));
- assert_eq!(knowledge.sent_statements.len(), 2);
- assert!(knowledge.received_statements.is_empty());
- assert_eq!(knowledge.seconded_counts.len(), 2);
- assert!(knowledge.received_message_count.get(&hash_a).is_none());
+ // Make the peer aware of the candidate.
+ assert_eq!(knowledge.send(&(CompactStatement::Seconded(hash_a), ValidatorIndex(0))), true);
+ assert_eq!(knowledge.send(&(CompactStatement::Seconded(hash_a), ValidatorIndex(1))), false);
+ assert!(knowledge.is_known_candidate(&hash_a));
+ assert_eq!(knowledge.sent_statements.len(), 2);
+ assert!(knowledge.received_statements.is_empty());
+ assert_eq!(knowledge.seconded_counts.len(), 2);
+ assert!(knowledge.received_message_count.get(&hash_a).is_none());
- // And now it should accept the dependent message.
- assert_eq!(knowledge.send(&(CompactStatement::Valid(hash_a), ValidatorIndex(0))), false);
- assert!(knowledge.is_known_candidate(&hash_a));
- assert_eq!(knowledge.sent_statements.len(), 3);
- assert!(knowledge.received_statements.is_empty());
- assert_eq!(knowledge.seconded_counts.len(), 2);
- assert!(knowledge.received_message_count.get(&hash_a).is_none());
+ // And now it should accept the dependent message.
+ assert_eq!(knowledge.send(&(CompactStatement::Valid(hash_a), ValidatorIndex(0))), false);
+ assert!(knowledge.is_known_candidate(&hash_a));
+ assert_eq!(knowledge.sent_statements.len(), 3);
+ assert!(knowledge.received_statements.is_empty());
+ assert_eq!(knowledge.seconded_counts.len(), 2);
+ assert!(knowledge.received_message_count.get(&hash_a).is_none());
}
#[test]
fn cant_send_after_receiving() {
- let mut knowledge = PeerRelayParentKnowledge::default();
+ let mut knowledge = PeerRelayParentKnowledge::default();
- let hash_a = CandidateHash([1; 32].into());
- assert!(knowledge.check_can_receive(&(CompactStatement::Seconded(hash_a), ValidatorIndex(0)), 3).is_ok());
- assert!(knowledge.receive(&(CompactStatement::Seconded(hash_a), ValidatorIndex(0)), 3).unwrap());
- assert!(!knowledge.can_send(&(CompactStatement::Seconded(hash_a), ValidatorIndex(0))));
+ let hash_a = CandidateHash([1; 32].into());
+ assert!(knowledge.check_can_receive(&(CompactStatement::Seconded(hash_a), ValidatorIndex(0)), 3).is_ok());
+ assert!(knowledge.receive(&(CompactStatement::Seconded(hash_a), ValidatorIndex(0)), 3).unwrap());
+ assert!(!knowledge.can_send(&(CompactStatement::Seconded(hash_a), ValidatorIndex(0))));
}
#[test]
fn per_peer_relay_parent_knowledge_receive() {
- let mut knowledge = PeerRelayParentKnowledge::default();
+ let mut knowledge = PeerRelayParentKnowledge::default();
- let hash_a = CandidateHash([1; 32].into());
+ let hash_a = CandidateHash([1; 32].into());
- assert_eq!(
- knowledge.check_can_receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(0)), 3),
- Err(COST_UNEXPECTED_STATEMENT),
- );
- assert_eq!(
- knowledge.receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(0)), 3),
- Err(COST_UNEXPECTED_STATEMENT),
- );
+ assert_eq!(
+ knowledge.check_can_receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(0)), 3),
+ Err(COST_UNEXPECTED_STATEMENT),
+ );
+ assert_eq!(
+ knowledge.receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(0)), 3),
+ Err(COST_UNEXPECTED_STATEMENT),
+ );
- assert!(knowledge.check_can_receive(&(CompactStatement::Seconded(hash_a), ValidatorIndex(0)), 3).is_ok());
- assert_eq!(
- knowledge.receive(&(CompactStatement::Seconded(hash_a), ValidatorIndex(0)), 3),
- Ok(true),
- );
+ assert!(knowledge.check_can_receive(&(CompactStatement::Seconded(hash_a), ValidatorIndex(0)), 3).is_ok());
+ assert_eq!(
+ knowledge.receive(&(CompactStatement::Seconded(hash_a), ValidatorIndex(0)), 3),
+ Ok(true),
+ );
- // Push statements up to the flood limit.
- assert!(knowledge.check_can_receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(1)), 3).is_ok());
- assert_eq!(
- knowledge.receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(1)), 3),
- Ok(false),
- );
+ // Push statements up to the flood limit.
+ assert!(knowledge.check_can_receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(1)), 3).is_ok());
+ assert_eq!(
+ knowledge.receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(1)), 3),
+ Ok(false),
+ );
- assert!(knowledge.is_known_candidate(&hash_a));
- assert_eq!(*knowledge.received_message_count.get(&hash_a).unwrap(), 2);
+ assert!(knowledge.is_known_candidate(&hash_a));
+ assert_eq!(*knowledge.received_message_count.get(&hash_a).unwrap(), 2);
- assert!(knowledge.check_can_receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(2)), 3).is_ok());
- assert_eq!(
- knowledge.receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(2)), 3),
- Ok(false),
- );
+ assert!(knowledge.check_can_receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(2)), 3).is_ok());
+ assert_eq!(
+ knowledge.receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(2)), 3),
+ Ok(false),
+ );
- assert_eq!(*knowledge.received_message_count.get(&hash_a).unwrap(), 3);
+ assert_eq!(*knowledge.received_message_count.get(&hash_a).unwrap(), 3);
- assert_eq!(
- knowledge.check_can_receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(7)), 3),
- Err(COST_APPARENT_FLOOD),
- );
- assert_eq!(
- knowledge.receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(7)), 3),
- Err(COST_APPARENT_FLOOD),
- );
+ assert_eq!(
+ knowledge.check_can_receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(7)), 3),
+ Err(COST_APPARENT_FLOOD),
+ );
+ assert_eq!(
+ knowledge.receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(7)), 3),
+ Err(COST_APPARENT_FLOOD),
+ );
- assert_eq!(*knowledge.received_message_count.get(&hash_a).unwrap(), 3);
- assert_eq!(knowledge.received_statements.len(), 3); // number of prior `Ok`s.
+ assert_eq!(*knowledge.received_message_count.get(&hash_a).unwrap(), 3);
+ assert_eq!(knowledge.received_statements.len(), 3); // number of prior `Ok`s.
- // Now make sure that the seconding limit is respected.
- let hash_b = CandidateHash([2; 32].into());
- let hash_c = CandidateHash([3; 32].into());
+ // Now make sure that the seconding limit is respected.
+ let hash_b = CandidateHash([2; 32].into());
+ let hash_c = CandidateHash([3; 32].into());
- assert!(knowledge.check_can_receive(&(CompactStatement::Seconded(hash_b), ValidatorIndex(0)), 3).is_ok());
- assert_eq!(
- knowledge.receive(&(CompactStatement::Seconded(hash_b), ValidatorIndex(0)), 3),
- Ok(true),
- );
+ assert!(knowledge.check_can_receive(&(CompactStatement::Seconded(hash_b), ValidatorIndex(0)), 3).is_ok());
+ assert_eq!(
+ knowledge.receive(&(CompactStatement::Seconded(hash_b), ValidatorIndex(0)), 3),
+ Ok(true),
+ );
- assert_eq!(
- knowledge.check_can_receive(&(CompactStatement::Seconded(hash_c), ValidatorIndex(0)), 3),
- Err(COST_UNEXPECTED_STATEMENT),
- );
- assert_eq!(
- knowledge.receive(&(CompactStatement::Seconded(hash_c), ValidatorIndex(0)), 3),
- Err(COST_UNEXPECTED_STATEMENT),
- );
+ assert_eq!(
+ knowledge.check_can_receive(&(CompactStatement::Seconded(hash_c), ValidatorIndex(0)), 3),
+ Err(COST_UNEXPECTED_STATEMENT),
+ );
+ assert_eq!(
+ knowledge.receive(&(CompactStatement::Seconded(hash_c), ValidatorIndex(0)), 3),
+ Err(COST_UNEXPECTED_STATEMENT),
+ );
- // Last, make sure that already-known statements are disregarded.
- assert_eq!(
- knowledge.check_can_receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(2)), 3),
- Err(COST_DUPLICATE_STATEMENT),
- );
- assert_eq!(
- knowledge.receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(2)), 3),
- Err(COST_DUPLICATE_STATEMENT),
- );
+ // Last, make sure that already-known statements are disregarded.
+ assert_eq!(
+ knowledge.check_can_receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(2)), 3),
+ Err(COST_DUPLICATE_STATEMENT),
+ );
+ assert_eq!(
+ knowledge.receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(2)), 3),
+ Err(COST_DUPLICATE_STATEMENT),
+ );
- assert_eq!(
- knowledge.check_can_receive(&(CompactStatement::Seconded(hash_b), ValidatorIndex(0)), 3),
- Err(COST_DUPLICATE_STATEMENT),
- );
- assert_eq!(
- knowledge.receive(&(CompactStatement::Seconded(hash_b), ValidatorIndex(0)), 3),
- Err(COST_DUPLICATE_STATEMENT),
- );
+ assert_eq!(
+ knowledge.check_can_receive(&(CompactStatement::Seconded(hash_b), ValidatorIndex(0)), 3),
+ Err(COST_DUPLICATE_STATEMENT),
+ );
+ assert_eq!(
+ knowledge.receive(&(CompactStatement::Seconded(hash_b), ValidatorIndex(0)), 3),
+ Err(COST_DUPLICATE_STATEMENT),
+ );
}
#[test]
fn peer_view_update_sends_messages() {
- let hash_a = Hash::repeat_byte(1);
- let hash_b = Hash::repeat_byte(2);
- let hash_c = Hash::repeat_byte(3);
+ let hash_a = Hash::repeat_byte(1);
+ let hash_b = Hash::repeat_byte(2);
+ let hash_c = Hash::repeat_byte(3);
- let candidate = {
- let mut c = CommittedCandidateReceipt::default();
- c.descriptor.relay_parent = hash_c;
- c.descriptor.para_id = 1.into();
- c
- };
- let candidate_hash = candidate.hash();
+ let candidate = {
+ let mut c = CommittedCandidateReceipt::default();
+ c.descriptor.relay_parent = hash_c;
+ c.descriptor.para_id = 1.into();
+ c
+ };
+ let candidate_hash = candidate.hash();
- let old_view = view![hash_a, hash_b];
- let new_view = view![hash_b, hash_c];
+ let old_view = view![hash_a, hash_b];
+ let new_view = view![hash_b, hash_c];
- let mut active_heads = HashMap::new();
- let validators = vec![
- Sr25519Keyring::Alice.public().into(),
- Sr25519Keyring::Bob.public().into(),
- Sr25519Keyring::Charlie.public().into(),
- ];
+ let mut active_heads = HashMap::new();
+ let validators = vec![
+ Sr25519Keyring::Alice.public().into(),
+ Sr25519Keyring::Bob.public().into(),
+ Sr25519Keyring::Charlie.public().into(),
+ ];
- let session_index = 1;
- let signing_context = SigningContext {
- parent_hash: hash_c,
- session_index,
- };
+ let session_index = 1;
+ let signing_context = SigningContext {
+ parent_hash: hash_c,
+ session_index,
+ };
- let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory());
+ let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory());
- let alice_public = SyncCryptoStore::sr25519_generate_new(
- &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Alice.to_seed())
- ).unwrap();
- let bob_public = SyncCryptoStore::sr25519_generate_new(
- &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Bob.to_seed())
- ).unwrap();
- let charlie_public = SyncCryptoStore::sr25519_generate_new(
- &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Charlie.to_seed())
- ).unwrap();
+ let alice_public = SyncCryptoStore::sr25519_generate_new(
+ &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Alice.to_seed())
+ ).unwrap();
+ let bob_public = SyncCryptoStore::sr25519_generate_new(
+ &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Bob.to_seed())
+ ).unwrap();
+ let charlie_public = SyncCryptoStore::sr25519_generate_new(
+ &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Charlie.to_seed())
+ ).unwrap();
- let new_head_data = {
- let mut data = ActiveHeadData::new(
- validators,
- session_index,
- PerLeafSpan::new(Arc::new(jaeger::Span::Disabled), "test"),
- );
+ let new_head_data = {
+ let mut data = ActiveHeadData::new(
+ validators,
+ session_index,
+ PerLeafSpan::new(Arc::new(jaeger::Span::Disabled), "test"),
+ );
- let statement = block_on(SignedFullStatement::sign(
- &keystore,
- Statement::Seconded(candidate.clone()),
- &signing_context,
- ValidatorIndex(0),
- &alice_public.into(),
- )).ok().flatten().expect("should be signed");
- assert!(data.check_useful_or_unknown(&statement.clone().into()).is_ok());
- let noted = data.note_statement(statement);
+ let statement = block_on(SignedFullStatement::sign(
+ &keystore,
+ Statement::Seconded(candidate.clone()),
+ &signing_context,
+ ValidatorIndex(0),
+ &alice_public.into(),
+ )).ok().flatten().expect("should be signed");
+ assert!(data.check_useful_or_unknown(&statement.clone().into()).is_ok());
+ let noted = data.note_statement(statement);
- assert_matches!(noted, NotedStatement::Fresh(_));
+ assert_matches!(noted, NotedStatement::Fresh(_));
- let statement = block_on(SignedFullStatement::sign(
- &keystore,
- Statement::Valid(candidate_hash),
- &signing_context,
- ValidatorIndex(1),
- &bob_public.into(),
- )).ok().flatten().expect("should be signed");
- assert!(data.check_useful_or_unknown(&statement.clone().into()).is_ok());
- let noted = data.note_statement(statement);
+ let statement = block_on(SignedFullStatement::sign(
+ &keystore,
+ Statement::Valid(candidate_hash),
+ &signing_context,
+ ValidatorIndex(1),
+ &bob_public.into(),
+ )).ok().flatten().expect("should be signed");
+ assert!(data.check_useful_or_unknown(&statement.clone().into()).is_ok());
+ let noted = data.note_statement(statement);
- assert_matches!(noted, NotedStatement::Fresh(_));
+ assert_matches!(noted, NotedStatement::Fresh(_));
- let statement = block_on(SignedFullStatement::sign(
- &keystore,
- Statement::Valid(candidate_hash),
- &signing_context,
- ValidatorIndex(2),
- &charlie_public.into(),
- )).ok().flatten().expect("should be signed");
- assert!(data.check_useful_or_unknown(&statement.clone().into()).is_ok());
- let noted = data.note_statement(statement);
- assert_matches!(noted, NotedStatement::Fresh(_));
+ let statement = block_on(SignedFullStatement::sign(
+ &keystore,
+ Statement::Valid(candidate_hash),
+ &signing_context,
+ ValidatorIndex(2),
+ &charlie_public.into(),
+ )).ok().flatten().expect("should be signed");
+ assert!(data.check_useful_or_unknown(&statement.clone().into()).is_ok());
+ let noted = data.note_statement(statement);
+ assert_matches!(noted, NotedStatement::Fresh(_));
- data
- };
+ data
+ };
- active_heads.insert(hash_c, new_head_data);
+ active_heads.insert(hash_c, new_head_data);
- let mut peer_data = PeerData {
- view: old_view,
- view_knowledge: {
- let mut k = HashMap::new();
+ let mut peer_data = PeerData {
+ view: old_view,
+ view_knowledge: {
+ let mut k = HashMap::new();
- k.insert(hash_a, Default::default());
- k.insert(hash_b, Default::default());
+ k.insert(hash_a, Default::default());
+ k.insert(hash_b, Default::default());
- k
- },
- maybe_authority: None,
- };
+ k
+ },
+ maybe_authority: None,
+ };
- let pool = sp_core::testing::TaskExecutor::new();
- let (mut ctx, mut handle) =
- polkadot_node_subsystem_test_helpers
- ::make_subsystem_context
- ::(pool);
- let peer = PeerId::random();
+ let pool = sp_core::testing::TaskExecutor::new();
+ let (mut ctx, mut handle) =
+ polkadot_node_subsystem_test_helpers
+ ::make_subsystem_context
+ ::(pool);
+ let peer = PeerId::random();
- executor::block_on(async move {
- update_peer_view_and_send_unlocked(
- peer.clone(),
- &mut peer_data,
- &mut ctx,
- &active_heads,
- new_view.clone(),
- &Default::default(),
- ).await;
+ executor::block_on(async move {
+ update_peer_view_and_send_unlocked(
+ peer.clone(),
+ &mut peer_data,
+ &mut ctx,
+ &active_heads,
+ new_view.clone(),
+ &Default::default(),
+ ).await;
- assert_eq!(peer_data.view, new_view);
- assert!(!peer_data.view_knowledge.contains_key(&hash_a));
- assert!(peer_data.view_knowledge.contains_key(&hash_b));
+ assert_eq!(peer_data.view, new_view);
+ assert!(!peer_data.view_knowledge.contains_key(&hash_a));
+ assert!(peer_data.view_knowledge.contains_key(&hash_b));
- let c_knowledge = peer_data.view_knowledge.get(&hash_c).unwrap();
+ let c_knowledge = peer_data.view_knowledge.get(&hash_c).unwrap();
- assert!(c_knowledge.is_known_candidate(&candidate_hash));
- assert!(c_knowledge.sent_statements.contains(
- &(CompactStatement::Seconded(candidate_hash), ValidatorIndex(0))
- ));
- assert!(c_knowledge.sent_statements.contains(
- &(CompactStatement::Valid(candidate_hash), ValidatorIndex(1))
- ));
- assert!(c_knowledge.sent_statements.contains(
- &(CompactStatement::Valid(candidate_hash), ValidatorIndex(2))
- ));
+ assert!(c_knowledge.is_known_candidate(&candidate_hash));
+ assert!(c_knowledge.sent_statements.contains(
+ &(CompactStatement::Seconded(candidate_hash), ValidatorIndex(0))
+ ));
+ assert!(c_knowledge.sent_statements.contains(
+ &(CompactStatement::Valid(candidate_hash), ValidatorIndex(1))
+ ));
+ assert!(c_knowledge.sent_statements.contains(
+ &(CompactStatement::Valid(candidate_hash), ValidatorIndex(2))
+ ));
- // now see if we got the 3 messages from the active head data.
- let active_head = active_heads.get(&hash_c).unwrap();
+ // now see if we got the 3 messages from the active head data.
+ let active_head = active_heads.get(&hash_c).unwrap();
- // semi-fragile because hashmap iterator ordering is undefined, but in practice
- // it will not change between runs of the program.
- for statement in active_head.statements_about(candidate_hash) {
- let message = handle.recv().await;
- let expected_to = vec![peer.clone()];
- let expected_payload
- = statement_message(hash_c, statement.statement.clone());
+ // semi-fragile because hashmap iterator ordering is undefined, but in practice
+ // it will not change between runs of the program.
+ for statement in active_head.statements_about(candidate_hash) {
+ let message = handle.recv().await;
+ let expected_to = vec![peer.clone()];
+ let expected_payload
+ = statement_message(hash_c, statement.statement.clone());
- assert_matches!(
- message,
- AllMessages::NetworkBridge(NetworkBridgeMessage::SendValidationMessage(
- to,
- payload,
- )) => {
- assert_eq!(to, expected_to);
- assert_eq!(payload, expected_payload)
- }
- )
- }
- });
+ assert_matches!(
+ message,
+ AllMessages::NetworkBridge(NetworkBridgeMessage::SendValidationMessage(
+ to,
+ payload,
+ )) => {
+ assert_eq!(to, expected_to);
+ assert_eq!(payload, expected_payload)
+ }
+ )
+ }
+ });
}
#[test]
fn circulated_statement_goes_to_all_peers_with_view() {
- let hash_a = Hash::repeat_byte(1);
- let hash_b = Hash::repeat_byte(2);
- let hash_c = Hash::repeat_byte(3);
+ let hash_a = Hash::repeat_byte(1);
+ let hash_b = Hash::repeat_byte(2);
+ let hash_c = Hash::repeat_byte(3);
- let candidate = {
- let mut c = CommittedCandidateReceipt::default();
- c.descriptor.relay_parent = hash_b;
- c.descriptor.para_id = 1.into();
- c
- };
+ let candidate = {
+ let mut c = CommittedCandidateReceipt::default();
+ c.descriptor.relay_parent = hash_b;
+ c.descriptor.para_id = 1.into();
+ c
+ };
- let peer_a = PeerId::random();
- let peer_b = PeerId::random();
- let peer_c = PeerId::random();
+ let peer_a = PeerId::random();
+ let peer_b = PeerId::random();
+ let peer_c = PeerId::random();
- let peer_a_view = view![hash_a];
- let peer_b_view = view![hash_a, hash_b];
- let peer_c_view = view![hash_b, hash_c];
+ let peer_a_view = view![hash_a];
+ let peer_b_view = view![hash_a, hash_b];
+ let peer_c_view = view![hash_b, hash_c];
- let session_index = 1;
+ let session_index = 1;
- let peer_data_from_view = |view: View| PeerData {
- view: view.clone(),
- view_knowledge: view.iter().map(|v| (v.clone(), Default::default())).collect(),
- maybe_authority: None,
- };
+ let peer_data_from_view = |view: View| PeerData {
+ view: view.clone(),
+ view_knowledge: view.iter().map(|v| (v.clone(), Default::default())).collect(),
+ maybe_authority: None,
+ };
- let mut peer_data: HashMap<_, _> = vec![
- (peer_a.clone(), peer_data_from_view(peer_a_view)),
- (peer_b.clone(), peer_data_from_view(peer_b_view)),
- (peer_c.clone(), peer_data_from_view(peer_c_view)),
- ].into_iter().collect();
+ let mut peer_data: HashMap<_, _> = vec![
+ (peer_a.clone(), peer_data_from_view(peer_a_view)),
+ (peer_b.clone(), peer_data_from_view(peer_b_view)),
+ (peer_c.clone(), peer_data_from_view(peer_c_view)),
+ ].into_iter().collect();
- let pool = sp_core::testing::TaskExecutor::new();
- let (mut ctx, mut handle) =
- polkadot_node_subsystem_test_helpers
- ::make_subsystem_context
- ::(pool);
+ let pool = sp_core::testing::TaskExecutor::new();
+ let (mut ctx, mut handle) =
+ polkadot_node_subsystem_test_helpers
+ ::make_subsystem_context
+ ::(pool);
- executor::block_on(async move {
- let signing_context = SigningContext {
- parent_hash: hash_b,
- session_index,
- };
+ executor::block_on(async move {
+ let signing_context = SigningContext {
+ parent_hash: hash_b,
+ session_index,
+ };
- let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory());
- let alice_public = CryptoStore::sr25519_generate_new(
- &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Alice.to_seed())
- ).await.unwrap();
+ let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory());
+ let alice_public = CryptoStore::sr25519_generate_new(
+ &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Alice.to_seed())
+ ).await.unwrap();
- let statement = SignedFullStatement::sign(
- &keystore,
- Statement::Seconded(candidate),
- &signing_context,
- ValidatorIndex(0),
- &alice_public.into(),
- ).await.ok().flatten().expect("should be signed");
+ let statement = SignedFullStatement::sign(
+ &keystore,
+ Statement::Seconded(candidate),
+ &signing_context,
+ ValidatorIndex(0),
+ &alice_public.into(),
+ ).await.ok().flatten().expect("should be signed");
- let comparator = StoredStatementComparator {
- compact: statement.payload().to_compact(),
- validator_index: ValidatorIndex(0),
- signature: statement.signature().clone()
- };
- let statement = StoredStatement {
- comparator: &comparator,
- statement: &statement,
- };
+ let comparator = StoredStatementComparator {
+ compact: statement.payload().to_compact(),
+ validator_index: ValidatorIndex(0),
+ signature: statement.signature().clone()
+ };
+ let statement = StoredStatement {
+ comparator: &comparator,
+ statement: &statement,
+ };
- let needs_dependents = circulate_statement(
- &mut peer_data,
- &mut ctx,
- hash_b,
- statement,
- Vec::new(),
- ).await;
+ let needs_dependents = circulate_statement(
+ &mut peer_data,
+ &mut ctx,
+ hash_b,
+ statement,
+ Vec::new(),
+ ).await;
- {
- assert_eq!(needs_dependents.len(), 2);
- assert!(needs_dependents.contains(&peer_b));
- assert!(needs_dependents.contains(&peer_c));
- }
+ {
+ assert_eq!(needs_dependents.len(), 2);
+ assert!(needs_dependents.contains(&peer_b));
+ assert!(needs_dependents.contains(&peer_c));
+ }
- let fingerprint = (statement.compact().clone(), ValidatorIndex(0));
+ let fingerprint = (statement.compact().clone(), ValidatorIndex(0));
- assert!(
- peer_data.get(&peer_b).unwrap()
- .view_knowledge.get(&hash_b).unwrap()
- .sent_statements.contains(&fingerprint),
- );
+ assert!(
+ peer_data.get(&peer_b).unwrap()
+ .view_knowledge.get(&hash_b).unwrap()
+ .sent_statements.contains(&fingerprint),
+ );
- assert!(
- peer_data.get(&peer_c).unwrap()
- .view_knowledge.get(&hash_b).unwrap()
- .sent_statements.contains(&fingerprint),
- );
+ assert!(
+ peer_data.get(&peer_c).unwrap()
+ .view_knowledge.get(&hash_b).unwrap()
+ .sent_statements.contains(&fingerprint),
+ );
- let message = handle.recv().await;
- assert_matches!(
- message,
- AllMessages::NetworkBridge(NetworkBridgeMessage::SendValidationMessage(
- to,
- payload,
- )) => {
- assert_eq!(to.len(), 2);
- assert!(to.contains(&peer_b));
- assert!(to.contains(&peer_c));
+ let message = handle.recv().await;
+ assert_matches!(
+ message,
+ AllMessages::NetworkBridge(NetworkBridgeMessage::SendValidationMessage(
+ to,
+ payload,
+ )) => {
+ assert_eq!(to.len(), 2);
+ assert!(to.contains(&peer_b));
+ assert!(to.contains(&peer_c));
- assert_eq!(
- payload,
- statement_message(hash_b, statement.statement.clone()),
- );
- }
- )
- });
+ assert_eq!(
+ payload,
+ statement_message(hash_b, statement.statement.clone()),
+ );
+ }
+ )
+ });
}
#[test]
fn receiving_from_one_sends_to_another_and_to_candidate_backing() {
- let hash_a = Hash::repeat_byte(1);
+ let hash_a = Hash::repeat_byte(1);
- let candidate = {
- let mut c = CommittedCandidateReceipt::default();
- c.descriptor.relay_parent = hash_a;
- c.descriptor.para_id = 1.into();
- c
- };
+ let candidate = {
+ let mut c = CommittedCandidateReceipt::default();
+ c.descriptor.relay_parent = hash_a;
+ c.descriptor.para_id = 1.into();
+ c
+ };
- let peer_a = PeerId::random();
- let peer_b = PeerId::random();
+ let peer_a = PeerId::random();
+ let peer_b = PeerId::random();
- let validators = vec![
- Sr25519Keyring::Alice.pair(),
- Sr25519Keyring::Bob.pair(),
- Sr25519Keyring::Charlie.pair(),
- ];
+ let validators = vec![
+ Sr25519Keyring::Alice.pair(),
+ Sr25519Keyring::Bob.pair(),
+ Sr25519Keyring::Charlie.pair(),
+ ];
- let session_info = make_session_info(validators, vec![]);
+ let session_info = make_session_info(validators, vec![]);
- let session_index = 1;
+ let session_index = 1;
- let pool = sp_core::testing::TaskExecutor::new();
- let (ctx, mut handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context(pool);
+ let pool = sp_core::testing::TaskExecutor::new();
+ let (ctx, mut handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context(pool);
- let bg = async move {
- let s = StatementDistribution { metrics: Default::default(), keystore: Arc::new(LocalKeystore::in_memory()) };
- s.run(ctx).await.unwrap();
- };
+ let bg = async move {
+ let s = StatementDistribution { metrics: Default::default(), keystore: Arc::new(LocalKeystore::in_memory()) };
+ s.run(ctx).await.unwrap();
+ };
- let test_fut = async move {
- // register our active heads.
- handle.send(FromOverseer::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate {
- activated: vec![ActivatedLeaf {
- hash: hash_a,
- number: 1,
- status: LeafStatus::Fresh,
- span: Arc::new(jaeger::Span::Disabled),
- }].into(),
- deactivated: vec![].into(),
- }))).await;
+ let test_fut = async move {
+ // register our active heads.
+ handle.send(FromOverseer::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate {
+ activated: vec![ActivatedLeaf {
+ hash: hash_a,
+ number: 1,
+ status: LeafStatus::Fresh,
+ span: Arc::new(jaeger::Span::Disabled),
+ }].into(),
+ deactivated: vec![].into(),
+ }))).await;
- assert_matches!(
- handle.recv().await,
- AllMessages::RuntimeApi(
- RuntimeApiMessage::Request(r, RuntimeApiRequest::SessionIndexForChild(tx))
- )
- if r == hash_a
- => {
- let _ = tx.send(Ok(session_index));
- }
- );
+ assert_matches!(
+ handle.recv().await,
+ AllMessages::RuntimeApi(
+ RuntimeApiMessage::Request(r, RuntimeApiRequest::SessionIndexForChild(tx))
+ )
+ if r == hash_a
+ => {
+ let _ = tx.send(Ok(session_index));
+ }
+ );
- assert_matches!(
- handle.recv().await,
- AllMessages::RuntimeApi(
- RuntimeApiMessage::Request(r, RuntimeApiRequest::SessionInfo(sess_index, tx))
- )
- if r == hash_a && sess_index == session_index
- => {
- let _ = tx.send(Ok(Some(session_info)));
- }
- );
+ assert_matches!(
+ handle.recv().await,
+ AllMessages::RuntimeApi(
+ RuntimeApiMessage::Request(r, RuntimeApiRequest::SessionInfo(sess_index, tx))
+ )
+ if r == hash_a && sess_index == session_index
+ => {
+ let _ = tx.send(Ok(Some(session_info)));
+ }
+ );
- // notify of peers and view
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerConnected(peer_a.clone(), ObservedRole::Full, None)
- )
- }).await;
+ // notify of peers and view
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerConnected(peer_a.clone(), ObservedRole::Full, None)
+ )
+ }).await;
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerConnected(peer_b.clone(), ObservedRole::Full, None)
- )
- }).await;
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerConnected(peer_b.clone(), ObservedRole::Full, None)
+ )
+ }).await;
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerViewChange(peer_a.clone(), view![hash_a])
- )
- }).await;
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerViewChange(peer_a.clone(), view![hash_a])
+ )
+ }).await;
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerViewChange(peer_b.clone(), view![hash_a])
- )
- }).await;
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerViewChange(peer_b.clone(), view![hash_a])
+ )
+ }).await;
- // receive a seconded statement from peer A. it should be propagated onwards to peer B and to
- // candidate backing.
- let statement = {
- let signing_context = SigningContext {
- parent_hash: hash_a,
- session_index,
- };
+ // receive a seconded statement from peer A. it should be propagated onwards to peer B and to
+ // candidate backing.
+ let statement = {
+ let signing_context = SigningContext {
+ parent_hash: hash_a,
+ session_index,
+ };
- let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory());
- let alice_public = CryptoStore::sr25519_generate_new(
- &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Alice.to_seed())
- ).await.unwrap();
+ let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory());
+ let alice_public = CryptoStore::sr25519_generate_new(
+ &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Alice.to_seed())
+ ).await.unwrap();
- SignedFullStatement::sign(
- &keystore,
- Statement::Seconded(candidate),
- &signing_context,
- ValidatorIndex(0),
- &alice_public.into(),
- ).await.ok().flatten().expect("should be signed")
- };
+ SignedFullStatement::sign(
+ &keystore,
+ Statement::Seconded(candidate),
+ &signing_context,
+ ValidatorIndex(0),
+ &alice_public.into(),
+ ).await.ok().flatten().expect("should be signed")
+ };
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerMessage(
- peer_a.clone(),
- protocol_v1::StatementDistributionMessage::Statement(hash_a, statement.clone().into()),
- )
- )
- }).await;
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerMessage(
+ peer_a.clone(),
+ protocol_v1::StatementDistributionMessage::Statement(hash_a, statement.clone().into()),
+ )
+ )
+ }).await;
- assert_matches!(
- handle.recv().await,
- AllMessages::NetworkBridge(
- NetworkBridgeMessage::ReportPeer(p, r)
- ) if p == peer_a && r == BENEFIT_VALID_STATEMENT_FIRST => {}
- );
+ assert_matches!(
+ handle.recv().await,
+ AllMessages::NetworkBridge(
+ NetworkBridgeMessage::ReportPeer(p, r)
+ ) if p == peer_a && r == BENEFIT_VALID_STATEMENT_FIRST => {}
+ );
- assert_matches!(
- handle.recv().await,
- AllMessages::CandidateBacking(
- CandidateBackingMessage::Statement(r, s)
- ) if r == hash_a && s == statement => {}
- );
+ assert_matches!(
+ handle.recv().await,
+ AllMessages::CandidateBacking(
+ CandidateBackingMessage::Statement(r, s)
+ ) if r == hash_a && s == statement => {}
+ );
- assert_matches!(
- handle.recv().await,
- AllMessages::NetworkBridge(
- NetworkBridgeMessage::SendValidationMessage(
- recipients,
- protocol_v1::ValidationProtocol::StatementDistribution(
- protocol_v1::StatementDistributionMessage::Statement(r, s)
- ),
- )
- ) => {
- assert_eq!(recipients, vec![peer_b.clone()]);
- assert_eq!(r, hash_a);
- assert_eq!(s, statement.into());
- }
- );
- handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await;
- };
+ assert_matches!(
+ handle.recv().await,
+ AllMessages::NetworkBridge(
+ NetworkBridgeMessage::SendValidationMessage(
+ recipients,
+ protocol_v1::ValidationProtocol::StatementDistribution(
+ protocol_v1::StatementDistributionMessage::Statement(r, s)
+ ),
+ )
+ ) => {
+ assert_eq!(recipients, vec![peer_b.clone()]);
+ assert_eq!(r, hash_a);
+ assert_eq!(s, statement.into());
+ }
+ );
+ handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await;
+ };
- futures::pin_mut!(test_fut);
- futures::pin_mut!(bg);
+ futures::pin_mut!(test_fut);
+ futures::pin_mut!(bg);
- executor::block_on(future::join(test_fut, bg));
+ executor::block_on(future::join(test_fut, bg));
}
#[test]
fn receiving_large_statement_from_one_sends_to_another_and_to_candidate_backing() {
- sp_tracing::try_init_simple();
- let hash_a = Hash::repeat_byte(1);
- let hash_b = Hash::repeat_byte(2);
+ sp_tracing::try_init_simple();
+ let hash_a = Hash::repeat_byte(1);
+ let hash_b = Hash::repeat_byte(2);
- let candidate = {
- let mut c = CommittedCandidateReceipt::default();
- c.descriptor.relay_parent = hash_a;
- c.descriptor.para_id = 1.into();
- c.commitments.new_validation_code = Some(ValidationCode(vec![1,2,3]));
- c
- };
+ let candidate = {
+ let mut c = CommittedCandidateReceipt::default();
+ c.descriptor.relay_parent = hash_a;
+ c.descriptor.para_id = 1.into();
+ c.commitments.new_validation_code = Some(ValidationCode(vec![1,2,3]));
+ c
+ };
- let peer_a = PeerId::random(); // Alice
- let peer_b = PeerId::random(); // Bob
- let peer_c = PeerId::random(); // Charlie
- let peer_bad = PeerId::random(); // No validator
+ let peer_a = PeerId::random(); // Alice
+ let peer_b = PeerId::random(); // Bob
+ let peer_c = PeerId::random(); // Charlie
+ let peer_bad = PeerId::random(); // No validator
- let validators = vec![
- Sr25519Keyring::Alice.pair(),
- Sr25519Keyring::Bob.pair(),
- Sr25519Keyring::Charlie.pair(),
- // We:
- Sr25519Keyring::Ferdie.pair(),
- ];
+ let validators = vec![
+ Sr25519Keyring::Alice.pair(),
+ Sr25519Keyring::Bob.pair(),
+ Sr25519Keyring::Charlie.pair(),
+ // We:
+ Sr25519Keyring::Ferdie.pair(),
+ ];
- let session_info = make_session_info(
- validators,
- vec![vec![0,1,2,4], vec![3]]
- );
+ let session_info = make_session_info(
+ validators,
+ vec![vec![0,1,2,4], vec![3]]
+ );
- let session_index = 1;
+ let session_index = 1;
- let pool = sp_core::testing::TaskExecutor::new();
- let (ctx, mut handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context(pool);
+ let pool = sp_core::testing::TaskExecutor::new();
+ let (ctx, mut handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context(pool);
- let bg = async move {
- let s = StatementDistribution { metrics: Default::default(), keystore: make_ferdie_keystore()};
- s.run(ctx).await.unwrap();
- };
+ let bg = async move {
+ let s = StatementDistribution { metrics: Default::default(), keystore: make_ferdie_keystore()};
+ s.run(ctx).await.unwrap();
+ };
- let (mut tx_reqs, rx_reqs) = mpsc::channel(1);
+ let (mut tx_reqs, rx_reqs) = mpsc::channel(1);
- let test_fut = async move {
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::StatementFetchingReceiver(rx_reqs)
- }).await;
+ let test_fut = async move {
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::StatementFetchingReceiver(rx_reqs)
+ }).await;
- // register our active heads.
- handle.send(FromOverseer::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate {
- activated: vec![ActivatedLeaf {
- hash: hash_a,
- number: 1,
- status: LeafStatus::Fresh,
- span: Arc::new(jaeger::Span::Disabled),
- }].into(),
- deactivated: vec![].into(),
- }))).await;
+ // register our active heads.
+ handle.send(FromOverseer::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate {
+ activated: vec![ActivatedLeaf {
+ hash: hash_a,
+ number: 1,
+ status: LeafStatus::Fresh,
+ span: Arc::new(jaeger::Span::Disabled),
+ }].into(),
+ deactivated: vec![].into(),
+ }))).await;
- assert_matches!(
- handle.recv().await,
- AllMessages::RuntimeApi(
- RuntimeApiMessage::Request(r, RuntimeApiRequest::SessionIndexForChild(tx))
- )
- if r == hash_a
- => {
- let _ = tx.send(Ok(session_index));
- }
- );
+ assert_matches!(
+ handle.recv().await,
+ AllMessages::RuntimeApi(
+ RuntimeApiMessage::Request(r, RuntimeApiRequest::SessionIndexForChild(tx))
+ )
+ if r == hash_a
+ => {
+ let _ = tx.send(Ok(session_index));
+ }
+ );
- assert_matches!(
- handle.recv().await,
- AllMessages::RuntimeApi(
- RuntimeApiMessage::Request(r, RuntimeApiRequest::SessionInfo(sess_index, tx))
- )
- if r == hash_a && sess_index == session_index
- => {
- let _ = tx.send(Ok(Some(session_info)));
- }
- );
+ assert_matches!(
+ handle.recv().await,
+ AllMessages::RuntimeApi(
+ RuntimeApiMessage::Request(r, RuntimeApiRequest::SessionInfo(sess_index, tx))
+ )
+ if r == hash_a && sess_index == session_index
+ => {
+ let _ = tx.send(Ok(Some(session_info)));
+ }
+ );
- // notify of peers and view
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerConnected(
- peer_a.clone(),
- ObservedRole::Full,
- Some(Sr25519Keyring::Alice.public().into())
- )
- )
- }).await;
+ // notify of peers and view
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerConnected(
+ peer_a.clone(),
+ ObservedRole::Full,
+ Some(Sr25519Keyring::Alice.public().into())
+ )
+ )
+ }).await;
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerConnected(
- peer_b.clone(),
- ObservedRole::Full,
- Some(Sr25519Keyring::Bob.public().into())
- )
- )
- }).await;
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerConnected(
- peer_c.clone(),
- ObservedRole::Full,
- Some(Sr25519Keyring::Charlie.public().into())
- )
- )
- }).await;
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerConnected(peer_bad.clone(), ObservedRole::Full, None)
- )
- }).await;
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerConnected(
+ peer_b.clone(),
+ ObservedRole::Full,
+ Some(Sr25519Keyring::Bob.public().into())
+ )
+ )
+ }).await;
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerConnected(
+ peer_c.clone(),
+ ObservedRole::Full,
+ Some(Sr25519Keyring::Charlie.public().into())
+ )
+ )
+ }).await;
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerConnected(peer_bad.clone(), ObservedRole::Full, None)
+ )
+ }).await;
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerViewChange(peer_a.clone(), view![hash_a])
- )
- }).await;
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerViewChange(peer_a.clone(), view![hash_a])
+ )
+ }).await;
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerViewChange(peer_b.clone(), view![hash_a])
- )
- }).await;
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerViewChange(peer_c.clone(), view![hash_a])
- )
- }).await;
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerViewChange(peer_bad.clone(), view![hash_a])
- )
- }).await;
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerViewChange(peer_b.clone(), view![hash_a])
+ )
+ }).await;
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerViewChange(peer_c.clone(), view![hash_a])
+ )
+ }).await;
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerViewChange(peer_bad.clone(), view![hash_a])
+ )
+ }).await;
- // receive a seconded statement from peer A, which does not provide the request data,
- // then get that data from peer C. It should be propagated onwards to peer B and to
- // candidate backing.
- let statement = {
- let signing_context = SigningContext {
- parent_hash: hash_a,
- session_index,
- };
+ // receive a seconded statement from peer A, which does not provide the request data,
+ // then get that data from peer C. It should be propagated onwards to peer B and to
+ // candidate backing.
+ let statement = {
+ let signing_context = SigningContext {
+ parent_hash: hash_a,
+ session_index,
+ };
- let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory());
- let alice_public = CryptoStore::sr25519_generate_new(
- &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Alice.to_seed())
- ).await.unwrap();
+ let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory());
+ let alice_public = CryptoStore::sr25519_generate_new(
+ &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Alice.to_seed())
+ ).await.unwrap();
- SignedFullStatement::sign(
- &keystore,
- Statement::Seconded(candidate.clone()),
- &signing_context,
- ValidatorIndex(0),
- &alice_public.into(),
- ).await.ok().flatten().expect("should be signed")
- };
+ SignedFullStatement::sign(
+ &keystore,
+ Statement::Seconded(candidate.clone()),
+ &signing_context,
+ ValidatorIndex(0),
+ &alice_public.into(),
+ ).await.ok().flatten().expect("should be signed")
+ };
- let metadata =
- protocol_v1::StatementDistributionMessage::Statement(hash_a, statement.clone().into()).get_metadata();
+ let metadata =
+ protocol_v1::StatementDistributionMessage::Statement(hash_a, statement.clone().into()).get_metadata();
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerMessage(
- peer_a.clone(),
- protocol_v1::StatementDistributionMessage::LargeStatement(metadata.clone()),
- )
- )
- }).await;
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerMessage(
+ peer_a.clone(),
+ protocol_v1::StatementDistributionMessage::LargeStatement(metadata.clone()),
+ )
+ )
+ }).await;
- assert_matches!(
- handle.recv().await,
- AllMessages::NetworkBridge(
- NetworkBridgeMessage::SendRequests(
- mut reqs, IfDisconnected::ImmediateError
- )
- ) => {
- let reqs = reqs.pop().unwrap();
- let outgoing = match reqs {
- Requests::StatementFetching(outgoing) => outgoing,
- _ => panic!("Unexpected request"),
- };
- let req = outgoing.payload;
- assert_eq!(req.relay_parent, metadata.relay_parent);
- assert_eq!(req.candidate_hash, metadata.candidate_hash);
- assert_eq!(outgoing.peer, Recipient::Peer(peer_a));
- // Just drop request - should trigger error.
- }
- );
+ assert_matches!(
+ handle.recv().await,
+ AllMessages::NetworkBridge(
+ NetworkBridgeMessage::SendRequests(
+ mut reqs, IfDisconnected::ImmediateError
+ )
+ ) => {
+ let reqs = reqs.pop().unwrap();
+ let outgoing = match reqs {
+ Requests::StatementFetching(outgoing) => outgoing,
+ _ => panic!("Unexpected request"),
+ };
+ let req = outgoing.payload;
+ assert_eq!(req.relay_parent, metadata.relay_parent);
+ assert_eq!(req.candidate_hash, metadata.candidate_hash);
+ assert_eq!(outgoing.peer, Recipient::Peer(peer_a));
+ // Just drop request - should trigger error.
+ }
+ );
- // There is a race between request handler asking for more peers and processing of the
- // coming `PeerMessage`s, we want the request handler to ask first here for better test
- // coverage:
- Delay::new(Duration::from_millis(20)).await;
+ // There is a race between request handler asking for more peers and processing of the
+ // coming `PeerMessage`s, we want the request handler to ask first here for better test
+ // coverage:
+ Delay::new(Duration::from_millis(20)).await;
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerMessage(
- peer_c.clone(),
- protocol_v1::StatementDistributionMessage::LargeStatement(metadata.clone()),
- )
- )
- }).await;
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerMessage(
+ peer_c.clone(),
+ protocol_v1::StatementDistributionMessage::LargeStatement(metadata.clone()),
+ )
+ )
+ }).await;
- // Malicious peer:
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerMessage(
- peer_bad.clone(),
- protocol_v1::StatementDistributionMessage::LargeStatement(metadata.clone()),
- )
- )
- }).await;
+ // Malicious peer:
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerMessage(
+ peer_bad.clone(),
+ protocol_v1::StatementDistributionMessage::LargeStatement(metadata.clone()),
+ )
+ )
+ }).await;
- // Let c fail once too:
- assert_matches!(
- handle.recv().await,
- AllMessages::NetworkBridge(
- NetworkBridgeMessage::SendRequests(
- mut reqs, IfDisconnected::ImmediateError
- )
- ) => {
- let reqs = reqs.pop().unwrap();
- let outgoing = match reqs {
- Requests::StatementFetching(outgoing) => outgoing,
- _ => panic!("Unexpected request"),
- };
- let req = outgoing.payload;
- assert_eq!(req.relay_parent, metadata.relay_parent);
- assert_eq!(req.candidate_hash, metadata.candidate_hash);
- assert_eq!(outgoing.peer, Recipient::Peer(peer_c));
- }
- );
+ // Let c fail once too:
+ assert_matches!(
+ handle.recv().await,
+ AllMessages::NetworkBridge(
+ NetworkBridgeMessage::SendRequests(
+ mut reqs, IfDisconnected::ImmediateError
+ )
+ ) => {
+ let reqs = reqs.pop().unwrap();
+ let outgoing = match reqs {
+ Requests::StatementFetching(outgoing) => outgoing,
+ _ => panic!("Unexpected request"),
+ };
+ let req = outgoing.payload;
+ assert_eq!(req.relay_parent, metadata.relay_parent);
+ assert_eq!(req.candidate_hash, metadata.candidate_hash);
+ assert_eq!(outgoing.peer, Recipient::Peer(peer_c));
+ }
+ );
- // a fails again:
- assert_matches!(
- handle.recv().await,
- AllMessages::NetworkBridge(
- NetworkBridgeMessage::SendRequests(
- mut reqs, IfDisconnected::ImmediateError
- )
- ) => {
- let reqs = reqs.pop().unwrap();
- let outgoing = match reqs {
- Requests::StatementFetching(outgoing) => outgoing,
- _ => panic!("Unexpected request"),
- };
- let req = outgoing.payload;
- assert_eq!(req.relay_parent, metadata.relay_parent);
- assert_eq!(req.candidate_hash, metadata.candidate_hash);
- // On retry, we should have reverse order:
- assert_eq!(outgoing.peer, Recipient::Peer(peer_a));
- }
- );
+ // a fails again:
+ assert_matches!(
+ handle.recv().await,
+ AllMessages::NetworkBridge(
+ NetworkBridgeMessage::SendRequests(
+ mut reqs, IfDisconnected::ImmediateError
+ )
+ ) => {
+ let reqs = reqs.pop().unwrap();
+ let outgoing = match reqs {
+ Requests::StatementFetching(outgoing) => outgoing,
+ _ => panic!("Unexpected request"),
+ };
+ let req = outgoing.payload;
+ assert_eq!(req.relay_parent, metadata.relay_parent);
+ assert_eq!(req.candidate_hash, metadata.candidate_hash);
+ // On retry, we should have reverse order:
+ assert_eq!(outgoing.peer, Recipient::Peer(peer_a));
+ }
+ );
- // Send invalid response (all other peers have been tried now):
- assert_matches!(
- handle.recv().await,
- AllMessages::NetworkBridge(
- NetworkBridgeMessage::SendRequests(
- mut reqs, IfDisconnected::ImmediateError
- )
- ) => {
- let reqs = reqs.pop().unwrap();
- let outgoing = match reqs {
- Requests::StatementFetching(outgoing) => outgoing,
- _ => panic!("Unexpected request"),
- };
- let req = outgoing.payload;
- assert_eq!(req.relay_parent, metadata.relay_parent);
- assert_eq!(req.candidate_hash, metadata.candidate_hash);
- assert_eq!(outgoing.peer, Recipient::Peer(peer_bad));
- let bad_candidate = {
- let mut bad = candidate.clone();
- bad.descriptor.para_id = 0xeadbeaf.into();
- bad
- };
- let response = StatementFetchingResponse::Statement(bad_candidate);
- outgoing.pending_response.send(Ok(response.encode())).unwrap();
- }
- );
+ // Send invalid response (all other peers have been tried now):
+ assert_matches!(
+ handle.recv().await,
+ AllMessages::NetworkBridge(
+ NetworkBridgeMessage::SendRequests(
+ mut reqs, IfDisconnected::ImmediateError
+ )
+ ) => {
+ let reqs = reqs.pop().unwrap();
+ let outgoing = match reqs {
+ Requests::StatementFetching(outgoing) => outgoing,
+ _ => panic!("Unexpected request"),
+ };
+ let req = outgoing.payload;
+ assert_eq!(req.relay_parent, metadata.relay_parent);
+ assert_eq!(req.candidate_hash, metadata.candidate_hash);
+ assert_eq!(outgoing.peer, Recipient::Peer(peer_bad));
+ let bad_candidate = {
+ let mut bad = candidate.clone();
+ bad.descriptor.para_id = 0xeadbeaf.into();
+ bad
+ };
+ let response = StatementFetchingResponse::Statement(bad_candidate);
+ outgoing.pending_response.send(Ok(response.encode())).unwrap();
+ }
+ );
- // Should get punished and never tried again:
- assert_matches!(
- handle.recv().await,
- AllMessages::NetworkBridge(
- NetworkBridgeMessage::ReportPeer(p, r)
- ) if p == peer_bad && r == COST_WRONG_HASH => {}
- );
+ // Should get punished and never tried again:
+ assert_matches!(
+ handle.recv().await,
+ AllMessages::NetworkBridge(
+ NetworkBridgeMessage::ReportPeer(p, r)
+ ) if p == peer_bad && r == COST_WRONG_HASH => {}
+ );
- // a is tried again (retried in reverse order):
- assert_matches!(
- handle.recv().await,
- AllMessages::NetworkBridge(
- NetworkBridgeMessage::SendRequests(
- mut reqs, IfDisconnected::ImmediateError
- )
- ) => {
- let reqs = reqs.pop().unwrap();
- let outgoing = match reqs {
- Requests::StatementFetching(outgoing) => outgoing,
- _ => panic!("Unexpected request"),
- };
- let req = outgoing.payload;
- assert_eq!(req.relay_parent, metadata.relay_parent);
- assert_eq!(req.candidate_hash, metadata.candidate_hash);
- // On retry, we should have reverse order:
- assert_eq!(outgoing.peer, Recipient::Peer(peer_a));
- }
- );
+ // a is tried again (retried in reverse order):
+ assert_matches!(
+ handle.recv().await,
+ AllMessages::NetworkBridge(
+ NetworkBridgeMessage::SendRequests(
+ mut reqs, IfDisconnected::ImmediateError
+ )
+ ) => {
+ let reqs = reqs.pop().unwrap();
+ let outgoing = match reqs {
+ Requests::StatementFetching(outgoing) => outgoing,
+ _ => panic!("Unexpected request"),
+ };
+ let req = outgoing.payload;
+ assert_eq!(req.relay_parent, metadata.relay_parent);
+ assert_eq!(req.candidate_hash, metadata.candidate_hash);
+ // On retry, we should have reverse order:
+ assert_eq!(outgoing.peer, Recipient::Peer(peer_a));
+ }
+ );
- // c succeeds now:
- assert_matches!(
- handle.recv().await,
- AllMessages::NetworkBridge(
- NetworkBridgeMessage::SendRequests(
- mut reqs, IfDisconnected::ImmediateError
- )
- ) => {
- let reqs = reqs.pop().unwrap();
- let outgoing = match reqs {
- Requests::StatementFetching(outgoing) => outgoing,
- _ => panic!("Unexpected request"),
- };
- let req = outgoing.payload;
- assert_eq!(req.relay_parent, metadata.relay_parent);
- assert_eq!(req.candidate_hash, metadata.candidate_hash);
- // On retry, we should have reverse order:
- assert_eq!(outgoing.peer, Recipient::Peer(peer_c));
- let response = StatementFetchingResponse::Statement(candidate.clone());
- outgoing.pending_response.send(Ok(response.encode())).unwrap();
- }
- );
+ // c succeeds now:
+ assert_matches!(
+ handle.recv().await,
+ AllMessages::NetworkBridge(
+ NetworkBridgeMessage::SendRequests(
+ mut reqs, IfDisconnected::ImmediateError
+ )
+ ) => {
+ let reqs = reqs.pop().unwrap();
+ let outgoing = match reqs {
+ Requests::StatementFetching(outgoing) => outgoing,
+ _ => panic!("Unexpected request"),
+ };
+ let req = outgoing.payload;
+ assert_eq!(req.relay_parent, metadata.relay_parent);
+ assert_eq!(req.candidate_hash, metadata.candidate_hash);
+ // On retry, we should have reverse order:
+ assert_eq!(outgoing.peer, Recipient::Peer(peer_c));
+ let response = StatementFetchingResponse::Statement(candidate.clone());
+ outgoing.pending_response.send(Ok(response.encode())).unwrap();
+ }
+ );
- assert_matches!(
- handle.recv().await,
- AllMessages::NetworkBridge(
- NetworkBridgeMessage::ReportPeer(p, r)
- ) if p == peer_a && r == COST_FETCH_FAIL => {}
- );
+ assert_matches!(
+ handle.recv().await,
+ AllMessages::NetworkBridge(
+ NetworkBridgeMessage::ReportPeer(p, r)
+ ) if p == peer_a && r == COST_FETCH_FAIL => {}
+ );
- assert_matches!(
- handle.recv().await,
- AllMessages::NetworkBridge(
- NetworkBridgeMessage::ReportPeer(p, r)
- ) if p == peer_c && r == BENEFIT_VALID_RESPONSE => {}
- );
+ assert_matches!(
+ handle.recv().await,
+ AllMessages::NetworkBridge(
+ NetworkBridgeMessage::ReportPeer(p, r)
+ ) if p == peer_c && r == BENEFIT_VALID_RESPONSE => {}
+ );
- assert_matches!(
- handle.recv().await,
- AllMessages::NetworkBridge(
- NetworkBridgeMessage::ReportPeer(p, r)
- ) if p == peer_a && r == BENEFIT_VALID_STATEMENT_FIRST => {}
- );
+ assert_matches!(
+ handle.recv().await,
+ AllMessages::NetworkBridge(
+ NetworkBridgeMessage::ReportPeer(p, r)
+ ) if p == peer_a && r == BENEFIT_VALID_STATEMENT_FIRST => {}
+ );
- assert_matches!(
- handle.recv().await,
- AllMessages::CandidateBacking(
- CandidateBackingMessage::Statement(r, s)
- ) if r == hash_a && s == statement => {}
- );
+ assert_matches!(
+ handle.recv().await,
+ AllMessages::CandidateBacking(
+ CandidateBackingMessage::Statement(r, s)
+ ) if r == hash_a && s == statement => {}
+ );
- // Now messages should go out:
- assert_matches!(
- handle.recv().await,
- AllMessages::NetworkBridge(
- NetworkBridgeMessage::SendValidationMessage(
- mut recipients,
- protocol_v1::ValidationProtocol::StatementDistribution(
- protocol_v1::StatementDistributionMessage::LargeStatement(meta)
- ),
- )
- ) => {
- tracing::debug!(
- target: LOG_TARGET,
- ?recipients,
- "Recipients received"
- );
- recipients.sort();
- let mut expected = vec![peer_b, peer_c, peer_bad];
- expected.sort();
- assert_eq!(recipients, expected);
- assert_eq!(meta.relay_parent, hash_a);
- assert_eq!(meta.candidate_hash, statement.payload().candidate_hash());
- assert_eq!(meta.signed_by, statement.validator_index());
- assert_eq!(&meta.signature, statement.signature());
- }
- );
+ // Now messages should go out:
+ assert_matches!(
+ handle.recv().await,
+ AllMessages::NetworkBridge(
+ NetworkBridgeMessage::SendValidationMessage(
+ mut recipients,
+ protocol_v1::ValidationProtocol::StatementDistribution(
+ protocol_v1::StatementDistributionMessage::LargeStatement(meta)
+ ),
+ )
+ ) => {
+ tracing::debug!(
+ target: LOG_TARGET,
+ ?recipients,
+ "Recipients received"
+ );
+ recipients.sort();
+ let mut expected = vec![peer_b, peer_c, peer_bad];
+ expected.sort();
+ assert_eq!(recipients, expected);
+ assert_eq!(meta.relay_parent, hash_a);
+ assert_eq!(meta.candidate_hash, statement.payload().candidate_hash());
+ assert_eq!(meta.signed_by, statement.validator_index());
+ assert_eq!(&meta.signature, statement.signature());
+ }
+ );
- // Now that it has the candidate it should answer requests accordingly (even after a
- // failed request):
+ // Now that it has the candidate it should answer requests accordingly (even after a
+ // failed request):
- // Failing request first (wrong relay parent hash):
- let (pending_response, response_rx) = oneshot::channel();
- let inner_req = StatementFetchingRequest {
- relay_parent: hash_b,
- candidate_hash: metadata.candidate_hash,
- };
- let req = sc_network::config::IncomingRequest {
- peer: peer_b,
- payload: inner_req.encode(),
- pending_response,
- };
- tx_reqs.send(req).await.unwrap();
- assert_matches!(
- response_rx.await.unwrap().result,
- Err(()) => {}
- );
+ // Failing request first (wrong relay parent hash):
+ let (pending_response, response_rx) = oneshot::channel();
+ let inner_req = StatementFetchingRequest {
+ relay_parent: hash_b,
+ candidate_hash: metadata.candidate_hash,
+ };
+ let req = sc_network::config::IncomingRequest {
+ peer: peer_b,
+ payload: inner_req.encode(),
+ pending_response,
+ };
+ tx_reqs.send(req).await.unwrap();
+ assert_matches!(
+ response_rx.await.unwrap().result,
+ Err(()) => {}
+ );
- // Another failing request (peer_a never received a statement from us, so it is not
- // allowed to request the data):
- let (pending_response, response_rx) = oneshot::channel();
- let inner_req = StatementFetchingRequest {
- relay_parent: metadata.relay_parent,
- candidate_hash: metadata.candidate_hash,
- };
- let req = sc_network::config::IncomingRequest {
- peer: peer_a,
- payload: inner_req.encode(),
- pending_response,
- };
- tx_reqs.send(req).await.unwrap();
- assert_matches!(
- response_rx.await.unwrap().result,
- Err(()) => {}
- );
+ // Another failing request (peer_a never received a statement from us, so it is not
+ // allowed to request the data):
+ let (pending_response, response_rx) = oneshot::channel();
+ let inner_req = StatementFetchingRequest {
+ relay_parent: metadata.relay_parent,
+ candidate_hash: metadata.candidate_hash,
+ };
+ let req = sc_network::config::IncomingRequest {
+ peer: peer_a,
+ payload: inner_req.encode(),
+ pending_response,
+ };
+ tx_reqs.send(req).await.unwrap();
+ assert_matches!(
+ response_rx.await.unwrap().result,
+ Err(()) => {}
+ );
- // And now the succeding request from peer_b:
- let (pending_response, response_rx) = oneshot::channel();
- let inner_req = StatementFetchingRequest {
- relay_parent: metadata.relay_parent,
- candidate_hash: metadata.candidate_hash,
- };
- let req = sc_network::config::IncomingRequest {
- peer: peer_b,
- payload: inner_req.encode(),
- pending_response,
- };
- tx_reqs.send(req).await.unwrap();
- let StatementFetchingResponse::Statement(committed) =
- Decode::decode(&mut response_rx.await.unwrap().result.unwrap().as_ref()).unwrap();
- assert_eq!(committed, candidate);
+ // And now the succeding request from peer_b:
+ let (pending_response, response_rx) = oneshot::channel();
+ let inner_req = StatementFetchingRequest {
+ relay_parent: metadata.relay_parent,
+ candidate_hash: metadata.candidate_hash,
+ };
+ let req = sc_network::config::IncomingRequest {
+ peer: peer_b,
+ payload: inner_req.encode(),
+ pending_response,
+ };
+ tx_reqs.send(req).await.unwrap();
+ let StatementFetchingResponse::Statement(committed) =
+ Decode::decode(&mut response_rx.await.unwrap().result.unwrap().as_ref()).unwrap();
+ assert_eq!(committed, candidate);
- handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await;
- };
+ handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await;
+ };
- futures::pin_mut!(test_fut);
- futures::pin_mut!(bg);
+ futures::pin_mut!(test_fut);
+ futures::pin_mut!(bg);
- executor::block_on(future::join(test_fut, bg));
+ executor::block_on(future::join(test_fut, bg));
}
#[test]
fn share_prioritizes_backing_group() {
- sp_tracing::try_init_simple();
- let hash_a = Hash::repeat_byte(1);
+ sp_tracing::try_init_simple();
+ let hash_a = Hash::repeat_byte(1);
- let candidate = {
- let mut c = CommittedCandidateReceipt::default();
- c.descriptor.relay_parent = hash_a;
- c.descriptor.para_id = 1.into();
- c.commitments.new_validation_code = Some(ValidationCode(vec![1,2,3]));
- c
- };
+ let candidate = {
+ let mut c = CommittedCandidateReceipt::default();
+ c.descriptor.relay_parent = hash_a;
+ c.descriptor.para_id = 1.into();
+ c.commitments.new_validation_code = Some(ValidationCode(vec![1,2,3]));
+ c
+ };
- let peer_a = PeerId::random(); // Alice
- let peer_b = PeerId::random(); // Bob
- let peer_c = PeerId::random(); // Charlie
- let peer_bad = PeerId::random(); // No validator
- let peer_other_group = PeerId::random(); //Ferdie
+ let peer_a = PeerId::random(); // Alice
+ let peer_b = PeerId::random(); // Bob
+ let peer_c = PeerId::random(); // Charlie
+ let peer_bad = PeerId::random(); // No validator
+ let peer_other_group = PeerId::random(); //Ferdie
- let mut validators = vec![
- Sr25519Keyring::Alice.pair(),
- Sr25519Keyring::Bob.pair(),
- Sr25519Keyring::Charlie.pair(),
- // other group
- Sr25519Keyring::Dave.pair(),
- // We:
- Sr25519Keyring::Ferdie.pair(),
- ];
+ let mut validators = vec![
+ Sr25519Keyring::Alice.pair(),
+ Sr25519Keyring::Bob.pair(),
+ Sr25519Keyring::Charlie.pair(),
+ // other group
+ Sr25519Keyring::Dave.pair(),
+ // We:
+ Sr25519Keyring::Ferdie.pair(),
+ ];
- // Strictly speaking we only need MIN_GOSSIP_PEERS - 3 to make sure only priority peers
- // will be served, but by using a larger value we test for overflow errors:
- let dummy_count = MIN_GOSSIP_PEERS;
+ // Strictly speaking we only need MIN_GOSSIP_PEERS - 3 to make sure only priority peers
+ // will be served, but by using a larger value we test for overflow errors:
+ let dummy_count = MIN_GOSSIP_PEERS;
- // We artificially inflate our group, so there won't be any free slots for other peers. (We
- // want to test that our group is prioritized):
- let dummy_pairs: Vec<_> = std::iter::repeat_with(|| Pair::generate().0).take(dummy_count).collect();
- let dummy_peers: Vec<_> = std::iter::repeat_with(|| PeerId::random()).take(dummy_count).collect();
+ // We artificially inflate our group, so there won't be any free slots for other peers. (We
+ // want to test that our group is prioritized):
+ let dummy_pairs: Vec<_> = std::iter::repeat_with(|| Pair::generate().0).take(dummy_count).collect();
+ let dummy_peers: Vec<_> = std::iter::repeat_with(|| PeerId::random()).take(dummy_count).collect();
- validators = validators.into_iter().chain(dummy_pairs.clone()).collect();
+ validators = validators.into_iter().chain(dummy_pairs.clone()).collect();
- let mut first_group = vec![0,1,2,4];
- first_group.append(&mut (0..dummy_count as u32).map(|v| v + 5).collect());
- let session_info = make_session_info(
- validators,
- vec![first_group, vec![3]]
- );
+ let mut first_group = vec![0,1,2,4];
+ first_group.append(&mut (0..dummy_count as u32).map(|v| v + 5).collect());
+ let session_info = make_session_info(
+ validators,
+ vec![first_group, vec![3]]
+ );
- let session_index = 1;
+ let session_index = 1;
- let pool = sp_core::testing::TaskExecutor::new();
- let (ctx, mut handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context(pool);
+ let pool = sp_core::testing::TaskExecutor::new();
+ let (ctx, mut handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context(pool);
- let bg = async move {
- let s = StatementDistribution { metrics: Default::default(), keystore: make_ferdie_keystore()};
- s.run(ctx).await.unwrap();
- };
+ let bg = async move {
+ let s = StatementDistribution { metrics: Default::default(), keystore: make_ferdie_keystore()};
+ s.run(ctx).await.unwrap();
+ };
- let (mut tx_reqs, rx_reqs) = mpsc::channel(1);
+ let (mut tx_reqs, rx_reqs) = mpsc::channel(1);
- let test_fut = async move {
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::StatementFetchingReceiver(rx_reqs)
- }).await;
+ let test_fut = async move {
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::StatementFetchingReceiver(rx_reqs)
+ }).await;
- // register our active heads.
- handle.send(FromOverseer::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate {
- activated: vec![ActivatedLeaf {
- hash: hash_a,
- number: 1,
- status: LeafStatus::Fresh,
- span: Arc::new(jaeger::Span::Disabled),
- }].into(),
- deactivated: vec![].into(),
- }))).await;
+ // register our active heads.
+ handle.send(FromOverseer::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate {
+ activated: vec![ActivatedLeaf {
+ hash: hash_a,
+ number: 1,
+ status: LeafStatus::Fresh,
+ span: Arc::new(jaeger::Span::Disabled),
+ }].into(),
+ deactivated: vec![].into(),
+ }))).await;
- assert_matches!(
- handle.recv().await,
- AllMessages::RuntimeApi(
- RuntimeApiMessage::Request(r, RuntimeApiRequest::SessionIndexForChild(tx))
- )
- if r == hash_a
- => {
- let _ = tx.send(Ok(session_index));
- }
- );
+ assert_matches!(
+ handle.recv().await,
+ AllMessages::RuntimeApi(
+ RuntimeApiMessage::Request(r, RuntimeApiRequest::SessionIndexForChild(tx))
+ )
+ if r == hash_a
+ => {
+ let _ = tx.send(Ok(session_index));
+ }
+ );
- assert_matches!(
- handle.recv().await,
- AllMessages::RuntimeApi(
- RuntimeApiMessage::Request(r, RuntimeApiRequest::SessionInfo(sess_index, tx))
- )
- if r == hash_a && sess_index == session_index
- => {
- let _ = tx.send(Ok(Some(session_info)));
- }
- );
+ assert_matches!(
+ handle.recv().await,
+ AllMessages::RuntimeApi(
+ RuntimeApiMessage::Request(r, RuntimeApiRequest::SessionInfo(sess_index, tx))
+ )
+ if r == hash_a && sess_index == session_index
+ => {
+ let _ = tx.send(Ok(Some(session_info)));
+ }
+ );
- // notify of dummy peers and view
- for (peer, pair) in dummy_peers.clone().into_iter().zip(dummy_pairs) {
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerConnected(
- peer,
- ObservedRole::Full,
- Some(pair.public().into()),
- )
- )
- }).await;
+ // notify of dummy peers and view
+ for (peer, pair) in dummy_peers.clone().into_iter().zip(dummy_pairs) {
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerConnected(
+ peer,
+ ObservedRole::Full,
+ Some(pair.public().into()),
+ )
+ )
+ }).await;
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerViewChange(peer, view![hash_a])
- )
- }).await;
- }
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerViewChange(peer, view![hash_a])
+ )
+ }).await;
+ }
- // notify of peers and view
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerConnected(
- peer_a.clone(),
- ObservedRole::Full,
- Some(Sr25519Keyring::Alice.public().into())
- )
- )
- }).await;
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerConnected(
- peer_b.clone(),
- ObservedRole::Full,
- Some(Sr25519Keyring::Bob.public().into())
- )
- )
- }).await;
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerConnected(
- peer_c.clone(),
- ObservedRole::Full,
- Some(Sr25519Keyring::Charlie.public().into())
- )
- )
- }).await;
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerConnected(peer_bad.clone(), ObservedRole::Full, None)
- )
- }).await;
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerConnected(
- peer_other_group.clone(),
- ObservedRole::Full,
- Some(Sr25519Keyring::Dave.public().into())
- )
- )
- }).await;
+ // notify of peers and view
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerConnected(
+ peer_a.clone(),
+ ObservedRole::Full,
+ Some(Sr25519Keyring::Alice.public().into())
+ )
+ )
+ }).await;
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerConnected(
+ peer_b.clone(),
+ ObservedRole::Full,
+ Some(Sr25519Keyring::Bob.public().into())
+ )
+ )
+ }).await;
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerConnected(
+ peer_c.clone(),
+ ObservedRole::Full,
+ Some(Sr25519Keyring::Charlie.public().into())
+ )
+ )
+ }).await;
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerConnected(peer_bad.clone(), ObservedRole::Full, None)
+ )
+ }).await;
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerConnected(
+ peer_other_group.clone(),
+ ObservedRole::Full,
+ Some(Sr25519Keyring::Dave.public().into())
+ )
+ )
+ }).await;
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerViewChange(peer_a.clone(), view![hash_a])
- )
- }).await;
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerViewChange(peer_a.clone(), view![hash_a])
+ )
+ }).await;
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerViewChange(peer_b.clone(), view![hash_a])
- )
- }).await;
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerViewChange(peer_c.clone(), view![hash_a])
- )
- }).await;
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerViewChange(peer_bad.clone(), view![hash_a])
- )
- }).await;
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerViewChange(peer_other_group.clone(), view![hash_a])
- )
- }).await;
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerViewChange(peer_b.clone(), view![hash_a])
+ )
+ }).await;
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerViewChange(peer_c.clone(), view![hash_a])
+ )
+ }).await;
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerViewChange(peer_bad.clone(), view![hash_a])
+ )
+ }).await;
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerViewChange(peer_other_group.clone(), view![hash_a])
+ )
+ }).await;
- // receive a seconded statement from peer A, which does not provide the request data,
- // then get that data from peer C. It should be propagated onwards to peer B and to
- // candidate backing.
- let statement = {
- let signing_context = SigningContext {
- parent_hash: hash_a,
- session_index,
- };
+ // receive a seconded statement from peer A, which does not provide the request data,
+ // then get that data from peer C. It should be propagated onwards to peer B and to
+ // candidate backing.
+ let statement = {
+ let signing_context = SigningContext {
+ parent_hash: hash_a,
+ session_index,
+ };
- let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory());
- let ferdie_public = CryptoStore::sr25519_generate_new(
- &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Ferdie.to_seed())
- ).await.unwrap();
+ let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory());
+ let ferdie_public = CryptoStore::sr25519_generate_new(
+ &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Ferdie.to_seed())
+ ).await.unwrap();
- SignedFullStatement::sign(
- &keystore,
- Statement::Seconded(candidate.clone()),
- &signing_context,
- ValidatorIndex(4),
- &ferdie_public.into(),
- ).await.ok().flatten().expect("should be signed")
- };
+ SignedFullStatement::sign(
+ &keystore,
+ Statement::Seconded(candidate.clone()),
+ &signing_context,
+ ValidatorIndex(4),
+ &ferdie_public.into(),
+ ).await.ok().flatten().expect("should be signed")
+ };
- let metadata =
- protocol_v1::StatementDistributionMessage::Statement(hash_a, statement.clone().into()).get_metadata();
+ let metadata =
+ protocol_v1::StatementDistributionMessage::Statement(hash_a, statement.clone().into()).get_metadata();
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::Share(hash_a, statement.clone())
- }).await;
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::Share(hash_a, statement.clone())
+ }).await;
- // Messages should go out:
- assert_matches!(
- handle.recv().await,
- AllMessages::NetworkBridge(
- NetworkBridgeMessage::SendValidationMessage(
- mut recipients,
- protocol_v1::ValidationProtocol::StatementDistribution(
- protocol_v1::StatementDistributionMessage::LargeStatement(meta)
- ),
- )
- ) => {
- tracing::debug!(
- target: LOG_TARGET,
- ?recipients,
- "Recipients received"
- );
- recipients.sort();
- // We expect only our backing group to be the recipients, du to the inflated
- // test group above:
- let mut expected: Vec<_> = vec![peer_a, peer_b, peer_c].into_iter().chain(dummy_peers).collect();
- expected.sort();
- assert_eq!(recipients.len(), expected.len());
- assert_eq!(recipients, expected);
- assert_eq!(meta.relay_parent, hash_a);
- assert_eq!(meta.candidate_hash, statement.payload().candidate_hash());
- assert_eq!(meta.signed_by, statement.validator_index());
- assert_eq!(&meta.signature, statement.signature());
- }
- );
+ // Messages should go out:
+ assert_matches!(
+ handle.recv().await,
+ AllMessages::NetworkBridge(
+ NetworkBridgeMessage::SendValidationMessage(
+ mut recipients,
+ protocol_v1::ValidationProtocol::StatementDistribution(
+ protocol_v1::StatementDistributionMessage::LargeStatement(meta)
+ ),
+ )
+ ) => {
+ tracing::debug!(
+ target: LOG_TARGET,
+ ?recipients,
+ "Recipients received"
+ );
+ recipients.sort();
+ // We expect only our backing group to be the recipients, du to the inflated
+ // test group above:
+ let mut expected: Vec<_> = vec![peer_a, peer_b, peer_c].into_iter().chain(dummy_peers).collect();
+ expected.sort();
+ assert_eq!(recipients.len(), expected.len());
+ assert_eq!(recipients, expected);
+ assert_eq!(meta.relay_parent, hash_a);
+ assert_eq!(meta.candidate_hash, statement.payload().candidate_hash());
+ assert_eq!(meta.signed_by, statement.validator_index());
+ assert_eq!(&meta.signature, statement.signature());
+ }
+ );
- // Now that it has the candidate it should answer requests accordingly:
+ // Now that it has the candidate it should answer requests accordingly:
- let (pending_response, response_rx) = oneshot::channel();
- let inner_req = StatementFetchingRequest {
- relay_parent: metadata.relay_parent,
- candidate_hash: metadata.candidate_hash,
- };
- let req = sc_network::config::IncomingRequest {
- peer: peer_b,
- payload: inner_req.encode(),
- pending_response,
- };
- tx_reqs.send(req).await.unwrap();
- let StatementFetchingResponse::Statement(committed) =
- Decode::decode(&mut response_rx.await.unwrap().result.unwrap().as_ref()).unwrap();
- assert_eq!(committed, candidate);
+ let (pending_response, response_rx) = oneshot::channel();
+ let inner_req = StatementFetchingRequest {
+ relay_parent: metadata.relay_parent,
+ candidate_hash: metadata.candidate_hash,
+ };
+ let req = sc_network::config::IncomingRequest {
+ peer: peer_b,
+ payload: inner_req.encode(),
+ pending_response,
+ };
+ tx_reqs.send(req).await.unwrap();
+ let StatementFetchingResponse::Statement(committed) =
+ Decode::decode(&mut response_rx.await.unwrap().result.unwrap().as_ref()).unwrap();
+ assert_eq!(committed, candidate);
- handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await;
- };
+ handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await;
+ };
- futures::pin_mut!(test_fut);
- futures::pin_mut!(bg);
+ futures::pin_mut!(test_fut);
+ futures::pin_mut!(bg);
- executor::block_on(future::join(test_fut, bg));
+ executor::block_on(future::join(test_fut, bg));
}
#[test]
fn peer_cant_flood_with_large_statements() {
- sp_tracing::try_init_simple();
- let hash_a = Hash::repeat_byte(1);
+ sp_tracing::try_init_simple();
+ let hash_a = Hash::repeat_byte(1);
- let candidate = {
- let mut c = CommittedCandidateReceipt::default();
- c.descriptor.relay_parent = hash_a;
- c.descriptor.para_id = 1.into();
- c.commitments.new_validation_code = Some(ValidationCode(vec![1,2,3]));
- c
- };
+ let candidate = {
+ let mut c = CommittedCandidateReceipt::default();
+ c.descriptor.relay_parent = hash_a;
+ c.descriptor.para_id = 1.into();
+ c.commitments.new_validation_code = Some(ValidationCode(vec![1,2,3]));
+ c
+ };
- let peer_a = PeerId::random(); // Alice
+ let peer_a = PeerId::random(); // Alice
- let validators = vec![
- Sr25519Keyring::Alice.pair(),
- Sr25519Keyring::Bob.pair(),
- Sr25519Keyring::Charlie.pair(),
- // other group
- Sr25519Keyring::Dave.pair(),
- // We:
- Sr25519Keyring::Ferdie.pair(),
- ];
+ let validators = vec![
+ Sr25519Keyring::Alice.pair(),
+ Sr25519Keyring::Bob.pair(),
+ Sr25519Keyring::Charlie.pair(),
+ // other group
+ Sr25519Keyring::Dave.pair(),
+ // We:
+ Sr25519Keyring::Ferdie.pair(),
+ ];
- let first_group = vec![0,1,2,4];
- let session_info = make_session_info(
- validators,
- vec![first_group, vec![3]]
- );
+ let first_group = vec![0,1,2,4];
+ let session_info = make_session_info(
+ validators,
+ vec![first_group, vec![3]]
+ );
- let session_index = 1;
+ let session_index = 1;
- let pool = sp_core::testing::TaskExecutor::new();
- let (ctx, mut handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context(pool);
+ let pool = sp_core::testing::TaskExecutor::new();
+ let (ctx, mut handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context(pool);
- let bg = async move {
- let s = StatementDistribution { metrics: Default::default(), keystore: make_ferdie_keystore()};
- s.run(ctx).await.unwrap();
- };
+ let bg = async move {
+ let s = StatementDistribution { metrics: Default::default(), keystore: make_ferdie_keystore()};
+ s.run(ctx).await.unwrap();
+ };
- let (_, rx_reqs) = mpsc::channel(1);
+ let (_, rx_reqs) = mpsc::channel(1);
- let test_fut = async move {
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::StatementFetchingReceiver(rx_reqs)
- }).await;
+ let test_fut = async move {
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::StatementFetchingReceiver(rx_reqs)
+ }).await;
- // register our active heads.
- handle.send(FromOverseer::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate {
- activated: vec![ActivatedLeaf {
- hash: hash_a,
- number: 1,
- status: LeafStatus::Fresh,
- span: Arc::new(jaeger::Span::Disabled),
- }].into(),
- deactivated: vec![].into(),
- }))).await;
+ // register our active heads.
+ handle.send(FromOverseer::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate {
+ activated: vec![ActivatedLeaf {
+ hash: hash_a,
+ number: 1,
+ status: LeafStatus::Fresh,
+ span: Arc::new(jaeger::Span::Disabled),
+ }].into(),
+ deactivated: vec![].into(),
+ }))).await;
- assert_matches!(
- handle.recv().await,
- AllMessages::RuntimeApi(
- RuntimeApiMessage::Request(r, RuntimeApiRequest::SessionIndexForChild(tx))
- )
- if r == hash_a
- => {
- let _ = tx.send(Ok(session_index));
- }
- );
+ assert_matches!(
+ handle.recv().await,
+ AllMessages::RuntimeApi(
+ RuntimeApiMessage::Request(r, RuntimeApiRequest::SessionIndexForChild(tx))
+ )
+ if r == hash_a
+ => {
+ let _ = tx.send(Ok(session_index));
+ }
+ );
- assert_matches!(
- handle.recv().await,
- AllMessages::RuntimeApi(
- RuntimeApiMessage::Request(r, RuntimeApiRequest::SessionInfo(sess_index, tx))
- )
- if r == hash_a && sess_index == session_index
- => {
- let _ = tx.send(Ok(Some(session_info)));
- }
- );
+ assert_matches!(
+ handle.recv().await,
+ AllMessages::RuntimeApi(
+ RuntimeApiMessage::Request(r, RuntimeApiRequest::SessionInfo(sess_index, tx))
+ )
+ if r == hash_a && sess_index == session_index
+ => {
+ let _ = tx.send(Ok(Some(session_info)));
+ }
+ );
- // notify of peers and view
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerConnected(
- peer_a.clone(),
- ObservedRole::Full,
- Some(Sr25519Keyring::Alice.public().into())
- )
- )
- }).await;
+ // notify of peers and view
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerConnected(
+ peer_a.clone(),
+ ObservedRole::Full,
+ Some(Sr25519Keyring::Alice.public().into())
+ )
+ )
+ }).await;
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerViewChange(peer_a.clone(), view![hash_a])
- )
- }).await;
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerViewChange(peer_a.clone(), view![hash_a])
+ )
+ }).await;
- // receive a seconded statement from peer A.
- let statement = {
- let signing_context = SigningContext {
- parent_hash: hash_a,
- session_index,
- };
+ // receive a seconded statement from peer A.
+ let statement = {
+ let signing_context = SigningContext {
+ parent_hash: hash_a,
+ session_index,
+ };
- let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory());
- let alice_public = CryptoStore::sr25519_generate_new(
- &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Alice.to_seed())
- ).await.unwrap();
+ let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory());
+ let alice_public = CryptoStore::sr25519_generate_new(
+ &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Alice.to_seed())
+ ).await.unwrap();
- SignedFullStatement::sign(
- &keystore,
- Statement::Seconded(candidate.clone()),
- &signing_context,
- ValidatorIndex(0),
- &alice_public.into(),
- ).await.ok().flatten().expect("should be signed")
- };
+ SignedFullStatement::sign(
+ &keystore,
+ Statement::Seconded(candidate.clone()),
+ &signing_context,
+ ValidatorIndex(0),
+ &alice_public.into(),
+ ).await.ok().flatten().expect("should be signed")
+ };
- let metadata =
- protocol_v1::StatementDistributionMessage::Statement(hash_a, statement.clone().into()).get_metadata();
+ let metadata =
+ protocol_v1::StatementDistributionMessage::Statement(hash_a, statement.clone().into()).get_metadata();
- for _ in 0..MAX_LARGE_STATEMENTS_PER_SENDER + 1 {
- handle.send(FromOverseer::Communication {
- msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
- NetworkBridgeEvent::PeerMessage(
- peer_a.clone(),
- protocol_v1::StatementDistributionMessage::LargeStatement(metadata.clone()),
- )
- )
- }).await;
- }
+ for _ in 0..MAX_LARGE_STATEMENTS_PER_SENDER + 1 {
+ handle.send(FromOverseer::Communication {
+ msg: StatementDistributionMessage::NetworkBridgeUpdateV1(
+ NetworkBridgeEvent::PeerMessage(
+ peer_a.clone(),
+ protocol_v1::StatementDistributionMessage::LargeStatement(metadata.clone()),
+ )
+ )
+ }).await;
+ }
- // We should try to fetch the data and punish the peer (but we don't know what comes
- // first):
- let mut requested = false;
- let mut punished = false;
- for _ in 0..2 {
- match handle.recv().await {
- AllMessages::NetworkBridge(
- NetworkBridgeMessage::SendRequests(
- mut reqs, IfDisconnected::ImmediateError
- )
- ) => {
- let reqs = reqs.pop().unwrap();
- let outgoing = match reqs {
- Requests::StatementFetching(outgoing) => outgoing,
- _ => panic!("Unexpected request"),
- };
- let req = outgoing.payload;
- assert_eq!(req.relay_parent, metadata.relay_parent);
- assert_eq!(req.candidate_hash, metadata.candidate_hash);
- assert_eq!(outgoing.peer, Recipient::Peer(peer_a));
- // Just drop request - should trigger error.
- requested = true;
- }
+ // We should try to fetch the data and punish the peer (but we don't know what comes
+ // first):
+ let mut requested = false;
+ let mut punished = false;
+ for _ in 0..2 {
+ match handle.recv().await {
+ AllMessages::NetworkBridge(
+ NetworkBridgeMessage::SendRequests(
+ mut reqs, IfDisconnected::ImmediateError
+ )
+ ) => {
+ let reqs = reqs.pop().unwrap();
+ let outgoing = match reqs {
+ Requests::StatementFetching(outgoing) => outgoing,
+ _ => panic!("Unexpected request"),
+ };
+ let req = outgoing.payload;
+ assert_eq!(req.relay_parent, metadata.relay_parent);
+ assert_eq!(req.candidate_hash, metadata.candidate_hash);
+ assert_eq!(outgoing.peer, Recipient::Peer(peer_a));
+ // Just drop request - should trigger error.
+ requested = true;
+ }
- AllMessages::NetworkBridge(
- NetworkBridgeMessage::ReportPeer(p, r)
- ) if p == peer_a && r == COST_APPARENT_FLOOD => {
- punished = true;
- }
+ AllMessages::NetworkBridge(
+ NetworkBridgeMessage::ReportPeer(p, r)
+ ) if p == peer_a && r == COST_APPARENT_FLOOD => {
+ punished = true;
+ }
- m => panic!("Unexpected message: {:?}", m),
- }
- }
- assert!(requested, "large data has not been requested.");
- assert!(punished, "Peer should have been punished for flooding.");
+ m => panic!("Unexpected message: {:?}", m),
+ }
+ }
+ assert!(requested, "large data has not been requested.");
+ assert!(punished, "Peer should have been punished for flooding.");
- handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await;
- };
+ handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await;
+ };
- futures::pin_mut!(test_fut);
- futures::pin_mut!(bg);
+ futures::pin_mut!(test_fut);
+ futures::pin_mut!(bg);
- executor::block_on(future::join(test_fut, bg));
+ executor::block_on(future::join(test_fut, bg));
}
fn make_session_info(validators: Vec, groups: Vec>) -> SessionInfo {
- let validator_groups: Vec> = groups
- .iter().map(|g| g.into_iter().map(|v| ValidatorIndex(*v)).collect()).collect();
+ let validator_groups: Vec> = groups
+ .iter().map(|g| g.into_iter().map(|v| ValidatorIndex(*v)).collect()).collect();
- SessionInfo {
- discovery_keys: validators.iter().map(|k| k.public().into()).collect(),
- // Not used:
- n_cores: validator_groups.len() as u32,
- validator_groups,
- validators: validators.iter().map(|k| k.public().into()).collect(),
- // Not used values:
- assignment_keys: Vec::new(),
- zeroth_delay_tranche_width: 0,
- relay_vrf_modulo_samples: 0,
- n_delay_tranches: 0,
- no_show_slots: 0,
- needed_approvals: 0,
- }
+ SessionInfo {
+ discovery_keys: validators.iter().map(|k| k.public().into()).collect(),
+ // Not used:
+ n_cores: validator_groups.len() as u32,
+ validator_groups,
+ validators: validators.iter().map(|k| k.public().into()).collect(),
+ // Not used values:
+ assignment_keys: Vec::new(),
+ zeroth_delay_tranche_width: 0,
+ relay_vrf_modulo_samples: 0,
+ n_delay_tranches: 0,
+ no_show_slots: 0,
+ needed_approvals: 0,
+ }
}
pub fn make_ferdie_keystore() -> SyncCryptoStorePtr {
- let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory());
- SyncCryptoStore::sr25519_generate_new(
- &*keystore,
- ValidatorId::ID,
- Some(&Sr25519Keyring::Ferdie.to_seed()),
- )
- .expect("Insert key into keystore");
- keystore
+ let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory());
+ SyncCryptoStore::sr25519_generate_new(
+ &*keystore,
+ ValidatorId::ID,
+ Some(&Sr25519Keyring::Ferdie.to_seed()),
+ )
+ .expect("Insert key into keystore");
+ keystore
}
diff --git a/polkadot/node/overseer/src/lib.rs b/polkadot/node/overseer/src/lib.rs
index 2463e545fd..8dbd22b8fc 100644
--- a/polkadot/node/overseer/src/lib.rs
+++ b/polkadot/node/overseer/src/lib.rs
@@ -98,6 +98,9 @@ use polkadot_node_subsystem_util::{TimeoutExt, metrics::{self, prometheus}, mete
use polkadot_node_primitives::SpawnNamed;
use polkadot_procmacro_overseer_subsystems_gen::AllSubsystemsGen;
+#[cfg(test)]
+mod tests;
+
// A capacity of bounded channels inside the overseer.
const CHANNEL_CAPACITY: usize = 1024;
// The capacity of signal channels to subsystems.
@@ -2196,6 +2199,3 @@ fn spawn(
instance,
})
}
-
-#[cfg(test)]
-mod tests;
diff --git a/polkadot/node/overseer/src/tests.rs b/polkadot/node/overseer/src/tests.rs
index 6e5383b21c..c33a01dabf 100644
--- a/polkadot/node/overseer/src/tests.rs
+++ b/polkadot/node/overseer/src/tests.rs
@@ -32,231 +32,231 @@ use super::*;
struct TestSubsystem1(metered::MeteredSender);
impl Subsystem for TestSubsystem1
- where C: SubsystemContext
+ where C: SubsystemContext
{
- fn start(self, mut ctx: C) -> SpawnedSubsystem {
- let mut sender = self.0;
- SpawnedSubsystem {
- name: "test-subsystem-1",
- future: Box::pin(async move {
- let mut i = 0;
- loop {
- match ctx.recv().await {
- Ok(FromOverseer::Communication { .. }) => {
- let _ = sender.send(i).await;
- i += 1;
- continue;
- }
- Ok(FromOverseer::Signal(OverseerSignal::Conclude)) => return Ok(()),
- Err(_) => return Ok(()),
- _ => (),
- }
- }
- }),
- }
- }
+ fn start(self, mut ctx: C) -> SpawnedSubsystem {
+ let mut sender = self.0;
+ SpawnedSubsystem {
+ name: "test-subsystem-1",
+ future: Box::pin(async move {
+ let mut i = 0;
+ loop {
+ match ctx.recv().await {
+ Ok(FromOverseer::Communication { .. }) => {
+ let _ = sender.send(i).await;
+ i += 1;
+ continue;
+ }
+ Ok(FromOverseer::Signal(OverseerSignal::Conclude)) => return Ok(()),
+ Err(_) => return Ok(()),
+ _ => (),
+ }
+ }
+ }),
+ }
+ }
}
struct TestSubsystem2(metered::MeteredSender);
impl Subsystem for TestSubsystem2
- where C: SubsystemContext
+ where C: SubsystemContext
{
- fn start(self, mut ctx: C) -> SpawnedSubsystem {
- let sender = self.0.clone();
- SpawnedSubsystem {
- name: "test-subsystem-2",
- future: Box::pin(async move {
- let _sender = sender;
- let mut c: usize = 0;
- loop {
- if c < 10 {
- let (tx, _) = oneshot::channel();
- ctx.send_message(
- AllMessages::CandidateValidation(
- CandidateValidationMessage::ValidateFromChainState(
- Default::default(),
- PoV {
- block_data: BlockData(Vec::new()),
- }.into(),
- tx,
- )
- )
- ).await;
- c += 1;
- continue;
- }
- match ctx.try_recv().await {
- Ok(Some(FromOverseer::Signal(OverseerSignal::Conclude))) => {
- break;
- }
- Ok(Some(_)) => {
- continue;
- }
- Err(_) => return Ok(()),
- _ => (),
- }
- pending!();
- }
+ fn start(self, mut ctx: C) -> SpawnedSubsystem {
+ let sender = self.0.clone();
+ SpawnedSubsystem {
+ name: "test-subsystem-2",
+ future: Box::pin(async move {
+ let _sender = sender;
+ let mut c: usize = 0;
+ loop {
+ if c < 10 {
+ let (tx, _) = oneshot::channel();
+ ctx.send_message(
+ AllMessages::CandidateValidation(
+ CandidateValidationMessage::ValidateFromChainState(
+ Default::default(),
+ PoV {
+ block_data: BlockData(Vec::new()),
+ }.into(),
+ tx,
+ )
+ )
+ ).await;
+ c += 1;
+ continue;
+ }
+ match ctx.try_recv().await {
+ Ok(Some(FromOverseer::Signal(OverseerSignal::Conclude))) => {
+ break;
+ }
+ Ok(Some(_)) => {
+ continue;
+ }
+ Err(_) => return Ok(()),
+ _ => (),
+ }
+ pending!();
+ }
- Ok(())
- }),
- }
- }
+ Ok(())
+ }),
+ }
+ }
}
struct ReturnOnStart;
impl Subsystem for ReturnOnStart
- where C: SubsystemContext
+ where C: SubsystemContext
{
- fn start(self, mut _ctx: C) -> SpawnedSubsystem {
- SpawnedSubsystem {
- name: "test-subsystem-4",
- future: Box::pin(async move {
- // Do nothing and exit.
- Ok(())
- }),
- }
- }
+ fn start(self, mut _ctx: C) -> SpawnedSubsystem {
+ SpawnedSubsystem {
+ name: "test-subsystem-4",
+ future: Box::pin(async move {
+ // Do nothing and exit.
+ Ok(())
+ }),
+ }
+ }
}
struct MockSupportsParachains;
impl HeadSupportsParachains for MockSupportsParachains {
- fn head_supports_parachains(&self, _head: &Hash) -> bool {
- true
- }
+ fn head_supports_parachains(&self, _head: &Hash) -> bool {
+ true
+ }
}
// Checks that a minimal configuration of two jobs can run and exchange messages.
#[test]
fn overseer_works() {
- let spawner = sp_core::testing::TaskExecutor::new();
+ let spawner = sp_core::testing::TaskExecutor::new();
- executor::block_on(async move {
- let (s1_tx, s1_rx) = metered::channel::(64);
- let (s2_tx, s2_rx) = metered::channel::(64);
+ executor::block_on(async move {
+ let (s1_tx, s1_rx) = metered::channel::(64);
+ let (s2_tx, s2_rx) = metered::channel::(64);
- let mut s1_rx = s1_rx.fuse();
- let mut s2_rx = s2_rx.fuse();
+ let mut s1_rx = s1_rx.fuse();
+ let mut s2_rx = s2_rx.fuse();
- let all_subsystems = AllSubsystems::<()>::dummy()
- .replace_candidate_validation(TestSubsystem1(s1_tx))
- .replace_candidate_backing(TestSubsystem2(s2_tx));
+ let all_subsystems = AllSubsystems::<()>::dummy()
+ .replace_candidate_validation(TestSubsystem1(s1_tx))
+ .replace_candidate_backing(TestSubsystem2(s2_tx));
- let (overseer, mut handler) = Overseer::new(
- vec![],
- all_subsystems,
- None,
- MockSupportsParachains,
- spawner,
- ).unwrap();
- let overseer_fut = overseer.run().fuse();
+ let (overseer, mut handler) = Overseer::new(
+ vec![],
+ all_subsystems,
+ None,
+ MockSupportsParachains,
+ spawner,
+ ).unwrap();
+ let overseer_fut = overseer.run().fuse();
- pin_mut!(overseer_fut);
+ pin_mut!(overseer_fut);
- let mut s1_results = Vec::new();
- let mut s2_results = Vec::new();
+ let mut s1_results = Vec::new();
+ let mut s2_results = Vec::new();
- loop {
- select! {
- _ = overseer_fut => break,
- s1_next = s1_rx.next() => {
- match s1_next {
- Some(msg) => {
- s1_results.push(msg);
- if s1_results.len() == 10 {
- handler.stop().await;
- }
- }
- None => break,
- }
- },
- s2_next = s2_rx.next() => {
- match s2_next {
- Some(_) => s2_results.push(s2_next),
- None => break,
- }
- },
- complete => break,
- }
- }
+ loop {
+ select! {
+ _ = overseer_fut => break,
+ s1_next = s1_rx.next() => {
+ match s1_next {
+ Some(msg) => {
+ s1_results.push(msg);
+ if s1_results.len() == 10 {
+ handler.stop().await;
+ }
+ }
+ None => break,
+ }
+ },
+ s2_next = s2_rx.next() => {
+ match s2_next {
+ Some(_) => s2_results.push(s2_next),
+ None => break,
+ }
+ },
+ complete => break,
+ }
+ }
- assert_eq!(s1_results, (0..10).collect::>());
- });
+ assert_eq!(s1_results, (0..10).collect::>());
+ });
}
// Checks activated/deactivated metrics are updated properly.
#[test]
fn overseer_metrics_work() {
- let spawner = sp_core::testing::TaskExecutor::new();
+ let spawner = sp_core::testing::TaskExecutor::new();
- executor::block_on(async move {
- let first_block_hash = [1; 32].into();
- let second_block_hash = [2; 32].into();
- let third_block_hash = [3; 32].into();
+ executor::block_on(async move {
+ let first_block_hash = [1; 32].into();
+ let second_block_hash = [2; 32].into();
+ let third_block_hash = [3; 32].into();
- let first_block = BlockInfo {
- hash: first_block_hash,
- parent_hash: [0; 32].into(),
- number: 1,
- };
- let second_block = BlockInfo {
- hash: second_block_hash,
- parent_hash: first_block_hash,
- number: 2,
- };
- let third_block = BlockInfo {
- hash: third_block_hash,
- parent_hash: second_block_hash,
- number: 3,
- };
+ let first_block = BlockInfo {
+ hash: first_block_hash,
+ parent_hash: [0; 32].into(),
+ number: 1,
+ };
+ let second_block = BlockInfo {
+ hash: second_block_hash,
+ parent_hash: first_block_hash,
+ number: 2,
+ };
+ let third_block = BlockInfo {
+ hash: third_block_hash,
+ parent_hash: second_block_hash,
+ number: 3,
+ };
- let all_subsystems = AllSubsystems::<()>::dummy();
- let registry = prometheus::Registry::new();
- let (overseer, mut handler) = Overseer::new(
- vec![first_block],
- all_subsystems,
- Some(®istry),
- MockSupportsParachains,
- spawner,
- ).unwrap();
- let overseer_fut = overseer.run().fuse();
+ let all_subsystems = AllSubsystems::<()>::dummy();
+ let registry = prometheus::Registry::new();
+ let (overseer, mut handler) = Overseer::new(
+ vec![first_block],
+ all_subsystems,
+ Some(®istry),
+ MockSupportsParachains,
+ spawner,
+ ).unwrap();
+ let overseer_fut = overseer.run().fuse();
- pin_mut!(overseer_fut);
+ pin_mut!(overseer_fut);
- handler.block_imported(second_block).await;
- handler.block_imported(third_block).await;
- handler.send_msg(AllMessages::CandidateValidation(test_candidate_validation_msg())).await;
- handler.stop().await;
+ handler.block_imported(second_block).await;
+ handler.block_imported(third_block).await;
+ handler.send_msg(AllMessages::CandidateValidation(test_candidate_validation_msg())).await;
+ handler.stop().await;
- select! {
- res = overseer_fut => {
- assert!(res.is_ok());
- let metrics = extract_metrics(®istry);
- assert_eq!(metrics["activated"], 3);
- assert_eq!(metrics["deactivated"], 2);
- assert_eq!(metrics["relayed"], 1);
- },
- complete => (),
- }
- });
+ select! {
+ res = overseer_fut => {
+ assert!(res.is_ok());
+ let metrics = extract_metrics(®istry);
+ assert_eq!(metrics["activated"], 3);
+ assert_eq!(metrics["deactivated"], 2);
+ assert_eq!(metrics["relayed"], 1);
+ },
+ complete => (),
+ }
+ });
}
fn extract_metrics(registry: &prometheus::Registry) -> HashMap<&'static str, u64> {
- let gather = registry.gather();
- assert_eq!(gather[0].get_name(), "parachain_activated_heads_total");
- assert_eq!(gather[1].get_name(), "parachain_deactivated_heads_total");
- assert_eq!(gather[2].get_name(), "parachain_messages_relayed_total");
- let activated = gather[0].get_metric()[0].get_counter().get_value() as u64;
- let deactivated = gather[1].get_metric()[0].get_counter().get_value() as u64;
- let relayed = gather[2].get_metric()[0].get_counter().get_value() as u64;
- let mut result = HashMap::new();
- result.insert("activated", activated);
- result.insert("deactivated", deactivated);
- result.insert("relayed", relayed);
- result
+ let gather = registry.gather();
+ assert_eq!(gather[0].get_name(), "parachain_activated_heads_total");
+ assert_eq!(gather[1].get_name(), "parachain_deactivated_heads_total");
+ assert_eq!(gather[2].get_name(), "parachain_messages_relayed_total");
+ let activated = gather[0].get_metric()[0].get_counter().get_value() as u64;
+ let deactivated = gather[1].get_metric()[0].get_counter().get_value() as u64;
+ let relayed = gather[2].get_metric()[0].get_counter().get_value() as u64;
+ let mut result = HashMap::new();
+ result.insert("activated", activated);
+ result.insert("deactivated", deactivated);
+ result.insert("relayed", relayed);
+ result
}
// Spawn a subsystem that immediately exits.
@@ -264,890 +264,890 @@ fn extract_metrics(registry: &prometheus::Registry) -> HashMap<&'static str, u64
// Should immediately conclude the overseer itself.
#[test]
fn overseer_ends_on_subsystem_exit() {
- let spawner = sp_core::testing::TaskExecutor::new();
+ let spawner = sp_core::testing::TaskExecutor::new();
- executor::block_on(async move {
- let all_subsystems = AllSubsystems::<()>::dummy()
- .replace_candidate_backing(ReturnOnStart);
- let (overseer, _handle) = Overseer::new(
- vec![],
- all_subsystems,
- None,
- MockSupportsParachains,
- spawner,
- ).unwrap();
+ executor::block_on(async move {
+ let all_subsystems = AllSubsystems::<()>::dummy()
+ .replace_candidate_backing(ReturnOnStart);
+ let (overseer, _handle) = Overseer::new(
+ vec![],
+ all_subsystems,
+ None,
+ MockSupportsParachains,
+ spawner,
+ ).unwrap();
- overseer.run().await.unwrap();
- })
+ overseer.run().await.unwrap();
+ })
}
struct TestSubsystem5(metered::MeteredSender);
impl Subsystem for TestSubsystem5
- where C: SubsystemContext
+ where C: SubsystemContext
{
- fn start(self, mut ctx: C) -> SpawnedSubsystem {
- let mut sender = self.0.clone();
+ fn start(self, mut ctx: C) -> SpawnedSubsystem {
+ let mut sender = self.0.clone();
- SpawnedSubsystem {
- name: "test-subsystem-5",
- future: Box::pin(async move {
- loop {
- match ctx.try_recv().await {
- Ok(Some(FromOverseer::Signal(OverseerSignal::Conclude))) => break,
- Ok(Some(FromOverseer::Signal(s))) => {
- sender.send(s).await.unwrap();
- continue;
- },
- Ok(Some(_)) => continue,
- Err(_) => break,
- _ => (),
- }
- pending!();
- }
+ SpawnedSubsystem {
+ name: "test-subsystem-5",
+ future: Box::pin(async move {
+ loop {
+ match ctx.try_recv().await {
+ Ok(Some(FromOverseer::Signal(OverseerSignal::Conclude))) => break,
+ Ok(Some(FromOverseer::Signal(s))) => {
+ sender.send(s).await.unwrap();
+ continue;
+ },
+ Ok(Some(_)) => continue,
+ Err(_) => break,
+ _ => (),
+ }
+ pending!();
+ }
- Ok(())
- }),
- }
- }
+ Ok(())
+ }),
+ }
+ }
}
struct TestSubsystem6(metered::MeteredSender);
impl Subsystem for TestSubsystem6
- where C: SubsystemContext
+ where C: SubsystemContext
{
- fn start(self, mut ctx: C) -> SpawnedSubsystem {
- let mut sender = self.0.clone();
+ fn start(self, mut ctx: C) -> SpawnedSubsystem {
+ let mut sender = self.0.clone();
- SpawnedSubsystem {
- name: "test-subsystem-6",
- future: Box::pin(async move {
- loop {
- match ctx.try_recv().await {
- Ok(Some(FromOverseer::Signal(OverseerSignal::Conclude))) => break,
- Ok(Some(FromOverseer::Signal(s))) => {
- sender.send(s).await.unwrap();
- continue;
- },
- Ok(Some(_)) => continue,
- Err(_) => break,
- _ => (),
- }
- pending!();
- }
+ SpawnedSubsystem {
+ name: "test-subsystem-6",
+ future: Box::pin(async move {
+ loop {
+ match ctx.try_recv().await {
+ Ok(Some(FromOverseer::Signal(OverseerSignal::Conclude))) => break,
+ Ok(Some(FromOverseer::Signal(s))) => {
+ sender.send(s).await.unwrap();
+ continue;
+ },
+ Ok(Some(_)) => continue,
+ Err(_) => break,
+ _ => (),
+ }
+ pending!();
+ }
- Ok(())
- }),
- }
- }
+ Ok(())
+ }),
+ }
+ }
}
// Tests that starting with a defined set of leaves and receiving
// notifications on imported blocks triggers expected `StartWork` and `StopWork` heartbeats.
#[test]
fn overseer_start_stop_works() {
- let spawner = sp_core::testing::TaskExecutor::new();
+ let spawner = sp_core::testing::TaskExecutor::new();
- executor::block_on(async move {
- let first_block_hash = [1; 32].into();
- let second_block_hash = [2; 32].into();
- let third_block_hash = [3; 32].into();
+ executor::block_on(async move {
+ let first_block_hash = [1; 32].into();
+ let second_block_hash = [2; 32].into();
+ let third_block_hash = [3; 32].into();
- let first_block = BlockInfo {
- hash: first_block_hash,
- parent_hash: [0; 32].into(),
- number: 1,
- };
- let second_block = BlockInfo {
- hash: second_block_hash,
- parent_hash: first_block_hash,
- number: 2,
- };
- let third_block = BlockInfo {
- hash: third_block_hash,
- parent_hash: second_block_hash,
- number: 3,
- };
+ let first_block = BlockInfo {
+ hash: first_block_hash,
+ parent_hash: [0; 32].into(),
+ number: 1,
+ };
+ let second_block = BlockInfo {
+ hash: second_block_hash,
+ parent_hash: first_block_hash,
+ number: 2,
+ };
+ let third_block = BlockInfo {
+ hash: third_block_hash,
+ parent_hash: second_block_hash,
+ number: 3,
+ };
- let (tx_5, mut rx_5) = metered::channel(64);
- let (tx_6, mut rx_6) = metered::channel(64);
- let all_subsystems = AllSubsystems::<()>::dummy()
- .replace_candidate_validation(TestSubsystem5(tx_5))
- .replace_candidate_backing(TestSubsystem6(tx_6));
- let (overseer, mut handler) = Overseer::new(
- vec![first_block],
- all_subsystems,
- None,
- MockSupportsParachains,
- spawner,
- ).unwrap();
+ let (tx_5, mut rx_5) = metered::channel(64);
+ let (tx_6, mut rx_6) = metered::channel(64);
+ let all_subsystems = AllSubsystems::<()>::dummy()
+ .replace_candidate_validation(TestSubsystem5(tx_5))
+ .replace_candidate_backing(TestSubsystem6(tx_6));
+ let (overseer, mut handler) = Overseer::new(
+ vec![first_block],
+ all_subsystems,
+ None,
+ MockSupportsParachains,
+ spawner,
+ ).unwrap();
- let overseer_fut = overseer.run().fuse();
- pin_mut!(overseer_fut);
+ let overseer_fut = overseer.run().fuse();
+ pin_mut!(overseer_fut);
- let mut ss5_results = Vec::new();
- let mut ss6_results = Vec::new();
+ let mut ss5_results = Vec::new();
+ let mut ss6_results = Vec::new();
- handler.block_imported(second_block).await;
- handler.block_imported(third_block).await;
+ handler.block_imported(second_block).await;
+ handler.block_imported(third_block).await;
- let expected_heartbeats = vec![
- OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf {
- hash: first_block_hash,
- number: 1,
- status: LeafStatus::Fresh,
- span: Arc::new(jaeger::Span::Disabled),
- })),
- OverseerSignal::ActiveLeaves(ActiveLeavesUpdate {
- activated: [ActivatedLeaf {
- hash: second_block_hash,
- number: 2,
- status: LeafStatus::Fresh,
- span: Arc::new(jaeger::Span::Disabled),
- }].as_ref().into(),
- deactivated: [first_block_hash].as_ref().into(),
- }),
- OverseerSignal::ActiveLeaves(ActiveLeavesUpdate {
- activated: [ActivatedLeaf {
- hash: third_block_hash,
- number: 3,
- status: LeafStatus::Fresh,
- span: Arc::new(jaeger::Span::Disabled),
- }].as_ref().into(),
- deactivated: [second_block_hash].as_ref().into(),
- }),
- ];
+ let expected_heartbeats = vec![
+ OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf {
+ hash: first_block_hash,
+ number: 1,
+ status: LeafStatus::Fresh,
+ span: Arc::new(jaeger::Span::Disabled),
+ })),
+ OverseerSignal::ActiveLeaves(ActiveLeavesUpdate {
+ activated: [ActivatedLeaf {
+ hash: second_block_hash,
+ number: 2,
+ status: LeafStatus::Fresh,
+ span: Arc::new(jaeger::Span::Disabled),
+ }].as_ref().into(),
+ deactivated: [first_block_hash].as_ref().into(),
+ }),
+ OverseerSignal::ActiveLeaves(ActiveLeavesUpdate {
+ activated: [ActivatedLeaf {
+ hash: third_block_hash,
+ number: 3,
+ status: LeafStatus::Fresh,
+ span: Arc::new(jaeger::Span::Disabled),
+ }].as_ref().into(),
+ deactivated: [second_block_hash].as_ref().into(),
+ }),
+ ];
- loop {
- select! {
- res = overseer_fut => {
- assert!(res.is_ok());
- break;
- },
- res = rx_5.next() => {
- if let Some(res) = res {
- ss5_results.push(res);
- }
- }
- res = rx_6.next() => {
- if let Some(res) = res {
- ss6_results.push(res);
- }
- }
- complete => break,
- }
+ loop {
+ select! {
+ res = overseer_fut => {
+ assert!(res.is_ok());
+ break;
+ },
+ res = rx_5.next() => {
+ if let Some(res) = res {
+ ss5_results.push(res);
+ }
+ }
+ res = rx_6.next() => {
+ if let Some(res) = res {
+ ss6_results.push(res);
+ }
+ }
+ complete => break,
+ }
- if ss5_results.len() == expected_heartbeats.len() &&
- ss6_results.len() == expected_heartbeats.len() {
- handler.stop().await;
- }
- }
+ if ss5_results.len() == expected_heartbeats.len() &&
+ ss6_results.len() == expected_heartbeats.len() {
+ handler.stop().await;
+ }
+ }
- assert_eq!(ss5_results, expected_heartbeats);
- assert_eq!(ss6_results, expected_heartbeats);
- });
+ assert_eq!(ss5_results, expected_heartbeats);
+ assert_eq!(ss6_results, expected_heartbeats);
+ });
}
// Tests that starting with a defined set of leaves and receiving
// notifications on imported blocks triggers expected `StartWork` and `StopWork` heartbeats.
#[test]
fn overseer_finalize_works() {
- let spawner = sp_core::testing::TaskExecutor::new();
+ let spawner = sp_core::testing::TaskExecutor::new();
- executor::block_on(async move {
- let first_block_hash = [1; 32].into();
- let second_block_hash = [2; 32].into();
- let third_block_hash = [3; 32].into();
+ executor::block_on(async move {
+ let first_block_hash = [1; 32].into();
+ let second_block_hash = [2; 32].into();
+ let third_block_hash = [3; 32].into();
- let first_block = BlockInfo {
- hash: first_block_hash,
- parent_hash: [0; 32].into(),
- number: 1,
- };
- let second_block = BlockInfo {
- hash: second_block_hash,
- parent_hash: [42; 32].into(),
- number: 2,
- };
- let third_block = BlockInfo {
- hash: third_block_hash,
- parent_hash: second_block_hash,
- number: 3,
- };
+ let first_block = BlockInfo {
+ hash: first_block_hash,
+ parent_hash: [0; 32].into(),
+ number: 1,
+ };
+ let second_block = BlockInfo {
+ hash: second_block_hash,
+ parent_hash: [42; 32].into(),
+ number: 2,
+ };
+ let third_block = BlockInfo {
+ hash: third_block_hash,
+ parent_hash: second_block_hash,
+ number: 3,
+ };
- let (tx_5, mut rx_5) = metered::channel(64);
- let (tx_6, mut rx_6) = metered::channel(64);
+ let (tx_5, mut rx_5) = metered::channel(64);
+ let (tx_6, mut rx_6) = metered::channel(64);
- let all_subsystems = AllSubsystems::<()>::dummy()
- .replace_candidate_validation(TestSubsystem5(tx_5))
- .replace_candidate_backing(TestSubsystem6(tx_6));
+ let all_subsystems = AllSubsystems::<()>::dummy()
+ .replace_candidate_validation(TestSubsystem5(tx_5))
+ .replace_candidate_backing(TestSubsystem6(tx_6));
- // start with two forks of different height.
- let (overseer, mut handler) = Overseer::new(
- vec![first_block, second_block],
- all_subsystems,
- None,
- MockSupportsParachains,
- spawner,
- ).unwrap();
+ // start with two forks of different height.
+ let (overseer, mut handler) = Overseer::new(
+ vec![first_block, second_block],
+ all_subsystems,
+ None,
+ MockSupportsParachains,
+ spawner,
+ ).unwrap();
- let overseer_fut = overseer.run().fuse();
- pin_mut!(overseer_fut);
+ let overseer_fut = overseer.run().fuse();
+ pin_mut!(overseer_fut);
- let mut ss5_results = Vec::new();
- let mut ss6_results = Vec::new();
+ let mut ss5_results = Vec::new();
+ let mut ss6_results = Vec::new();
- // this should stop work on both forks we started with earlier.
- handler.block_finalized(third_block).await;
+ // this should stop work on both forks we started with earlier.
+ handler.block_finalized(third_block).await;
- let expected_heartbeats = vec![
- OverseerSignal::ActiveLeaves(ActiveLeavesUpdate {
- activated: [
- ActivatedLeaf {
- hash: first_block_hash,
- number: 1,
- status: LeafStatus::Fresh,
- span: Arc::new(jaeger::Span::Disabled),
- },
- ActivatedLeaf {
- hash: second_block_hash,
- number: 2,
- status: LeafStatus::Fresh,
- span: Arc::new(jaeger::Span::Disabled),
- },
- ].as_ref().into(),
- ..Default::default()
- }),
- OverseerSignal::ActiveLeaves(ActiveLeavesUpdate {
- deactivated: [first_block_hash, second_block_hash].as_ref().into(),
- ..Default::default()
- }),
- OverseerSignal::BlockFinalized(third_block_hash, 3),
- ];
+ let expected_heartbeats = vec![
+ OverseerSignal::ActiveLeaves(ActiveLeavesUpdate {
+ activated: [
+ ActivatedLeaf {
+ hash: first_block_hash,
+ number: 1,
+ status: LeafStatus::Fresh,
+ span: Arc::new(jaeger::Span::Disabled),
+ },
+ ActivatedLeaf {
+ hash: second_block_hash,
+ number: 2,
+ status: LeafStatus::Fresh,
+ span: Arc::new(jaeger::Span::Disabled),
+ },
+ ].as_ref().into(),
+ ..Default::default()
+ }),
+ OverseerSignal::ActiveLeaves(ActiveLeavesUpdate {
+ deactivated: [first_block_hash, second_block_hash].as_ref().into(),
+ ..Default::default()
+ }),
+ OverseerSignal::BlockFinalized(third_block_hash, 3),
+ ];
- loop {
- select! {
- res = overseer_fut => {
- assert!(res.is_ok());
- break;
- },
- res = rx_5.next() => {
- if let Some(res) = res {
- ss5_results.push(res);
- }
- }
- res = rx_6.next() => {
- if let Some(res) = res {
- ss6_results.push(res);
- }
- }
- complete => break,
- }
+ loop {
+ select! {
+ res = overseer_fut => {
+ assert!(res.is_ok());
+ break;
+ },
+ res = rx_5.next() => {
+ if let Some(res) = res {
+ ss5_results.push(res);
+ }
+ }
+ res = rx_6.next() => {
+ if let Some(res) = res {
+ ss6_results.push(res);
+ }
+ }
+ complete => break,
+ }
- if ss5_results.len() == expected_heartbeats.len() && ss6_results.len() == expected_heartbeats.len() {
- handler.stop().await;
- }
- }
+ if ss5_results.len() == expected_heartbeats.len() && ss6_results.len() == expected_heartbeats.len() {
+ handler.stop().await;
+ }
+ }
- assert_eq!(ss5_results.len(), expected_heartbeats.len());
- assert_eq!(ss6_results.len(), expected_heartbeats.len());
+ assert_eq!(ss5_results.len(), expected_heartbeats.len());
+ assert_eq!(ss6_results.len(), expected_heartbeats.len());
- // Notifications on finality for multiple blocks at once
- // may be received in different orders.
- for expected in expected_heartbeats {
- assert!(ss5_results.contains(&expected));
- assert!(ss6_results.contains(&expected));
- }
- });
+ // Notifications on finality for multiple blocks at once
+ // may be received in different orders.
+ for expected in expected_heartbeats {
+ assert!(ss5_results.contains(&expected));
+ assert!(ss6_results.contains(&expected));
+ }
+ });
}
#[test]
fn do_not_send_empty_leaves_update_on_block_finalization() {
- let spawner = sp_core::testing::TaskExecutor::new();
+ let spawner = sp_core::testing::TaskExecutor::new();
- executor::block_on(async move {
- let imported_block = BlockInfo {
- hash: Hash::random(),
- parent_hash: Hash::random(),
- number: 1,
- };
+ executor::block_on(async move {
+ let imported_block = BlockInfo {
+ hash: Hash::random(),
+ parent_hash: Hash::random(),
+ number: 1,
+ };
- let finalized_block = BlockInfo {
- hash: Hash::random(),
- parent_hash: Hash::random(),
- number: 1,
- };
+ let finalized_block = BlockInfo {
+ hash: Hash::random(),
+ parent_hash: Hash::random(),
+ number: 1,
+ };
- let (tx_5, mut rx_5) = metered::channel(64);
+ let (tx_5, mut rx_5) = metered::channel(64);
- let all_subsystems = AllSubsystems::<()>::dummy()
- .replace_candidate_backing(TestSubsystem6(tx_5));
+ let all_subsystems = AllSubsystems::<()>::dummy()
+ .replace_candidate_backing(TestSubsystem6(tx_5));
- let (overseer, mut handler) = Overseer::new(
- Vec::new(),
- all_subsystems,
- None,
- MockSupportsParachains,
- spawner,
- ).unwrap();
+ let (overseer, mut handler) = Overseer::new(
+ Vec::new(),
+ all_subsystems,
+ None,
+ MockSupportsParachains,
+ spawner,
+ ).unwrap();
- let overseer_fut = overseer.run().fuse();
- pin_mut!(overseer_fut);
+ let overseer_fut = overseer.run().fuse();
+ pin_mut!(overseer_fut);
- let mut ss5_results = Vec::new();
+ let mut ss5_results = Vec::new();
- handler.block_finalized(finalized_block.clone()).await;
- handler.block_imported(imported_block.clone()).await;
+ handler.block_finalized(finalized_block.clone()).await;
+ handler.block_imported(imported_block.clone()).await;
- let expected_heartbeats = vec![
- OverseerSignal::ActiveLeaves(ActiveLeavesUpdate {
- activated: [
- ActivatedLeaf {
- hash: imported_block.hash,
- number: imported_block.number,
- status: LeafStatus::Fresh,
- span: Arc::new(jaeger::Span::Disabled)
- }
- ].as_ref().into(),
- ..Default::default()
- }),
- OverseerSignal::BlockFinalized(finalized_block.hash, 1),
- ];
+ let expected_heartbeats = vec![
+ OverseerSignal::ActiveLeaves(ActiveLeavesUpdate {
+ activated: [
+ ActivatedLeaf {
+ hash: imported_block.hash,
+ number: imported_block.number,
+ status: LeafStatus::Fresh,
+ span: Arc::new(jaeger::Span::Disabled)
+ }
+ ].as_ref().into(),
+ ..Default::default()
+ }),
+ OverseerSignal::BlockFinalized(finalized_block.hash, 1),
+ ];
- loop {
- select! {
- res = overseer_fut => {
- assert!(res.is_ok());
- break;
- },
- res = rx_5.next() => {
- if let Some(res) = dbg!(res) {
- ss5_results.push(res);
- }
- }
- }
+ loop {
+ select! {
+ res = overseer_fut => {
+ assert!(res.is_ok());
+ break;
+ },
+ res = rx_5.next() => {
+ if let Some(res) = dbg!(res) {
+ ss5_results.push(res);
+ }
+ }
+ }
- if ss5_results.len() == expected_heartbeats.len() {
- handler.stop().await;
- }
- }
+ if ss5_results.len() == expected_heartbeats.len() {
+ handler.stop().await;
+ }
+ }
- assert_eq!(ss5_results.len(), expected_heartbeats.len());
+ assert_eq!(ss5_results.len(), expected_heartbeats.len());
- for expected in expected_heartbeats {
- assert!(ss5_results.contains(&expected));
- }
- });
+ for expected in expected_heartbeats {
+ assert!(ss5_results.contains(&expected));
+ }
+ });
}
// Tests that duplicate leaves have an attached 'Stale' status.
#[test]
fn overseer_stale_detection() {
- let spawner = sp_core::testing::TaskExecutor::new();
+ let spawner = sp_core::testing::TaskExecutor::new();
- executor::block_on(async move {
- let a1_hash = [1; 32].into();
- let b1_hash = [2; 32].into();
+ executor::block_on(async move {
+ let a1_hash = [1; 32].into();
+ let b1_hash = [2; 32].into();
- let a2_hash = [3; 32].into();
- let b2_hash = [4; 32].into();
+ let a2_hash = [3; 32].into();
+ let b2_hash = [4; 32].into();
- let first_block = BlockInfo {
- hash: a1_hash,
- parent_hash: [0; 32].into(),
- number: 1,
- };
- let second_block = BlockInfo {
- hash: b1_hash,
- parent_hash: [0; 32].into(),
- number: 1,
- };
+ let first_block = BlockInfo {
+ hash: a1_hash,
+ parent_hash: [0; 32].into(),
+ number: 1,
+ };
+ let second_block = BlockInfo {
+ hash: b1_hash,
+ parent_hash: [0; 32].into(),
+ number: 1,
+ };
- let third_block = BlockInfo {
- hash: a2_hash,
- parent_hash: a1_hash,
- number: 2,
- };
+ let third_block = BlockInfo {
+ hash: a2_hash,
+ parent_hash: a1_hash,
+ number: 2,
+ };
- let fourth_block = BlockInfo {
- hash: b2_hash,
- parent_hash: b1_hash,
- number: 2,
- };
+ let fourth_block = BlockInfo {
+ hash: b2_hash,
+ parent_hash: b1_hash,
+ number: 2,
+ };
- let (tx_5, mut rx_5) = metered::channel(64);
- let (tx_6, mut rx_6) = metered::channel(64);
- let all_subsystems = AllSubsystems::<()>::dummy()
- .replace_candidate_validation(TestSubsystem5(tx_5))
- .replace_candidate_backing(TestSubsystem6(tx_6));
+ let (tx_5, mut rx_5) = metered::channel(64);
+ let (tx_6, mut rx_6) = metered::channel(64);
+ let all_subsystems = AllSubsystems::<()>::dummy()
+ .replace_candidate_validation(TestSubsystem5(tx_5))
+ .replace_candidate_backing(TestSubsystem6(tx_6));
- let (overseer, mut handler) = Overseer::new(
- vec![first_block.clone()],
- all_subsystems,
- None,
- MockSupportsParachains,
- spawner,
- ).unwrap();
+ let (overseer, mut handler) = Overseer::new(
+ vec![first_block.clone()],
+ all_subsystems,
+ None,
+ MockSupportsParachains,
+ spawner,
+ ).unwrap();
- let overseer_fut = overseer.run().fuse();
- pin_mut!(overseer_fut);
+ let overseer_fut = overseer.run().fuse();
+ pin_mut!(overseer_fut);
- let mut ss5_results = Vec::new();
- let mut ss6_results = Vec::new();
+ let mut ss5_results = Vec::new();
+ let mut ss6_results = Vec::new();
- handler.block_imported(second_block.clone()).await;
+ handler.block_imported(second_block.clone()).await;
- // import the second block of each chain to deactivate the heads.
- handler.block_imported(third_block).await;
- handler.block_imported(fourth_block).await;
+ // import the second block of each chain to deactivate the heads.
+ handler.block_imported(third_block).await;
+ handler.block_imported(fourth_block).await;
- // import the first blocks again (emulating a revert)
- handler.block_imported(first_block).await;
- handler.block_imported(second_block).await;
+ // import the first blocks again (emulating a revert)
+ handler.block_imported(first_block).await;
+ handler.block_imported(second_block).await;
- let expected_heartbeats = vec![
- OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf {
- hash: a1_hash,
- number: 1,
- status: LeafStatus::Fresh,
- span: Arc::new(jaeger::Span::Disabled),
- })),
- OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf {
- hash: b1_hash,
- number: 1,
- status: LeafStatus::Fresh,
- span: Arc::new(jaeger::Span::Disabled),
- })),
- OverseerSignal::ActiveLeaves(ActiveLeavesUpdate {
- activated: [ActivatedLeaf {
- hash: a2_hash,
- number: 2,
- status: LeafStatus::Fresh,
- span: Arc::new(jaeger::Span::Disabled),
- }].as_ref().into(),
- deactivated: [a1_hash].as_ref().into(),
- }),
- OverseerSignal::ActiveLeaves(ActiveLeavesUpdate {
- activated: [ActivatedLeaf {
- hash: b2_hash,
- number: 2,
- status: LeafStatus::Fresh,
- span: Arc::new(jaeger::Span::Disabled),
- }].as_ref().into(),
- deactivated: [b1_hash].as_ref().into(),
- }),
- OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf {
- hash: a1_hash,
- number: 1,
- status: LeafStatus::Stale,
- span: Arc::new(jaeger::Span::Disabled),
- })),
- OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf {
- hash: b1_hash,
- number: 1,
- status: LeafStatus::Stale,
- span: Arc::new(jaeger::Span::Disabled),
- })),
- ];
+ let expected_heartbeats = vec![
+ OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf {
+ hash: a1_hash,
+ number: 1,
+ status: LeafStatus::Fresh,
+ span: Arc::new(jaeger::Span::Disabled),
+ })),
+ OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf {
+ hash: b1_hash,
+ number: 1,
+ status: LeafStatus::Fresh,
+ span: Arc::new(jaeger::Span::Disabled),
+ })),
+ OverseerSignal::ActiveLeaves(ActiveLeavesUpdate {
+ activated: [ActivatedLeaf {
+ hash: a2_hash,
+ number: 2,
+ status: LeafStatus::Fresh,
+ span: Arc::new(jaeger::Span::Disabled),
+ }].as_ref().into(),
+ deactivated: [a1_hash].as_ref().into(),
+ }),
+ OverseerSignal::ActiveLeaves(ActiveLeavesUpdate {
+ activated: [ActivatedLeaf {
+ hash: b2_hash,
+ number: 2,
+ status: LeafStatus::Fresh,
+ span: Arc::new(jaeger::Span::Disabled),
+ }].as_ref().into(),
+ deactivated: [b1_hash].as_ref().into(),
+ }),
+ OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf {
+ hash: a1_hash,
+ number: 1,
+ status: LeafStatus::Stale,
+ span: Arc::new(jaeger::Span::Disabled),
+ })),
+ OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf {
+ hash: b1_hash,
+ number: 1,
+ status: LeafStatus::Stale,
+ span: Arc::new(jaeger::Span::Disabled),
+ })),
+ ];
- loop {
- select! {
- res = overseer_fut => {
- assert!(res.is_ok());
- break;
- },
- res = rx_5.next() => {
- if let Some(res) = res {
- ss5_results.push(res);
- }
- }
- res = rx_6.next() => {
- if let Some(res) = res {
- ss6_results.push(res);
- }
- }
- complete => break,
- }
+ loop {
+ select! {
+ res = overseer_fut => {
+ assert!(res.is_ok());
+ break;
+ },
+ res = rx_5.next() => {
+ if let Some(res) = res {
+ ss5_results.push(res);
+ }
+ }
+ res = rx_6.next() => {
+ if let Some(res) = res {
+ ss6_results.push(res);
+ }
+ }
+ complete => break,
+ }
- if ss5_results.len() == expected_heartbeats.len() &&
- ss6_results.len() == expected_heartbeats.len() {
- handler.stop().await;
- }
- }
+ if ss5_results.len() == expected_heartbeats.len() &&
+ ss6_results.len() == expected_heartbeats.len() {
+ handler.stop().await;
+ }
+ }
- assert_eq!(ss5_results, expected_heartbeats);
- assert_eq!(ss6_results, expected_heartbeats);
- });
+ assert_eq!(ss5_results, expected_heartbeats);
+ assert_eq!(ss6_results, expected_heartbeats);
+ });
}
#[derive(Clone)]
struct CounterSubsystem {
- stop_signals_received: Arc,
- signals_received: Arc,
- msgs_received: Arc,
+ stop_signals_received: Arc,
+ signals_received: Arc,
+ msgs_received: Arc,
}
impl CounterSubsystem {
- fn new(
- stop_signals_received: Arc,
- signals_received: Arc,
- msgs_received: Arc,
- ) -> Self {
- Self {
- stop_signals_received,
- signals_received,
- msgs_received,
- }
- }
+ fn new(
+ stop_signals_received: Arc,
+ signals_received: Arc,
+ msgs_received: Arc,
+ ) -> Self {
+ Self {
+ stop_signals_received,
+ signals_received,
+ msgs_received,
+ }
+ }
}
impl Subsystem for CounterSubsystem
- where
- C: SubsystemContext,
- M: Send,
+ where
+ C: SubsystemContext,
+ M: Send,
{
- fn start(self, mut ctx: C) -> SpawnedSubsystem {
- SpawnedSubsystem {
- name: "counter-subsystem",
- future: Box::pin(async move {
- loop {
- match ctx.try_recv().await {
- Ok(Some(FromOverseer::Signal(OverseerSignal::Conclude))) => {
- self.stop_signals_received.fetch_add(1, atomic::Ordering::SeqCst);
- break;
- },
- Ok(Some(FromOverseer::Signal(_))) => {
- self.signals_received.fetch_add(1, atomic::Ordering::SeqCst);
- continue;
- },
- Ok(Some(FromOverseer::Communication { .. })) => {
- self.msgs_received.fetch_add(1, atomic::Ordering::SeqCst);
- continue;
- },
- Err(_) => (),
- _ => (),
- }
- pending!();
- }
+ fn start(self, mut ctx: C) -> SpawnedSubsystem {
+ SpawnedSubsystem {
+ name: "counter-subsystem",
+ future: Box::pin(async move {
+ loop {
+ match ctx.try_recv().await {
+ Ok(Some(FromOverseer::Signal(OverseerSignal::Conclude))) => {
+ self.stop_signals_received.fetch_add(1, atomic::Ordering::SeqCst);
+ break;
+ },
+ Ok(Some(FromOverseer::Signal(_))) => {
+ self.signals_received.fetch_add(1, atomic::Ordering::SeqCst);
+ continue;
+ },
+ Ok(Some(FromOverseer::Communication { .. })) => {
+ self.msgs_received.fetch_add(1, atomic::Ordering::SeqCst);
+ continue;
+ },
+ Err(_) => (),
+ _ => (),
+ }
+ pending!();
+ }
- Ok(())
- }),
- }
- }
+ Ok(())
+ }),
+ }
+ }
}
fn test_candidate_validation_msg() -> CandidateValidationMessage {
- let (sender, _) = oneshot::channel();
- let pov = Arc::new(PoV { block_data: BlockData(Vec::new()) });
- CandidateValidationMessage::ValidateFromChainState(Default::default(), pov, sender)
+ let (sender, _) = oneshot::channel();
+ let pov = Arc::new(PoV { block_data: BlockData(Vec::new()) });
+ CandidateValidationMessage::ValidateFromChainState(Default::default(), pov, sender)
}
fn test_candidate_backing_msg() -> CandidateBackingMessage {
- let (sender, _) = oneshot::channel();
- CandidateBackingMessage::GetBackedCandidates(Default::default(), Vec::new(), sender)
+ let (sender, _) = oneshot::channel();
+ CandidateBackingMessage::GetBackedCandidates(Default::default(), Vec::new(), sender)
}
fn test_chain_api_msg() -> ChainApiMessage {
- let (sender, _) = oneshot::channel();
- ChainApiMessage::FinalizedBlockNumber(sender)
+ let (sender, _) = oneshot::channel();
+ ChainApiMessage::FinalizedBlockNumber(sender)
}
fn test_collator_generation_msg() -> CollationGenerationMessage {
- CollationGenerationMessage::Initialize(CollationGenerationConfig {
- key: CollatorPair::generate().0,
- collator: Box::new(|_, _| TestCollator.boxed()),
- para_id: Default::default(),
- })
+ CollationGenerationMessage::Initialize(CollationGenerationConfig {
+ key: CollatorPair::generate().0,
+ collator: Box::new(|_, _| TestCollator.boxed()),
+ para_id: Default::default(),
+ })
}
struct TestCollator;
impl Future for TestCollator {
- type Output = Option;
+ type Output = Option;
- fn poll(self: Pin<&mut Self>, _cx: &mut futures::task::Context) -> Poll {
- panic!("at the Disco")
- }
+ fn poll(self: Pin<&mut Self>, _cx: &mut futures::task::Context) -> Poll {
+ panic!("at the Disco")
+ }
}
impl Unpin for TestCollator {}
fn test_collator_protocol_msg() -> CollatorProtocolMessage {
- CollatorProtocolMessage::CollateOn(Default::default())
+ CollatorProtocolMessage::CollateOn(Default::default())
}
fn test_network_bridge_event() -> NetworkBridgeEvent {
- NetworkBridgeEvent::PeerDisconnected(PeerId::random())
+ NetworkBridgeEvent::PeerDisconnected(PeerId::random())
}
fn test_statement_distribution_msg() -> StatementDistributionMessage {
- StatementDistributionMessage::NetworkBridgeUpdateV1(test_network_bridge_event())
+ StatementDistributionMessage::NetworkBridgeUpdateV1(test_network_bridge_event())
}
fn test_availability_recovery_msg() -> AvailabilityRecoveryMessage {
- let (sender, _) = oneshot::channel();
- AvailabilityRecoveryMessage::RecoverAvailableData(
- Default::default(),
- Default::default(),
- None,
- sender,
- )
+ let (sender, _) = oneshot::channel();
+ AvailabilityRecoveryMessage::RecoverAvailableData(
+ Default::default(),
+ Default::default(),
+ None,
+ sender,
+ )
}
fn test_bitfield_distribution_msg() -> BitfieldDistributionMessage {
- BitfieldDistributionMessage::NetworkBridgeUpdateV1(test_network_bridge_event())
+ BitfieldDistributionMessage::NetworkBridgeUpdateV1(test_network_bridge_event())
}
fn test_provisioner_msg() -> ProvisionerMessage {
- let (sender, _) = oneshot::channel();
- ProvisionerMessage::RequestInherentData(Default::default(), sender)
+ let (sender, _) = oneshot::channel();
+ ProvisionerMessage::RequestInherentData(Default::default(), sender)
}
fn test_runtime_api_msg() -> RuntimeApiMessage {
- let (sender, _) = oneshot::channel();
- RuntimeApiMessage::Request(Default::default(), RuntimeApiRequest::Validators(sender))
+ let (sender, _) = oneshot::channel();
+ RuntimeApiMessage::Request(Default::default(), RuntimeApiRequest::Validators(sender))
}
fn test_availability_store_msg() -> AvailabilityStoreMessage {
- let (sender, _) = oneshot::channel();
- AvailabilityStoreMessage::QueryAvailableData(CandidateHash(Default::default()), sender)
+ let (sender, _) = oneshot::channel();
+ AvailabilityStoreMessage::QueryAvailableData(CandidateHash(Default::default()), sender)
}
fn test_network_bridge_msg() -> NetworkBridgeMessage {
- NetworkBridgeMessage::ReportPeer(PeerId::random(), UnifiedReputationChange::BenefitMinor(""))
+ NetworkBridgeMessage::ReportPeer(PeerId::random(), UnifiedReputationChange::BenefitMinor(""))
}
fn test_approval_distribution_msg() -> ApprovalDistributionMessage {
- ApprovalDistributionMessage::NewBlocks(Default::default())
+ ApprovalDistributionMessage::NewBlocks(Default::default())
}
fn test_approval_voting_msg() -> ApprovalVotingMessage {
- let (sender, _) = oneshot::channel();
- ApprovalVotingMessage::ApprovedAncestor(Default::default(), 0, sender)
+ let (sender, _) = oneshot::channel();
+ ApprovalVotingMessage::ApprovedAncestor(Default::default(), 0, sender)
}
// Checks that `stop`, `broadcast_signal` and `broadcast_message` are implemented correctly.
#[test]
fn overseer_all_subsystems_receive_signals_and_messages() {
- const NUM_SUBSYSTEMS: usize = 17;
- // -3 for BitfieldSigning, GossipSupport and AvailabilityDistribution
- const NUM_SUBSYSTEMS_MESSAGED: usize = NUM_SUBSYSTEMS - 3;
+ const NUM_SUBSYSTEMS: usize = 17;
+ // -3 for BitfieldSigning, GossipSupport and AvailabilityDistribution
+ const NUM_SUBSYSTEMS_MESSAGED: usize = NUM_SUBSYSTEMS - 3;
- let spawner = sp_core::testing::TaskExecutor::new();
- executor::block_on(async move {
- let stop_signals_received = Arc::new(atomic::AtomicUsize::new(0));
- let signals_received = Arc::new(atomic::AtomicUsize::new(0));
- let msgs_received = Arc::new(atomic::AtomicUsize::new(0));
+ let spawner = sp_core::testing::TaskExecutor::new();
+ executor::block_on(async move {
+ let stop_signals_received = Arc::new(atomic::AtomicUsize::new(0));
+ let signals_received = Arc::new(atomic::AtomicUsize::new(0));
+ let msgs_received = Arc::new(atomic::AtomicUsize::new(0));
- let subsystem = CounterSubsystem::new(
- stop_signals_received.clone(),
- signals_received.clone(),
- msgs_received.clone(),
- );
+ let subsystem = CounterSubsystem::new(
+ stop_signals_received.clone(),
+ signals_received.clone(),
+ msgs_received.clone(),
+ );
- let all_subsystems = AllSubsystems {
- candidate_validation: subsystem.clone(),
- candidate_backing: subsystem.clone(),
- collation_generation: subsystem.clone(),
- collator_protocol: subsystem.clone(),
- statement_distribution: subsystem.clone(),
- availability_distribution: subsystem.clone(),
- availability_recovery: subsystem.clone(),
- bitfield_signing: subsystem.clone(),
- bitfield_distribution: subsystem.clone(),
- provisioner: subsystem.clone(),
- runtime_api: subsystem.clone(),
- availability_store: subsystem.clone(),
- network_bridge: subsystem.clone(),
- chain_api: subsystem.clone(),
- approval_distribution: subsystem.clone(),
- approval_voting: subsystem.clone(),
- gossip_support: subsystem.clone(),
- };
- let (overseer, mut handler) = Overseer::new(
- vec![],
- all_subsystems,
- None,
- MockSupportsParachains,
- spawner,
- ).unwrap();
- let overseer_fut = overseer.run().fuse();
+ let all_subsystems = AllSubsystems {
+ candidate_validation: subsystem.clone(),
+ candidate_backing: subsystem.clone(),
+ collation_generation: subsystem.clone(),
+ collator_protocol: subsystem.clone(),
+ statement_distribution: subsystem.clone(),
+ availability_distribution: subsystem.clone(),
+ availability_recovery: subsystem.clone(),
+ bitfield_signing: subsystem.clone(),
+ bitfield_distribution: subsystem.clone(),
+ provisioner: subsystem.clone(),
+ runtime_api: subsystem.clone(),
+ availability_store: subsystem.clone(),
+ network_bridge: subsystem.clone(),
+ chain_api: subsystem.clone(),
+ approval_distribution: subsystem.clone(),
+ approval_voting: subsystem.clone(),
+ gossip_support: subsystem.clone(),
+ };
+ let (overseer, mut handler) = Overseer::new(
+ vec![],
+ all_subsystems,
+ None,
+ MockSupportsParachains,
+ spawner,
+ ).unwrap();
+ let overseer_fut = overseer.run().fuse();
- pin_mut!(overseer_fut);
+ pin_mut!(overseer_fut);
- // send a signal to each subsystem
- handler.block_imported(BlockInfo {
- hash: Default::default(),
- parent_hash: Default::default(),
- number: Default::default(),
- }).await;
+ // send a signal to each subsystem
+ handler.block_imported(BlockInfo {
+ hash: Default::default(),
+ parent_hash: Default::default(),
+ number: Default::default(),
+ }).await;
- // send a msg to each subsystem
- // except for BitfieldSigning and GossipSupport as the messages are not instantiable
- handler.send_msg(AllMessages::CandidateValidation(test_candidate_validation_msg())).await;
- handler.send_msg(AllMessages::CandidateBacking(test_candidate_backing_msg())).await;
- handler.send_msg(AllMessages::CollationGeneration(test_collator_generation_msg())).await;
- handler.send_msg(AllMessages::CollatorProtocol(test_collator_protocol_msg())).await;
- handler.send_msg(AllMessages::StatementDistribution(test_statement_distribution_msg())).await;
- handler.send_msg(AllMessages::AvailabilityRecovery(test_availability_recovery_msg())).await;
- // handler.send_msg(AllMessages::BitfieldSigning(test_bitfield_signing_msg())).await;
- // handler.send_msg(AllMessages::GossipSupport(test_bitfield_signing_msg())).await;
- handler.send_msg(AllMessages::BitfieldDistribution(test_bitfield_distribution_msg())).await;
- handler.send_msg(AllMessages::Provisioner(test_provisioner_msg())).await;
- handler.send_msg(AllMessages::RuntimeApi(test_runtime_api_msg())).await;
- handler.send_msg(AllMessages::AvailabilityStore(test_availability_store_msg())).await;
- handler.send_msg(AllMessages::NetworkBridge(test_network_bridge_msg())).await;
- handler.send_msg(AllMessages::ChainApi(test_chain_api_msg())).await;
- handler.send_msg(AllMessages::ApprovalDistribution(test_approval_distribution_msg())).await;
- handler.send_msg(AllMessages::ApprovalVoting(test_approval_voting_msg())).await;
+ // send a msg to each subsystem
+ // except for BitfieldSigning and GossipSupport as the messages are not instantiable
+ handler.send_msg(AllMessages::CandidateValidation(test_candidate_validation_msg())).await;
+ handler.send_msg(AllMessages::CandidateBacking(test_candidate_backing_msg())).await;
+ handler.send_msg(AllMessages::CollationGeneration(test_collator_generation_msg())).await;
+ handler.send_msg(AllMessages::CollatorProtocol(test_collator_protocol_msg())).await;
+ handler.send_msg(AllMessages::StatementDistribution(test_statement_distribution_msg())).await;
+ handler.send_msg(AllMessages::AvailabilityRecovery(test_availability_recovery_msg())).await;
+ // handler.send_msg(AllMessages::BitfieldSigning(test_bitfield_signing_msg())).await;
+ // handler.send_msg(AllMessages::GossipSupport(test_bitfield_signing_msg())).await;
+ handler.send_msg(AllMessages::BitfieldDistribution(test_bitfield_distribution_msg())).await;
+ handler.send_msg(AllMessages::Provisioner(test_provisioner_msg())).await;
+ handler.send_msg(AllMessages::RuntimeApi(test_runtime_api_msg())).await;
+ handler.send_msg(AllMessages::AvailabilityStore(test_availability_store_msg())).await;
+ handler.send_msg(AllMessages::NetworkBridge(test_network_bridge_msg())).await;
+ handler.send_msg(AllMessages::ChainApi(test_chain_api_msg())).await;
+ handler.send_msg(AllMessages::ApprovalDistribution(test_approval_distribution_msg())).await;
+ handler.send_msg(AllMessages::ApprovalVoting(test_approval_voting_msg())).await;
- // Wait until all subsystems have received. Otherwise the messages might race against
- // the conclude signal.
- loop {
- match (&mut overseer_fut).timeout(Duration::from_millis(100)).await {
- None => {
- let r = msgs_received.load(atomic::Ordering::SeqCst);
- if r < NUM_SUBSYSTEMS_MESSAGED {
- Delay::new(Duration::from_millis(100)).await;
- } else if r > NUM_SUBSYSTEMS_MESSAGED {
- panic!("too many messages received??");
- } else {
- break
- }
- }
- Some(_) => panic!("exited too early"),
- }
- }
+ // Wait until all subsystems have received. Otherwise the messages might race against
+ // the conclude signal.
+ loop {
+ match (&mut overseer_fut).timeout(Duration::from_millis(100)).await {
+ None => {
+ let r = msgs_received.load(atomic::Ordering::SeqCst);
+ if r < NUM_SUBSYSTEMS_MESSAGED {
+ Delay::new(Duration::from_millis(100)).await;
+ } else if r > NUM_SUBSYSTEMS_MESSAGED {
+ panic!("too many messages received??");
+ } else {
+ break
+ }
+ }
+ Some(_) => panic!("exited too early"),
+ }
+ }
- // send a stop signal to each subsystems
- handler.stop().await;
+ // send a stop signal to each subsystems
+ handler.stop().await;
- let res = overseer_fut.await;
- assert_eq!(stop_signals_received.load(atomic::Ordering::SeqCst), NUM_SUBSYSTEMS);
- assert_eq!(signals_received.load(atomic::Ordering::SeqCst), NUM_SUBSYSTEMS);
- assert_eq!(msgs_received.load(atomic::Ordering::SeqCst), NUM_SUBSYSTEMS_MESSAGED);
+ let res = overseer_fut.await;
+ assert_eq!(stop_signals_received.load(atomic::Ordering::SeqCst), NUM_SUBSYSTEMS);
+ assert_eq!(signals_received.load(atomic::Ordering::SeqCst), NUM_SUBSYSTEMS);
+ assert_eq!(msgs_received.load(atomic::Ordering::SeqCst), NUM_SUBSYSTEMS_MESSAGED);
- assert!(res.is_ok());
- });
+ assert!(res.is_ok());
+ });
}
#[test]
fn context_holds_onto_message_until_enough_signals_received() {
- let (candidate_validation_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
- let (candidate_backing_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
- let (statement_distribution_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
- let (availability_distribution_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
- let (availability_recovery_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
- let (bitfield_signing_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
- let (bitfield_distribution_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
- let (provisioner_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
- let (runtime_api_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
- let (availability_store_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
- let (network_bridge_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
- let (chain_api_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
- let (collator_protocol_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
- let (collation_generation_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
- let (approval_distribution_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
- let (approval_voting_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
- let (gossip_support_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
+ let (candidate_validation_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
+ let (candidate_backing_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
+ let (statement_distribution_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
+ let (availability_distribution_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
+ let (availability_recovery_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
+ let (bitfield_signing_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
+ let (bitfield_distribution_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
+ let (provisioner_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
+ let (runtime_api_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
+ let (availability_store_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
+ let (network_bridge_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
+ let (chain_api_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
+ let (collator_protocol_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
+ let (collation_generation_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
+ let (approval_distribution_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
+ let (approval_voting_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
+ let (gossip_support_bounded_tx, _) = metered::channel(CHANNEL_CAPACITY);
- let (candidate_validation_unbounded_tx, _) = metered::unbounded();
- let (candidate_backing_unbounded_tx, _) = metered::unbounded();
- let (statement_distribution_unbounded_tx, _) = metered::unbounded();
- let (availability_distribution_unbounded_tx, _) = metered::unbounded();
- let (availability_recovery_unbounded_tx, _) = metered::unbounded();
- let (bitfield_signing_unbounded_tx, _) = metered::unbounded();
- let (bitfield_distribution_unbounded_tx, _) = metered::unbounded();
- let (provisioner_unbounded_tx, _) = metered::unbounded();
- let (runtime_api_unbounded_tx, _) = metered::unbounded();
- let (availability_store_unbounded_tx, _) = metered::unbounded();
- let (network_bridge_unbounded_tx, _) = metered::unbounded();
- let (chain_api_unbounded_tx, _) = metered::unbounded();
- let (collator_protocol_unbounded_tx, _) = metered::unbounded();
- let (collation_generation_unbounded_tx, _) = metered::unbounded();
- let (approval_distribution_unbounded_tx, _) = metered::unbounded();
- let (approval_voting_unbounded_tx, _) = metered::unbounded();
- let (gossip_support_unbounded_tx, _) = metered::unbounded();
+ let (candidate_validation_unbounded_tx, _) = metered::unbounded();
+ let (candidate_backing_unbounded_tx, _) = metered::unbounded();
+ let (statement_distribution_unbounded_tx, _) = metered::unbounded();
+ let (availability_distribution_unbounded_tx, _) = metered::unbounded();
+ let (availability_recovery_unbounded_tx, _) = metered::unbounded();
+ let (bitfield_signing_unbounded_tx, _) = metered::unbounded();
+ let (bitfield_distribution_unbounded_tx, _) = metered::unbounded();
+ let (provisioner_unbounded_tx, _) = metered::unbounded();
+ let (runtime_api_unbounded_tx, _) = metered::unbounded();
+ let (availability_store_unbounded_tx, _) = metered::unbounded();
+ let (network_bridge_unbounded_tx, _) = metered::unbounded();
+ let (chain_api_unbounded_tx, _) = metered::unbounded();
+ let (collator_protocol_unbounded_tx, _) = metered::unbounded();
+ let (collation_generation_unbounded_tx, _) = metered::unbounded();
+ let (approval_distribution_unbounded_tx, _) = metered::unbounded();
+ let (approval_voting_unbounded_tx, _) = metered::unbounded();
+ let (gossip_support_unbounded_tx, _) = metered::unbounded();
- let channels_out = ChannelsOut {
- candidate_validation: candidate_validation_bounded_tx.clone(),
- candidate_backing: candidate_backing_bounded_tx.clone(),
- statement_distribution: statement_distribution_bounded_tx.clone(),
- availability_distribution: availability_distribution_bounded_tx.clone(),
- availability_recovery: availability_recovery_bounded_tx.clone(),
- bitfield_signing: bitfield_signing_bounded_tx.clone(),
- bitfield_distribution: bitfield_distribution_bounded_tx.clone(),
- provisioner: provisioner_bounded_tx.clone(),
- runtime_api: runtime_api_bounded_tx.clone(),
- availability_store: availability_store_bounded_tx.clone(),
- network_bridge: network_bridge_bounded_tx.clone(),
- chain_api: chain_api_bounded_tx.clone(),
- collator_protocol: collator_protocol_bounded_tx.clone(),
- collation_generation: collation_generation_bounded_tx.clone(),
- approval_distribution: approval_distribution_bounded_tx.clone(),
- approval_voting: approval_voting_bounded_tx.clone(),
- gossip_support: gossip_support_bounded_tx.clone(),
+ let channels_out = ChannelsOut {
+ candidate_validation: candidate_validation_bounded_tx.clone(),
+ candidate_backing: candidate_backing_bounded_tx.clone(),
+ statement_distribution: statement_distribution_bounded_tx.clone(),
+ availability_distribution: availability_distribution_bounded_tx.clone(),
+ availability_recovery: availability_recovery_bounded_tx.clone(),
+ bitfield_signing: bitfield_signing_bounded_tx.clone(),
+ bitfield_distribution: bitfield_distribution_bounded_tx.clone(),
+ provisioner: provisioner_bounded_tx.clone(),
+ runtime_api: runtime_api_bounded_tx.clone(),
+ availability_store: availability_store_bounded_tx.clone(),
+ network_bridge: network_bridge_bounded_tx.clone(),
+ chain_api: chain_api_bounded_tx.clone(),
+ collator_protocol: collator_protocol_bounded_tx.clone(),
+ collation_generation: collation_generation_bounded_tx.clone(),
+ approval_distribution: approval_distribution_bounded_tx.clone(),
+ approval_voting: approval_voting_bounded_tx.clone(),
+ gossip_support: gossip_support_bounded_tx.clone(),
- candidate_validation_unbounded: candidate_validation_unbounded_tx.clone(),
- candidate_backing_unbounded: candidate_backing_unbounded_tx.clone(),
- statement_distribution_unbounded: statement_distribution_unbounded_tx.clone(),
- availability_distribution_unbounded: availability_distribution_unbounded_tx.clone(),
- availability_recovery_unbounded: availability_recovery_unbounded_tx.clone(),
- bitfield_signing_unbounded: bitfield_signing_unbounded_tx.clone(),
- bitfield_distribution_unbounded: bitfield_distribution_unbounded_tx.clone(),
- provisioner_unbounded: provisioner_unbounded_tx.clone(),
- runtime_api_unbounded: runtime_api_unbounded_tx.clone(),
- availability_store_unbounded: availability_store_unbounded_tx.clone(),
- network_bridge_unbounded: network_bridge_unbounded_tx.clone(),
- chain_api_unbounded: chain_api_unbounded_tx.clone(),
- collator_protocol_unbounded: collator_protocol_unbounded_tx.clone(),
- collation_generation_unbounded: collation_generation_unbounded_tx.clone(),
- approval_distribution_unbounded: approval_distribution_unbounded_tx.clone(),
- approval_voting_unbounded: approval_voting_unbounded_tx.clone(),
- gossip_support_unbounded: gossip_support_unbounded_tx.clone(),
- };
+ candidate_validation_unbounded: candidate_validation_unbounded_tx.clone(),
+ candidate_backing_unbounded: candidate_backing_unbounded_tx.clone(),
+ statement_distribution_unbounded: statement_distribution_unbounded_tx.clone(),
+ availability_distribution_unbounded: availability_distribution_unbounded_tx.clone(),
+ availability_recovery_unbounded: availability_recovery_unbounded_tx.clone(),
+ bitfield_signing_unbounded: bitfield_signing_unbounded_tx.clone(),
+ bitfield_distribution_unbounded: bitfield_distribution_unbounded_tx.clone(),
+ provisioner_unbounded: provisioner_unbounded_tx.clone(),
+ runtime_api_unbounded: runtime_api_unbounded_tx.clone(),
+ availability_store_unbounded: availability_store_unbounded_tx.clone(),
+ network_bridge_unbounded: network_bridge_unbounded_tx.clone(),
+ chain_api_unbounded: chain_api_unbounded_tx.clone(),
+ collator_protocol_unbounded: collator_protocol_unbounded_tx.clone(),
+ collation_generation_unbounded: collation_generation_unbounded_tx.clone(),
+ approval_distribution_unbounded: approval_distribution_unbounded_tx.clone(),
+ approval_voting_unbounded: approval_voting_unbounded_tx.clone(),
+ gossip_support_unbounded: gossip_support_unbounded_tx.clone(),
+ };
- let (mut signal_tx, signal_rx) = metered::channel(CHANNEL_CAPACITY);
- let (mut bounded_tx, bounded_rx) = metered::channel(CHANNEL_CAPACITY);
- let (unbounded_tx, unbounded_rx) = metered::unbounded();
- let (to_overseer_tx, _to_overseer_rx) = metered::unbounded();
+ let (mut signal_tx, signal_rx) = metered::channel(CHANNEL_CAPACITY);
+ let (mut bounded_tx, bounded_rx) = metered::channel(CHANNEL_CAPACITY);
+ let (unbounded_tx, unbounded_rx) = metered::unbounded();
+ let (to_overseer_tx, _to_overseer_rx) = metered::unbounded();
- let mut ctx = OverseerSubsystemContext::<()>::new_unmetered(
- signal_rx,
- stream::select(bounded_rx, unbounded_rx),
- channels_out,
- to_overseer_tx,
- );
+ let mut ctx = OverseerSubsystemContext::<()>::new_unmetered(
+ signal_rx,
+ stream::select(bounded_rx, unbounded_rx),
+ channels_out,
+ to_overseer_tx,
+ );
- assert_eq!(ctx.signals_received.load(), 0);
+ assert_eq!(ctx.signals_received.load(), 0);
- let test_fut = async move {
- signal_tx.send(OverseerSignal::Conclude).await.unwrap();
- assert_matches!(ctx.recv().await.unwrap(), FromOverseer::Signal(OverseerSignal::Conclude));
+ let test_fut = async move {
+ signal_tx.send(OverseerSignal::Conclude).await.unwrap();
+ assert_matches!(ctx.recv().await.unwrap(), FromOverseer::Signal(OverseerSignal::Conclude));
- assert_eq!(ctx.signals_received.load(), 1);
- bounded_tx.send(MessagePacket {
- signals_received: 2,
- message: (),
- }).await.unwrap();
- unbounded_tx.unbounded_send(MessagePacket {
- signals_received: 2,
- message: (),
- }).unwrap();
+ assert_eq!(ctx.signals_received.load(), 1);
+ bounded_tx.send(MessagePacket {
+ signals_received: 2,
+ message: (),
+ }).await.unwrap();
+ unbounded_tx.unbounded_send(MessagePacket {
+ signals_received: 2,
+ message: (),
+ }).unwrap();
- match poll!(ctx.recv()) {
- Poll::Pending => {}
- Poll::Ready(_) => panic!("ready too early"),
- };
+ match poll!(ctx.recv()) {
+ Poll::Pending => {}
+ Poll::Ready(_) => panic!("ready too early"),
+ };
- assert!(ctx.pending_incoming.is_some());
+ assert!(ctx.pending_incoming.is_some());
- signal_tx.send(OverseerSignal::Conclude).await.unwrap();
- assert_matches!(ctx.recv().await.unwrap(), FromOverseer::Signal(OverseerSignal::Conclude));
- assert_matches!(ctx.recv().await.unwrap(), FromOverseer::Communication { msg: () });
- assert_matches!(ctx.recv().await.unwrap(), FromOverseer::Communication { msg: () });
- assert!(ctx.pending_incoming.is_none());
- };
+ signal_tx.send(OverseerSignal::Conclude).await.unwrap();
+ assert_matches!(ctx.recv().await.unwrap(), FromOverseer::Signal(OverseerSignal::Conclude));
+ assert_matches!(ctx.recv().await.unwrap(), FromOverseer::Communication { msg: () });
+ assert_matches!(ctx.recv().await.unwrap(), FromOverseer::Communication { msg: () });
+ assert!(ctx.pending_incoming.is_none());
+ };
- futures::executor::block_on(test_fut);
+ futures::executor::block_on(test_fut);
}
diff --git a/polkadot/node/subsystem-util/src/lib.rs b/polkadot/node/subsystem-util/src/lib.rs
index ced1aaeda3..352634767d 100644
--- a/polkadot/node/subsystem-util/src/lib.rs
+++ b/polkadot/node/subsystem-util/src/lib.rs
@@ -54,8 +54,6 @@ use thiserror::Error;
pub use metered_channel as metered;
pub use polkadot_node_network_protocol::MIN_GOSSIP_PEERS;
-mod error_handling;
-
/// Error classification.
pub use error_handling::{Fault, unwrap_non_fatal};
@@ -72,6 +70,11 @@ pub mod reexports {
/// Convenient and efficient runtime info access.
pub mod runtime;
+mod error_handling;
+
+#[cfg(test)]
+mod tests;
+
/// Duration a job will wait after sending a stop signal before hard-aborting.
pub const JOB_GRACEFUL_STOP_DURATION: Duration = Duration::from_secs(1);
/// Capacity of channels to and from individual jobs
@@ -859,6 +862,3 @@ impl futures::Stream for Metronome
Poll::Pending
}
}
-
-#[cfg(test)]
-mod tests;
diff --git a/polkadot/node/subsystem-util/src/tests.rs b/polkadot/node/subsystem-util/src/tests.rs
index 40b87fff7c..10eb743671 100644
--- a/polkadot/node/subsystem-util/src/tests.rs
+++ b/polkadot/node/subsystem-util/src/tests.rs
@@ -19,8 +19,8 @@ use executor::block_on;
use thiserror::Error;
use polkadot_node_jaeger as jaeger;
use polkadot_node_subsystem::{
- messages::{AllMessages, CollatorProtocolMessage}, ActiveLeavesUpdate, FromOverseer, OverseerSignal,
- SpawnedSubsystem, ActivatedLeaf, LeafStatus,
+ messages::{AllMessages, CollatorProtocolMessage}, ActiveLeavesUpdate, FromOverseer, OverseerSignal,
+ SpawnedSubsystem, ActivatedLeaf, LeafStatus,
};
use assert_matches::assert_matches;
use futures::{channel::mpsc, executor, StreamExt, future, Future, FutureExt, SinkExt};
@@ -37,7 +37,7 @@ use std::{pin::Pin, sync::{Arc, atomic::{AtomicUsize, Ordering}}, time::Duration
// job structs are constructed within JobTrait::run
// most will want to retain the sender and receiver, as well as whatever other data they like
struct FakeCollatorProtocolJob {
- receiver: mpsc::Receiver,
+ receiver: mpsc::Receiver,
}
// Error will mostly be a wrapper to make the try operator more convenient;
@@ -45,215 +45,215 @@ struct FakeCollatorProtocolJob {
// It must implement Debug for logging.
#[derive(Debug, Error)]
enum Error {
- #[error(transparent)]
- Sending(#[from]mpsc::SendError),
+ #[error(transparent)]
+ Sending(#[from]mpsc::SendError),
}
impl JobTrait for FakeCollatorProtocolJob {
- type ToJob = CollatorProtocolMessage;
- type Error = Error;
- type RunArgs = bool;
- type Metrics = ();
+ type ToJob = CollatorProtocolMessage;
+ type Error = Error;
+ type RunArgs = bool;
+ type Metrics = ();
- const NAME: &'static str = "FakeCollatorProtocolJob";
+ const NAME: &'static str = "FakeCollatorProtocolJob";
- /// Run a job for the parent block indicated
- //
- // this function is in charge of creating and executing the job's main loop
- fn run(
- _: Hash,
- _: Arc,
- run_args: Self::RunArgs,
- _metrics: Self::Metrics,
- receiver: mpsc::Receiver,
- mut sender: JobSender,
- ) -> Pin> + Send>> {
- async move {
- let job = FakeCollatorProtocolJob { receiver };
+ /// Run a job for the parent block indicated
+ //
+ // this function is in charge of creating and executing the job's main loop
+ fn run(
+ _: Hash,
+ _: Arc,
+ run_args: Self::RunArgs,
+ _metrics: Self::Metrics,
+ receiver: mpsc::Receiver,
+ mut sender: JobSender,
+ ) -> Pin> + Send>> {
+ async move {
+ let job = FakeCollatorProtocolJob { receiver };
- if run_args {
- sender.send_message(CollatorProtocolMessage::Invalid(
- Default::default(),
- Default::default(),
- ).into()).await;
- }
+ if run_args {
+ sender.send_message(CollatorProtocolMessage::Invalid(
+ Default::default(),
+ Default::default(),
+ ).into()).await;
+ }
- // it isn't necessary to break run_loop into its own function,
- // but it's convenient to separate the concerns in this way
- job.run_loop().await
- }
- .boxed()
- }
+ // it isn't necessary to break run_loop into its own function,
+ // but it's convenient to separate the concerns in this way
+ job.run_loop().await
+ }
+ .boxed()
+ }
}
impl FakeCollatorProtocolJob {
- async fn run_loop(mut self) -> Result<(), Error> {
- loop {
- match self.receiver.next().await {
- Some(_csm) => {
- unimplemented!("we'd report the collator to the peer set manager here, but that's not implemented yet");
- }
- None => break,
- }
- }
+ async fn run_loop(mut self) -> Result<(), Error> {
+ loop {
+ match self.receiver.next().await {
+ Some(_csm) => {
+ unimplemented!("we'd report the collator to the peer set manager here, but that's not implemented yet");
+ }
+ None => break,
+ }
+ }
- Ok(())
- }
+ Ok(())
+ }
}
// with the job defined, it's straightforward to get a subsystem implementation.
type FakeCollatorProtocolSubsystem =
- JobSubsystem;
+ JobSubsystem;
// this type lets us pretend to be the overseer
type OverseerHandle = test_helpers::TestSubsystemContextHandle;
fn test_harness>(
- run_args: bool,
- test: impl FnOnce(OverseerHandle) -> T,
+ run_args: bool,
+ test: impl FnOnce(OverseerHandle) -> T,
) {
- let _ = env_logger::builder()
- .is_test(true)
- .filter(
- None,
- log::LevelFilter::Trace,
- )
- .try_init();
+ let _ = env_logger::builder()
+ .is_test(true)
+ .filter(
+ None,
+ log::LevelFilter::Trace,
+ )
+ .try_init();
- let pool = sp_core::testing::TaskExecutor::new();
- let (context, overseer_handle) = make_subsystem_context(pool.clone());
+ let pool = sp_core::testing::TaskExecutor::new();
+ let (context, overseer_handle) = make_subsystem_context(pool.clone());
- let subsystem = FakeCollatorProtocolSubsystem::new(
- pool,
- run_args,
- (),
- ).run(context);
- let test_future = test(overseer_handle);
+ let subsystem = FakeCollatorProtocolSubsystem::new(
+ pool,
+ run_args,
+ (),
+ ).run(context);
+ let test_future = test(overseer_handle);
- futures::pin_mut!(subsystem, test_future);
+ futures::pin_mut!(subsystem, test_future);
- executor::block_on(async move {
- future::join(subsystem, test_future)
- .timeout(Duration::from_secs(2))
- .await
- .expect("test timed out instead of completing")
- });
+ executor::block_on(async move {
+ future::join(subsystem, test_future)
+ .timeout(Duration::from_secs(2))
+ .await
+ .expect("test timed out instead of completing")
+ });
}
#[test]
fn starting_and_stopping_job_works() {
- let relay_parent: Hash = [0; 32].into();
+ let relay_parent: Hash = [0; 32].into();
- test_harness(true, |mut overseer_handle| async move {
- overseer_handle
- .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves(
- ActiveLeavesUpdate::start_work(ActivatedLeaf {
- hash: relay_parent,
- number: 1,
- status: LeafStatus::Fresh,
- span: Arc::new(jaeger::Span::Disabled),
- }),
- )))
- .await;
- assert_matches!(
- overseer_handle.recv().await,
- AllMessages::CollatorProtocol(_)
- );
- overseer_handle
- .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves(
- ActiveLeavesUpdate::stop_work(relay_parent),
- )))
- .await;
+ test_harness(true, |mut overseer_handle| async move {
+ overseer_handle
+ .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves(
+ ActiveLeavesUpdate::start_work(ActivatedLeaf {
+ hash: relay_parent,
+ number: 1,
+ status: LeafStatus::Fresh,
+ span: Arc::new(jaeger::Span::Disabled),
+ }),
+ )))
+ .await;
+ assert_matches!(
+ overseer_handle.recv().await,
+ AllMessages::CollatorProtocol(_)
+ );
+ overseer_handle
+ .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves(
+ ActiveLeavesUpdate::stop_work(relay_parent),
+ )))
+ .await;
- overseer_handle
- .send(FromOverseer::Signal(OverseerSignal::Conclude))
- .await;
- });
+ overseer_handle
+ .send(FromOverseer::Signal(OverseerSignal::Conclude))
+ .await;
+ });
}
#[test]
fn sending_to_a_non_running_job_do_not_stop_the_subsystem() {
- let relay_parent = Hash::repeat_byte(0x01);
+ let relay_parent = Hash::repeat_byte(0x01);
- test_harness(true, |mut overseer_handle| async move {
- overseer_handle
- .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves(
- ActiveLeavesUpdate::start_work(ActivatedLeaf {
- hash: relay_parent,
- number: 1,
- status: LeafStatus::Fresh,
- span: Arc::new(jaeger::Span::Disabled),
- }),
- )))
- .await;
+ test_harness(true, |mut overseer_handle| async move {
+ overseer_handle
+ .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves(
+ ActiveLeavesUpdate::start_work(ActivatedLeaf {
+ hash: relay_parent,
+ number: 1,
+ status: LeafStatus::Fresh,
+ span: Arc::new(jaeger::Span::Disabled),
+ }),
+ )))
+ .await;
- // send to a non running job
- overseer_handle
- .send(FromOverseer::Communication {
- msg: Default::default(),
- })
- .await;
+ // send to a non running job
+ overseer_handle
+ .send(FromOverseer::Communication {
+ msg: Default::default(),
+ })
+ .await;
- // the subsystem is still alive
- assert_matches!(
- overseer_handle.recv().await,
- AllMessages::CollatorProtocol(_)
- );
+ // the subsystem is still alive
+ assert_matches!(
+ overseer_handle.recv().await,
+ AllMessages::CollatorProtocol(_)
+ );
- overseer_handle
- .send(FromOverseer::Signal(OverseerSignal::Conclude))
- .await;
- });
+ overseer_handle
+ .send(FromOverseer::Signal(OverseerSignal::Conclude))
+ .await;
+ });
}
#[test]
fn test_subsystem_impl_and_name_derivation() {
- let pool = sp_core::testing::TaskExecutor::new();
- let (context, _) = make_subsystem_context::(pool.clone());
+ let pool = sp_core::testing::TaskExecutor::new();
+ let (context, _) = make_subsystem_context::(pool.clone());
- let SpawnedSubsystem { name, .. } =
- FakeCollatorProtocolSubsystem::new(pool, false, ()).start(context);
- assert_eq!(name, "FakeCollatorProtocol");
+ let SpawnedSubsystem { name, .. } =
+ FakeCollatorProtocolSubsystem::new(pool, false, ()).start(context);
+ assert_eq!(name, "FakeCollatorProtocol");
}
#[test]
fn tick_tack_metronome() {
- let n = Arc::new(AtomicUsize::default());
+ let n = Arc::new(AtomicUsize::default());
- let (tick, mut block) = mpsc::unbounded();
+ let (tick, mut block) = mpsc::unbounded();
- let metronome = {
- let n = n.clone();
- let stream = Metronome::new(Duration::from_millis(137_u64));
- stream.for_each(move |_res| {
- let _ = n.fetch_add(1, Ordering::Relaxed);
- let mut tick = tick.clone();
- async move {
- tick.send(()).await.expect("Test helper channel works. qed");
- }
- }).fuse()
- };
+ let metronome = {
+ let n = n.clone();
+ let stream = Metronome::new(Duration::from_millis(137_u64));
+ stream.for_each(move |_res| {
+ let _ = n.fetch_add(1, Ordering::Relaxed);
+ let mut tick = tick.clone();
+ async move {
+ tick.send(()).await.expect("Test helper channel works. qed");
+ }
+ }).fuse()
+ };
- let f2 = async move {
- block.next().await;
- assert_eq!(n.load(Ordering::Relaxed), 1_usize);
- block.next().await;
- assert_eq!(n.load(Ordering::Relaxed), 2_usize);
- block.next().await;
- assert_eq!(n.load(Ordering::Relaxed), 3_usize);
- block.next().await;
- assert_eq!(n.load(Ordering::Relaxed), 4_usize);
- }.fuse();
+ let f2 = async move {
+ block.next().await;
+ assert_eq!(n.load(Ordering::Relaxed), 1_usize);
+ block.next().await;
+ assert_eq!(n.load(Ordering::Relaxed), 2_usize);
+ block.next().await;
+ assert_eq!(n.load(Ordering::Relaxed), 3_usize);
+ block.next().await;
+ assert_eq!(n.load(Ordering::Relaxed), 4_usize);
+ }.fuse();
- futures::pin_mut!(f2);
- futures::pin_mut!(metronome);
+ futures::pin_mut!(f2);
+ futures::pin_mut!(metronome);
- block_on(async move {
- // futures::join!(metronome, f2)
- futures::select!(
- _ = metronome => unreachable!("Metronome never stops. qed"),
- _ = f2 => (),
- )
- });
+ block_on(async move {
+ // futures::join!(metronome, f2)
+ futures::select!(
+ _ = metronome => unreachable!("Metronome never stops. qed"),
+ _ = f2 => (),
+ )
+ });
}