diff --git a/polkadot/node/network/gossip-support/src/lib.rs b/polkadot/node/network/gossip-support/src/lib.rs index df90914b6f..823835aa76 100644 --- a/polkadot/node/network/gossip-support/src/lib.rs +++ b/polkadot/node/network/gossip-support/src/lib.rs @@ -249,11 +249,15 @@ where let mut connections = authorities_past_present_future(sender, leaf).await?; // Remove all of our locally controlled validator indices so we don't connect to ourself. - // If we control none of them, don't issue connection requests - we're outside - // of the 'clique' of recent validators. - if remove_all_controlled(&self.keystore, &mut connections).await != 0 { - self.issue_connection_request(sender, connections).await; - } + let connections = + if remove_all_controlled(&self.keystore, &mut connections).await != 0 { + connections + } else { + // If we control none of them, issue an empty connection request + // to clean up all connections. + Vec::new() + }; + self.issue_connection_request(sender, connections).await; } if is_new_session { @@ -353,7 +357,7 @@ where // issue another request for the same session // if at least a third of the authorities were not resolved. - if 3 * failures >= num { + if num != 0 && 3 * failures >= num { let timestamp = Instant::now(); match self.failure_start { None => self.failure_start = Some(timestamp), diff --git a/polkadot/node/network/gossip-support/src/tests.rs b/polkadot/node/network/gossip-support/src/tests.rs index 831f0aa943..cde47e2ba9 100644 --- a/polkadot/node/network/gossip-support/src/tests.rs +++ b/polkadot/node/network/gossip-support/src/tests.rs @@ -475,6 +475,64 @@ fn issues_connection_request_to_past_present_future() { }); } +#[test] +fn disconnect_when_not_in_past_present_future() { + sp_tracing::try_init_simple(); + let hash = Hash::repeat_byte(0xAA); + test_harness(make_subsystem(), |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + overseer_signal_active_leaves(overseer, hash).await; + assert_matches!( + overseer_recv(overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::SessionIndexForChild(tx), + )) => { + assert_eq!(relay_parent, hash); + tx.send(Ok(1)).unwrap(); + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::SessionInfo(s, tx), + )) => { + assert_eq!(relay_parent, hash); + assert_eq!(s, 1); + let mut heute_leider_nicht = make_session_info(); + heute_leider_nicht.discovery_keys = AUTHORITIES_WITHOUT_US.clone(); + tx.send(Ok(Some(heute_leider_nicht))).unwrap(); + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + relay_parent, + RuntimeApiRequest::Authorities(tx), + )) => { + assert_eq!(relay_parent, hash); + tx.send(Ok(AUTHORITIES_WITHOUT_US.clone())).unwrap(); + } + ); + + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ConnectToResolvedValidators { + validator_addrs, + peer_set, + }) => { + assert!(validator_addrs.is_empty()); + assert_eq!(peer_set, PeerSet::Validation); + } + ); + + virtual_overseer + }); +} + #[test] fn test_log_output() { sp_tracing::try_init_simple();