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
+61 -87
View File
@@ -37,13 +37,12 @@ use polkadot_node_primitives::{
use polkadot_node_subsystem::{
jaeger,
messages::{
AllMessages, AvailabilityDistributionMessage, AvailabilityStoreMessage,
CandidateBackingMessage, CandidateValidationMessage, CollatorProtocolMessage,
DisputeCoordinatorMessage, ProvisionableData, ProvisionerMessage, RuntimeApiRequest,
StatementDistributionMessage,
AvailabilityDistributionMessage, AvailabilityStoreMessage, CandidateBackingMessage,
CandidateValidationMessage, CollatorProtocolMessage, DisputeCoordinatorMessage,
ProvisionableData, ProvisionerMessage, RuntimeApiRequest, StatementDistributionMessage,
},
overseer, ActiveLeavesUpdate, FromOverseer, OverseerSignal, PerLeafSpan, SpawnedSubsystem,
Stage, SubsystemContext, SubsystemError, SubsystemSender,
Stage, SubsystemError,
};
use polkadot_node_subsystem_util::{
self as util, request_from_runtime, request_session_index_for_child, request_validator_groups,
@@ -131,10 +130,10 @@ impl CandidateBackingSubsystem {
}
}
impl<Context> overseer::Subsystem<Context, SubsystemError> for CandidateBackingSubsystem
#[overseer::subsystem(CandidateBacking, error = SubsystemError, prefix = self::overseer)]
impl<Context> CandidateBackingSubsystem
where
Context: SubsystemContext<Message = CandidateBackingMessage>,
Context: overseer::SubsystemContext<Message = CandidateBackingMessage>,
Context: Send + Sync,
{
fn start(self, ctx: Context) -> SpawnedSubsystem {
let future = async move {
@@ -148,15 +147,12 @@ where
}
}
#[overseer::contextbounds(CandidateBacking, prefix = self::overseer)]
async fn run<Context>(
mut ctx: Context,
keystore: SyncCryptoStorePtr,
metrics: Metrics,
) -> FatalResult<()>
where
Context: SubsystemContext<Message = CandidateBackingMessage>,
Context: overseer::SubsystemContext<Message = CandidateBackingMessage>,
{
) -> FatalResult<()> {
let (background_validation_tx, mut background_validation_rx) = mpsc::channel(16);
let mut jobs = HashMap::new();
@@ -180,6 +176,7 @@ where
Ok(())
}
#[overseer::contextbounds(CandidateBacking, prefix = self::overseer)]
async fn run_iteration<Context>(
ctx: &mut Context,
keystore: SyncCryptoStorePtr,
@@ -187,11 +184,7 @@ async fn run_iteration<Context>(
jobs: &mut HashMap<Hash, JobAndSpan<Context>>,
background_validation_tx: mpsc::Sender<(Hash, ValidatedCandidateCommand)>,
background_validation_rx: &mut mpsc::Receiver<(Hash, ValidatedCandidateCommand)>,
) -> Result<(), Error>
where
Context: SubsystemContext<Message = CandidateBackingMessage>,
Context: overseer::SubsystemContext<Message = CandidateBackingMessage>,
{
) -> Result<(), Error> {
loop {
futures::select!(
validated_command = background_validation_rx.next().fuse() => {
@@ -225,16 +218,13 @@ where
}
}
#[overseer::contextbounds(CandidateBacking, prefix = self::overseer)]
async fn handle_validated_candidate_command<Context>(
ctx: &mut Context,
jobs: &mut HashMap<Hash, JobAndSpan<Context>>,
relay_parent: Hash,
command: ValidatedCandidateCommand,
) -> Result<(), Error>
where
Context: SubsystemContext<Message = CandidateBackingMessage>,
Context: overseer::SubsystemContext<Message = CandidateBackingMessage>,
{
) -> Result<(), Error> {
if let Some(job) = jobs.get_mut(&relay_parent) {
job.job.handle_validated_candidate_command(&job.span, ctx, command).await?;
} else {
@@ -245,15 +235,12 @@ where
Ok(())
}
#[overseer::contextbounds(CandidateBacking, prefix = self::overseer)]
async fn handle_communication<Context>(
ctx: &mut Context,
jobs: &mut HashMap<Hash, JobAndSpan<Context>>,
message: CandidateBackingMessage,
) -> Result<(), Error>
where
Context: SubsystemContext<Message = CandidateBackingMessage>,
Context: overseer::SubsystemContext<Message = CandidateBackingMessage>,
{
) -> Result<(), Error> {
match message {
CandidateBackingMessage::Second(relay_parent, candidate, pov) => {
if let Some(job) = jobs.get_mut(&relay_parent) {
@@ -274,6 +261,7 @@ where
Ok(())
}
#[overseer::contextbounds(CandidateBacking, prefix = self::overseer)]
async fn handle_active_leaves_update<Context>(
ctx: &mut Context,
update: ActiveLeavesUpdate,
@@ -281,11 +269,7 @@ async fn handle_active_leaves_update<Context>(
keystore: &SyncCryptoStorePtr,
background_validation_tx: &mpsc::Sender<(Hash, ValidatedCandidateCommand)>,
metrics: &Metrics,
) -> Result<(), Error>
where
Context: SubsystemContext<Message = CandidateBackingMessage>,
Context: overseer::SubsystemContext<Message = CandidateBackingMessage>,
{
) -> Result<(), Error> {
for deactivated in update.deactivated {
jobs.remove(&deactivated);
}
@@ -578,22 +562,19 @@ fn table_attested_to_backed(
}
async fn store_available_data(
sender: &mut impl SubsystemSender,
sender: &mut impl overseer::CandidateBackingSenderTrait,
n_validators: u32,
candidate_hash: CandidateHash,
available_data: AvailableData,
) -> Result<(), Error> {
let (tx, rx) = oneshot::channel();
sender
.send_message(
AvailabilityStoreMessage::StoreAvailableData {
candidate_hash,
n_validators,
available_data,
tx,
}
.into(),
)
.send_message(AvailabilityStoreMessage::StoreAvailableData {
candidate_hash,
n_validators,
available_data,
tx,
})
.await;
let _ = rx.await.map_err(Error::StoreAvailableData)?;
@@ -605,8 +586,9 @@ async fn store_available_data(
//
// This will compute the erasure root internally and compare it to the expected erasure root.
// This returns `Err()` iff there is an internal error. Otherwise, it returns either `Ok(Ok(()))` or `Ok(Err(_))`.
async fn make_pov_available(
sender: &mut impl SubsystemSender,
sender: &mut impl overseer::CandidateBackingSenderTrait,
n_validators: usize,
pov: Arc<PoV>,
candidate_hash: CandidateHash,
@@ -639,7 +621,7 @@ async fn make_pov_available(
}
async fn request_pov(
sender: &mut impl SubsystemSender,
sender: &mut impl overseer::CandidateBackingSenderTrait,
relay_parent: Hash,
from_validator: ValidatorIndex,
candidate_hash: CandidateHash,
@@ -647,16 +629,13 @@ async fn request_pov(
) -> Result<Arc<PoV>, Error> {
let (tx, rx) = oneshot::channel();
sender
.send_message(
AvailabilityDistributionMessage::FetchPoV {
relay_parent,
from_validator,
candidate_hash,
pov_hash,
tx,
}
.into(),
)
.send_message(AvailabilityDistributionMessage::FetchPoV {
relay_parent,
from_validator,
candidate_hash,
pov_hash,
tx,
})
.await;
let pov = rx.await.map_err(|_| Error::FetchPoV)?;
@@ -664,22 +643,19 @@ async fn request_pov(
}
async fn request_candidate_validation(
sender: &mut impl SubsystemSender,
sender: &mut impl overseer::CandidateBackingSenderTrait,
candidate_receipt: CandidateReceipt,
pov: Arc<PoV>,
) -> Result<ValidationResult, Error> {
let (tx, rx) = oneshot::channel();
sender
.send_message(
CandidateValidationMessage::ValidateFromChainState(
candidate_receipt,
pov,
BACKING_EXECUTION_TIMEOUT,
tx,
)
.into(),
)
.send_message(CandidateValidationMessage::ValidateFromChainState(
candidate_receipt,
pov,
BACKING_EXECUTION_TIMEOUT,
tx,
))
.await;
match rx.await {
@@ -692,7 +668,7 @@ async fn request_candidate_validation(
type BackgroundValidationResult =
Result<(CandidateReceipt, CandidateCommitments, Arc<PoV>), CandidateReceipt>;
struct BackgroundValidationParams<S: overseer::SubsystemSender<AllMessages>, F> {
struct BackgroundValidationParams<S: overseer::CandidateBackingSenderTrait, F> {
sender: S,
tx_command: mpsc::Sender<(Hash, ValidatedCandidateCommand)>,
candidate: CandidateReceipt,
@@ -705,7 +681,7 @@ struct BackgroundValidationParams<S: overseer::SubsystemSender<AllMessages>, F>
async fn validate_and_make_available(
params: BackgroundValidationParams<
impl SubsystemSender,
impl overseer::CandidateBackingSenderTrait,
impl Fn(BackgroundValidationResult) -> ValidatedCandidateCommand + Sync,
>,
) -> Result<(), Error> {
@@ -809,11 +785,8 @@ async fn validate_and_make_available(
struct ValidatorIndexOutOfBounds;
impl<Context> CandidateBackingJob<Context>
where
Context: SubsystemContext,
Context: overseer::SubsystemContext,
{
#[overseer::contextbounds(CandidateBacking, prefix = self::overseer)]
impl<Context> CandidateBackingJob<Context> {
async fn handle_validated_candidate_command(
&mut self,
root_span: &jaeger::Span,
@@ -896,7 +869,7 @@ where
&mut self,
ctx: &mut Context,
params: BackgroundValidationParams<
impl SubsystemSender,
impl overseer::CandidateBackingSenderTrait,
impl Fn(BackgroundValidationResult) -> ValidatedCandidateCommand + Send + 'static + Sync,
>,
) -> Result<(), Error> {
@@ -1001,7 +974,7 @@ where
}
/// Check if there have happened any new misbehaviors and issue necessary messages.
fn issue_new_misbehaviors(&mut self, ctx: &mut Context) {
fn issue_new_misbehaviors(&mut self, sender: &mut impl overseer::CandidateBackingSenderTrait) {
// collect the misbehaviors to avoid double mutable self borrow issues
let misbehaviors: Vec<_> = self.table.drain_misbehaviors().collect();
for (validator_id, report) in misbehaviors {
@@ -1010,7 +983,7 @@ where
//
// Misbehaviors are bounded by the number of validators and
// the block production protocol.
ctx.send_unbounded_message(ProvisionerMessage::ProvisionableData(
sender.send_unbounded_message(ProvisionerMessage::ProvisionableData(
self.parent,
ProvisionableData::MisbehaviorReport(self.parent, validator_id, report),
));
@@ -1042,7 +1015,7 @@ where
};
if let Err(ValidatorIndexOutOfBounds) = self
.dispatch_new_statement_to_dispute_coordinator(ctx, candidate_hash, &statement)
.dispatch_new_statement_to_dispute_coordinator(ctx.sender(), candidate_hash, &statement)
.await
{
gum::warn!(
@@ -1101,7 +1074,7 @@ where
None
};
self.issue_new_misbehaviors(ctx);
self.issue_new_misbehaviors(ctx.sender());
// It is important that the child span is dropped before its parent span (`unbacked_span`)
drop(import_statement_span);
@@ -1123,8 +1096,8 @@ where
/// the networking component responsible for feeding statements to the backing subsystem
/// is meant to check the signature and provenance of all statements before submission.
async fn dispatch_new_statement_to_dispute_coordinator(
&mut self,
ctx: &mut Context,
&self,
sender: &mut impl overseer::CandidateBackingSenderTrait,
candidate_hash: CandidateHash,
statement: &SignedFullStatement,
) -> Result<(), ValidatorIndexOutOfBounds> {
@@ -1157,14 +1130,15 @@ where
if let (Some(candidate_receipt), Some(dispute_statement)) =
(maybe_candidate_receipt, maybe_signed_dispute_statement)
{
ctx.send_message(DisputeCoordinatorMessage::ImportStatements {
candidate_hash,
candidate_receipt,
session: self.session_index,
statements: vec![(dispute_statement, validator_index)],
pending_confirmation: None,
})
.await;
sender
.send_message(DisputeCoordinatorMessage::ImportStatements {
candidate_hash,
candidate_receipt,
session: self.session_index,
statements: vec![(dispute_statement, validator_index)],
pending_confirmation: None,
})
.await;
}
Ok(())