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
+64 -74
View File
@@ -37,9 +37,8 @@ use polkadot_node_subsystem::{
ChainSelectionMessage, DisputeCoordinatorMessage, HighestApprovedAncestorBlock,
RuntimeApiMessage, RuntimeApiRequest,
},
overseer::{self, SubsystemSender as _},
FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemContext, SubsystemError,
SubsystemResult, SubsystemSender,
overseer, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemError, SubsystemResult,
SubsystemSender,
};
use polkadot_node_subsystem_util::{
database::Database,
@@ -355,11 +354,8 @@ impl ApprovalVotingSubsystem {
}
}
impl<Context> overseer::Subsystem<Context, SubsystemError> for ApprovalVotingSubsystem
where
Context: SubsystemContext<Message = ApprovalVotingMessage>,
Context: overseer::SubsystemContext<Message = ApprovalVotingMessage>,
{
#[overseer::subsystem(ApprovalVoting, error = SubsystemError, prefix = self::overseer)]
impl<Context: Send> ApprovalVotingSubsystem {
fn start(self, ctx: Context) -> SpawnedSubsystem {
let backend = DbBackend::new(self.db.clone(), self.db_config);
let future = run::<DbBackend, Context>(
@@ -597,27 +593,34 @@ struct State {
assignment_criteria: Box<dyn AssignmentCriteria + Send + Sync>,
}
#[overseer::contextbounds(ApprovalVoting, prefix = self::overseer)]
impl State {
fn session_info(&self, i: SessionIndex) -> Option<&SessionInfo> {
self.session_window.as_ref().and_then(|w| w.session_info(i))
}
/// Bring `session_window` up to date.
pub async fn cache_session_info_for_head(
pub async fn cache_session_info_for_head<Context>(
&mut self,
ctx: &mut (impl SubsystemContext + overseer::SubsystemContext),
ctx: &mut Context,
head: Hash,
) -> Result<Option<SessionWindowUpdate>, SessionsUnavailable> {
) -> Result<Option<SessionWindowUpdate>, SessionsUnavailable>
where
<Context as overseer::SubsystemContext>::Sender: Sized + Send,
{
let session_window = self.session_window.take();
match session_window {
None => {
let sender = ctx.sender().clone();
self.session_window =
Some(RollingSessionWindow::new(ctx, APPROVAL_SESSIONS, head).await?);
Some(RollingSessionWindow::new(sender, APPROVAL_SESSIONS, head).await?);
Ok(None)
},
Some(mut session_window) => {
let r =
session_window.cache_session_info_for_head(ctx, head).await.map(Option::Some);
let r = session_window
.cache_session_info_for_head(ctx.sender(), head)
.await
.map(Option::Some);
self.session_window = Some(session_window);
r
},
@@ -701,6 +704,7 @@ enum Action {
Conclude,
}
#[overseer::contextbounds(ApprovalVoting, prefix = self::overseer)]
async fn run<B, Context>(
mut ctx: Context,
mut subsystem: ApprovalVotingSubsystem,
@@ -709,8 +713,6 @@ async fn run<B, Context>(
mut backend: B,
) -> SubsystemResult<()>
where
Context: SubsystemContext<Message = ApprovalVotingMessage>,
Context: overseer::SubsystemContext<Message = ApprovalVotingMessage>,
B: Backend,
{
let mut state = State {
@@ -848,9 +850,9 @@ where
// https://github.com/paritytech/polkadot/issues/3311
//
// returns `true` if any of the actions was a `Conclude` command.
async fn handle_actions(
ctx: &mut (impl SubsystemContext<Message = ApprovalVotingMessage>
+ overseer::SubsystemContext<Message = ApprovalVotingMessage>),
#[overseer::contextbounds(ApprovalVoting, prefix = self::overseer)]
async fn handle_actions<Context>(
ctx: &mut Context,
state: &mut State,
overlayed_db: &mut OverlayedBackend<'_, impl Backend>,
metrics: &Metrics,
@@ -868,7 +870,6 @@ async fn handle_actions(
Action::ScheduleWakeup { block_hash, block_number, candidate_hash, tick } =>
wakeups.schedule(block_hash, block_number, candidate_hash, tick),
Action::IssueApproval(candidate_hash, approval_request) => {
let mut sender = ctx.sender().clone();
// Note that the IssueApproval action will create additional
// actions that will need to all be processed before we can
// handle the next action in the set passed to the ambient
@@ -881,7 +882,7 @@ async fn handle_actions(
// Note that chaining these iterators is O(n) as we must consume
// the prior iterator.
let next_actions: Vec<Action> = issue_approval(
&mut sender,
ctx,
state,
overlayed_db,
metrics,
@@ -1086,9 +1087,9 @@ fn distribution_messages_for_activation(
}
// Handle an incoming signal from the overseer. Returns true if execution should conclude.
async fn handle_from_overseer(
ctx: &mut (impl SubsystemContext<Message = ApprovalVotingMessage>
+ overseer::SubsystemContext<Message = ApprovalVotingMessage>),
#[overseer::contextbounds(ApprovalVoting, prefix = self::overseer)]
async fn handle_from_overseer<Context>(
ctx: &mut Context,
state: &mut State,
db: &mut OverlayedBackend<'_, impl Backend>,
metrics: &Metrics,
@@ -1197,8 +1198,9 @@ async fn handle_from_overseer(
Ok(actions)
}
async fn handle_approved_ancestor(
ctx: &mut (impl SubsystemContext + overseer::SubsystemContext),
#[overseer::contextbounds(ApprovalVoting, prefix = self::overseer)]
async fn handle_approved_ancestor<Context>(
ctx: &mut Context,
db: &OverlayedBackend<'_, impl Backend>,
target: Hash,
lower_bound: BlockNumber,
@@ -2147,9 +2149,9 @@ fn process_wakeup(
// Launch approval work, returning an `AbortHandle` which corresponds to the background task
// spawned. When the background work is no longer needed, the `AbortHandle` should be dropped
// to cancel the background work and any requests it has spawned.
async fn launch_approval(
ctx: &mut (impl SubsystemContext<Message = ApprovalVotingMessage>
+ overseer::SubsystemContext<Message = ApprovalVotingMessage>),
#[overseer::contextbounds(ApprovalVoting, prefix = self::overseer)]
async fn launch_approval<Context>(
ctx: &mut Context,
metrics: Metrics,
session_index: SessionIndex,
candidate: CandidateReceipt,
@@ -2242,15 +2244,12 @@ async fn launch_approval(
);
sender
.send_message(
DisputeCoordinatorMessage::IssueLocalStatement(
session_index,
candidate_hash,
candidate.clone(),
false,
)
.into(),
)
.send_message(DisputeCoordinatorMessage::IssueLocalStatement(
session_index,
candidate_hash,
candidate.clone(),
false,
))
.await;
metrics_guard.take().on_approval_invalid();
},
@@ -2281,17 +2280,14 @@ async fn launch_approval(
let (val_tx, val_rx) = oneshot::channel();
sender
.send_message(
CandidateValidationMessage::ValidateFromExhaustive(
available_data.validation_data,
validation_code,
candidate.clone(),
available_data.pov,
APPROVAL_EXECUTION_TIMEOUT,
val_tx,
)
.into(),
)
.send_message(CandidateValidationMessage::ValidateFromExhaustive(
available_data.validation_data,
validation_code,
candidate.clone(),
available_data.pov,
APPROVAL_EXECUTION_TIMEOUT,
val_tx,
))
.await;
match val_rx.await {
@@ -2309,15 +2305,12 @@ async fn launch_approval(
} else {
// Commitments mismatch - issue a dispute.
sender
.send_message(
DisputeCoordinatorMessage::IssueLocalStatement(
session_index,
candidate_hash,
candidate.clone(),
false,
)
.into(),
)
.send_message(DisputeCoordinatorMessage::IssueLocalStatement(
session_index,
candidate_hash,
candidate.clone(),
false,
))
.await;
metrics_guard.take().on_approval_invalid();
@@ -2334,15 +2327,12 @@ async fn launch_approval(
);
sender
.send_message(
DisputeCoordinatorMessage::IssueLocalStatement(
session_index,
candidate_hash,
candidate.clone(),
false,
)
.into(),
)
.send_message(DisputeCoordinatorMessage::IssueLocalStatement(
session_index,
candidate_hash,
candidate.clone(),
false,
))
.await;
metrics_guard.take().on_approval_invalid();
@@ -2368,8 +2358,9 @@ async fn launch_approval(
// Issue and import a local approval vote. Should only be invoked after approval checks
// have been done.
async fn issue_approval(
ctx: &mut impl SubsystemSender,
#[overseer::contextbounds(ApprovalVoting, prefix = self::overseer)]
async fn issue_approval<Context>(
ctx: &mut Context,
state: &mut State,
db: &mut OverlayedBackend<'_, impl Backend>,
metrics: &Metrics,
@@ -2527,15 +2518,14 @@ async fn issue_approval(
metrics.on_approval_produced();
// dispatch to approval distribution.
ctx.send_unbounded_message(
ApprovalDistributionMessage::DistributeApproval(IndirectSignedApprovalVote {
ctx.send_unbounded_message(ApprovalDistributionMessage::DistributeApproval(
IndirectSignedApprovalVote {
block_hash,
candidate_index: candidate_index as _,
validator: validator_index,
signature: sig,
})
.into(),
);
},
));
// dispatch to dispute coordinator.
actions.extend(inform_disputes_action);