refactor+feat: allow subsystems to send only declared messages, generate graphviz (#5314)

Closes #3774
Closes #3826
This commit is contained in:
Bernhard Schuster
2022-05-12 17:39:05 +02:00
committed by GitHub
parent 26340b9054
commit 511891dcce
102 changed files with 3853 additions and 2514 deletions
+43 -59
View File
@@ -48,8 +48,7 @@ use polkadot_node_subsystem::{
GossipSupportMessage, NetworkBridgeEvent, NetworkBridgeMessage, RuntimeApiMessage,
RuntimeApiRequest,
},
overseer, ActiveLeavesUpdate, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemContext,
SubsystemError,
overseer, ActiveLeavesUpdate, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemError,
};
use polkadot_node_subsystem_util as util;
use polkadot_primitives::v2::{
@@ -115,6 +114,7 @@ pub struct GossipSupport<AD> {
metrics: Metrics,
}
#[overseer::contextbounds(GossipSupport, prefix = self::overseer)]
impl<AD> GossipSupport<AD>
where
AD: AuthorityDiscovery,
@@ -138,11 +138,7 @@ where
}
}
async fn run<Context>(mut self, mut ctx: Context) -> Self
where
Context: SubsystemContext<Message = GossipSupportMessage>,
Context: overseer::SubsystemContext<Message = GossipSupportMessage>,
{
async fn run<Context>(mut self, mut ctx: Context) -> Self {
fn get_connectivity_check_delay() -> Delay {
Delay::new(LOW_CONNECTIVITY_WARN_DELAY)
}
@@ -178,7 +174,7 @@ where
gum::trace!(target: LOG_TARGET, "active leaves signal");
let leaves = activated.into_iter().map(|a| a.hash);
if let Err(e) = self.handle_active_leaves(&mut ctx, leaves).await {
if let Err(e) = self.handle_active_leaves(ctx.sender(), leaves).await {
gum::debug!(target: LOG_TARGET, error = ?e);
}
},
@@ -191,18 +187,13 @@ where
/// 1. Determine if the current session index has changed.
/// 2. If it has, determine relevant validators
/// and issue a connection request.
async fn handle_active_leaves<Context>(
async fn handle_active_leaves(
&mut self,
ctx: &mut Context,
sender: &mut impl overseer::GossipSupportSenderTrait,
leaves: impl Iterator<Item = Hash>,
) -> Result<(), util::Error>
where
Context: SubsystemContext<Message = GossipSupportMessage>,
Context: overseer::SubsystemContext<Message = GossipSupportMessage>,
{
) -> Result<(), util::Error> {
for leaf in leaves {
let current_index =
util::request_session_index_for_child(leaf, ctx.sender()).await.await??;
let current_index = util::request_session_index_for_child(leaf, sender).await.await??;
let since_failure = self.last_failure.map(|i| i.elapsed()).unwrap_or_default();
let force_request = since_failure >= BACKOFF_DURATION;
let leaf_session = Some((current_index, leaf));
@@ -216,7 +207,7 @@ where
if let Some((session_index, relay_parent)) = maybe_issue_connection {
let session_info =
util::request_session_info(leaf, session_index, ctx.sender()).await.await??;
util::request_session_info(leaf, session_index, sender).await.await??;
let session_info = match session_info {
Some(s) => s,
@@ -255,13 +246,13 @@ where
// by virtue of a new session being entered. Therefore we maintain
// connections to a much broader set of validators.
{
let mut connections = authorities_past_present_future(ctx, leaf).await?;
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(ctx, connections).await;
self.issue_connection_request(sender, connections).await;
}
}
@@ -273,7 +264,7 @@ where
self.update_authority_status_metrics(&session_info).await;
update_gossip_topology(
ctx,
sender,
our_index,
session_info.discovery_keys,
relay_parent,
@@ -317,13 +308,12 @@ where
}
}
async fn issue_connection_request<Context>(
async fn issue_connection_request<Sender>(
&mut self,
ctx: &mut Context,
sender: &mut Sender,
authorities: Vec<AuthorityDiscoveryId>,
) where
Context: SubsystemContext<Message = GossipSupportMessage>,
Context: overseer::SubsystemContext<Message = GossipSupportMessage>,
Sender: overseer::GossipSupportSenderTrait,
{
let num = authorities.len();
let mut validator_addrs = Vec::with_capacity(authorities.len());
@@ -347,11 +337,12 @@ where
self.resolved_authorities = resolved;
gum::debug!(target: LOG_TARGET, %num, "Issuing a connection request");
ctx.send_message(NetworkBridgeMessage::ConnectToResolvedValidators {
validator_addrs,
peer_set: PeerSet::Validation,
})
.await;
sender
.send_message(NetworkBridgeMessage::ConnectToResolvedValidators {
validator_addrs,
peer_set: PeerSet::Validation,
})
.await;
// issue another request for the same session
// if at least a third of the authorities were not resolved.
@@ -442,15 +433,11 @@ where
}
// Get the authorities of the past, present, and future.
async fn authorities_past_present_future<Context>(
ctx: &mut Context,
async fn authorities_past_present_future(
sender: &mut impl overseer::GossipSupportSenderTrait,
relay_parent: Hash,
) -> Result<Vec<AuthorityDiscoveryId>, util::Error>
where
Context: SubsystemContext<Message = GossipSupportMessage>,
Context: overseer::SubsystemContext<Message = GossipSupportMessage>,
{
let authorities = util::request_authorities(relay_parent, ctx.sender()).await.await??;
) -> Result<Vec<AuthorityDiscoveryId>, util::Error> {
let authorities = util::request_authorities(relay_parent, sender).await.await??;
gum::debug!(
target: LOG_TARGET,
authority_count = ?authorities.len(),
@@ -500,28 +487,25 @@ async fn remove_all_controlled(
/// This limits the amount of gossip peers to 2 * `sqrt(len)` and ensures the diameter of 2.
///
/// [web3]: https://research.web3.foundation/en/latest/polkadot/networking/3-avail-valid.html#topology
async fn update_gossip_topology<Context>(
ctx: &mut Context,
async fn update_gossip_topology(
sender: &mut impl overseer::GossipSupportSenderTrait,
our_index: usize,
authorities: Vec<AuthorityDiscoveryId>,
relay_parent: Hash,
session_index: SessionIndex,
) -> Result<(), util::Error>
where
Context: SubsystemContext<Message = GossipSupportMessage>,
Context: overseer::SubsystemContext<Message = GossipSupportMessage>,
{
) -> Result<(), util::Error> {
// retrieve BABE randomness
let random_seed = {
let (tx, rx) = oneshot::channel();
// TODO https://github.com/paritytech/polkadot/issues/5316:
// get the random seed from the `SessionInfo` instead.
ctx.send_message(RuntimeApiMessage::Request(
relay_parent,
RuntimeApiRequest::CurrentBabeEpoch(tx),
))
.await;
sender
.send_message(RuntimeApiMessage::Request(
relay_parent,
RuntimeApiRequest::CurrentBabeEpoch(tx),
))
.await;
let randomness = rx.await??.randomness;
let mut subject = [0u8; 40];
@@ -553,12 +537,13 @@ where
.map(|i| (authorities[i].clone(), ValidatorIndex::from(i as u32)))
.collect();
ctx.send_message(NetworkBridgeMessage::NewGossipTopology {
session: session_index,
our_neighbors_x: row_neighbors,
our_neighbors_y: column_neighbors,
})
.await;
sender
.send_message(NetworkBridgeMessage::NewGossipTopology {
session: session_index,
our_neighbors_x: row_neighbors,
our_neighbors_y: column_neighbors,
})
.await;
Ok(())
}
@@ -596,10 +581,9 @@ fn matrix_neighbors(
}
}
impl<Context, AD> overseer::Subsystem<Context, SubsystemError> for GossipSupport<AD>
#[overseer::subsystem(GossipSupport, error = SubsystemError, prefix = self::overseer)]
impl<Context, AD> GossipSupport<AD>
where
Context: SubsystemContext<Message = GossipSupportMessage>,
Context: overseer::SubsystemContext<Message = GossipSupportMessage>,
AD: AuthorityDiscovery + Clone,
{
fn start(self, ctx: Context) -> SpawnedSubsystem {