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
@@ -33,8 +33,8 @@ use futures::{
};
use polkadot_node_subsystem::{
messages::{AllMessages, ChainApiMessage},
ActivatedLeaf, ActiveLeavesUpdate, LeafStatus, SubsystemContext,
messages::{ChainApiMessage, RuntimeApiMessage},
overseer, ActivatedLeaf, ActiveLeavesUpdate, LeafStatus,
};
use polkadot_node_subsystem_util::runtime::{get_occupied_cores, RuntimeInfo};
use polkadot_primitives::v2::{CandidateHash, Hash, OccupiedCore, SessionIndex};
@@ -78,6 +78,7 @@ pub struct Requester {
metrics: Metrics,
}
#[overseer::contextbounds(AvailabilityDistribution, prefix = self::overseer)]
impl Requester {
/// How many ancestors of the leaf should we consider along with it.
pub(crate) const LEAF_ANCESTRY_LEN_WITHIN_SESSION: usize = 3;
@@ -99,10 +100,7 @@ impl Requester {
ctx: &mut Context,
runtime: &mut RuntimeInfo,
update: ActiveLeavesUpdate,
) -> Result<()>
where
Context: SubsystemContext,
{
) -> Result<()> {
gum::trace!(target: LOG_TARGET, ?update, "Update fetching heads");
let ActiveLeavesUpdate { activated, deactivated } = update;
// Stale leaves happen after a reversion - we don't want to re-run availability there.
@@ -125,13 +123,11 @@ impl Requester {
ctx: &mut Context,
runtime: &mut RuntimeInfo,
new_head: ActivatedLeaf,
) -> Result<()>
where
Context: SubsystemContext,
{
) -> Result<()> {
let sender = &mut ctx.sender().clone();
let ActivatedLeaf { hash: leaf, .. } = new_head;
let (leaf_session_index, ancestors_in_session) = get_block_ancestors_in_same_session(
ctx,
sender,
runtime,
leaf,
Self::LEAF_ANCESTRY_LEN_WITHIN_SESSION,
@@ -139,7 +135,7 @@ impl Requester {
.await?;
// Also spawn or bump tasks for candidates in ancestry in the same session.
for hash in std::iter::once(leaf).chain(ancestors_in_session) {
let cores = get_occupied_cores(ctx, hash).await?;
let cores = get_occupied_cores(sender, hash).await?;
gum::trace!(
target: LOG_TARGET,
occupied_cores = ?cores,
@@ -177,15 +173,12 @@ impl Requester {
/// passed in leaf might be some later block where the candidate is still pending availability.
async fn add_cores<Context>(
&mut self,
ctx: &mut Context,
context: &mut Context,
runtime: &mut RuntimeInfo,
leaf: Hash,
leaf_session_index: SessionIndex,
cores: impl IntoIterator<Item = OccupiedCore>,
) -> Result<()>
where
Context: SubsystemContext,
{
) -> Result<()> {
for core in cores {
match self.fetches.entry(core.candidate_hash) {
Entry::Occupied(mut e) =>
@@ -200,7 +193,7 @@ impl Requester {
let task_cfg = self
.session_cache
.with_session_info(
ctx,
context,
runtime,
// We use leaf here, the relay_parent must be in the same session as the
// leaf. This is guaranteed by runtime which ensures that cores are cleared
@@ -221,7 +214,7 @@ impl Requester {
});
if let Ok(Some(task_cfg)) = task_cfg {
e.insert(FetchTask::start(task_cfg, ctx).await?);
e.insert(FetchTask::start(task_cfg, context).await?);
}
// Not a validator, nothing to do.
},
@@ -232,9 +225,9 @@ impl Requester {
}
impl Stream for Requester {
type Item = AllMessages;
type Item = overseer::AvailabilityDistributionOutgoingMessages;
fn poll_next(mut self: Pin<&mut Self>, ctx: &mut Context) -> Poll<Option<AllMessages>> {
fn poll_next(mut self: Pin<&mut Self>, ctx: &mut Context) -> Poll<Option<Self::Item>> {
loop {
match Pin::new(&mut self.rx).poll_next(ctx) {
Poll::Ready(Some(FromFetchTask::Message(m))) => return Poll::Ready(Some(m)),
@@ -257,26 +250,27 @@ impl Stream for Requester {
/// Requests up to `limit` ancestor hashes of relay parent in the same session.
///
/// Also returns session index of the `head`.
async fn get_block_ancestors_in_same_session<Context>(
ctx: &mut Context,
async fn get_block_ancestors_in_same_session<Sender>(
sender: &mut Sender,
runtime: &mut RuntimeInfo,
head: Hash,
limit: usize,
) -> Result<(SessionIndex, Vec<Hash>)>
where
Context: SubsystemContext,
Sender:
overseer::SubsystemSender<RuntimeApiMessage> + overseer::SubsystemSender<ChainApiMessage>,
{
// The order is parent, grandparent, ...
//
// `limit + 1` since a session index for the last element in ancestry
// is obtained through its parent. It always gets truncated because
// `session_ancestry_len` can only be incremented `ancestors.len() - 1` times.
let mut ancestors = get_block_ancestors(ctx, head, limit + 1).await?;
let mut ancestors = get_block_ancestors(sender, head, limit + 1).await?;
let mut ancestors_iter = ancestors.iter();
// `head` is the child of the first block in `ancestors`, request its session index.
let head_session_index = match ancestors_iter.next() {
Some(parent) => runtime.get_session_index_for_child(ctx.sender(), *parent).await?,
Some(parent) => runtime.get_session_index_for_child(sender, *parent).await?,
None => {
// No first element, i.e. empty.
return Ok((0, ancestors))
@@ -287,7 +281,7 @@ where
// The first parent is skipped.
for parent in ancestors_iter {
// Parent is the i-th ancestor, request session index for its child -- (i-1)th element.
let session_index = runtime.get_session_index_for_child(ctx.sender(), *parent).await?;
let session_index = runtime.get_session_index_for_child(sender, *parent).await?;
if session_index == head_session_index {
session_ancestry_len += 1;
} else {
@@ -302,21 +296,22 @@ where
}
/// Request up to `limit` ancestor hashes of relay parent from the Chain API.
async fn get_block_ancestors<Context>(
ctx: &mut Context,
async fn get_block_ancestors<Sender>(
sender: &mut Sender,
relay_parent: Hash,
limit: usize,
) -> Result<Vec<Hash>>
where
Context: SubsystemContext,
Sender: overseer::SubsystemSender<ChainApiMessage>,
{
let (tx, rx) = oneshot::channel();
ctx.send_message(ChainApiMessage::Ancestors {
hash: relay_parent,
k: limit,
response_channel: tx,
})
.await;
sender
.send_message(ChainApiMessage::Ancestors {
hash: relay_parent,
k: limit,
response_channel: tx,
})
.await;
let ancestors = rx
.await