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
@@ -38,7 +38,7 @@ use polkadot_node_subsystem::{
ApprovalDistributionMessage, ChainApiMessage, ChainSelectionMessage, RuntimeApiMessage,
RuntimeApiRequest,
},
overseer, RuntimeApiError, SubsystemContext, SubsystemError, SubsystemResult,
overseer, RuntimeApiError, SubsystemError, SubsystemResult,
};
use polkadot_node_subsystem_util::{
determine_new_blocks,
@@ -107,8 +107,9 @@ enum ImportedBlockInfoError {
}
/// Computes information about the imported block. Returns an error if the info couldn't be extracted.
async fn imported_block_info(
ctx: &mut (impl SubsystemContext + overseer::SubsystemContext),
#[overseer::contextbounds(ApprovalVoting, prefix = self::overseer)]
async fn imported_block_info<Context>(
ctx: &mut Context,
env: ImportedBlockInfoEnv<'_>,
block_hash: Hash,
block_header: &Header,
@@ -319,10 +320,11 @@ pub struct BlockImportedCandidates {
/// * and return information about all candidates imported under each block.
///
/// It is the responsibility of the caller to schedule wakeups for each block.
pub(crate) async fn handle_new_head(
ctx: &mut (impl SubsystemContext + overseer::SubsystemContext),
#[overseer::contextbounds(ApprovalVoting, prefix = self::overseer)]
pub(crate) async fn handle_new_head<Context, B: Backend>(
ctx: &mut Context,
state: &mut State,
db: &mut OverlayedBackend<'_, impl Backend>,
db: &mut OverlayedBackend<'_, B>,
head: Hash,
finalized_number: &Option<BlockNumber>,
) -> SubsystemResult<Vec<BlockImportedCandidates>> {
@@ -609,7 +611,7 @@ pub(crate) mod tests {
use assert_matches::assert_matches;
use merlin::Transcript;
use polkadot_node_primitives::approval::{VRFOutput, VRFProof};
use polkadot_node_subsystem::messages::AllMessages;
use polkadot_node_subsystem::messages::{AllMessages, ApprovalVotingMessage};
use polkadot_node_subsystem_test_helpers::make_subsystem_context;
use polkadot_node_subsystem_util::database::Database;
use polkadot_primitives::v2::{Id as ParaId, SessionInfo, ValidatorIndex};
@@ -724,7 +726,8 @@ pub(crate) mod tests {
#[test]
fn imported_block_info_is_good() {
let pool = TaskExecutor::new();
let (mut ctx, mut handle) = make_subsystem_context::<(), _>(pool.clone());
let (mut ctx, mut handle) =
make_subsystem_context::<ApprovalVotingMessage, _>(pool.clone());
let session = 5;
let session_info = dummy_session_info(session);
@@ -847,7 +850,8 @@ pub(crate) mod tests {
#[test]
fn imported_block_info_fails_if_no_babe_vrf() {
let pool = TaskExecutor::new();
let (mut ctx, mut handle) = make_subsystem_context::<(), _>(pool.clone());
let (mut ctx, mut handle) =
make_subsystem_context::<ApprovalVotingMessage, _>(pool.clone());
let session = 5;
let session_info = dummy_session_info(session);
@@ -950,7 +954,8 @@ pub(crate) mod tests {
#[test]
fn imported_block_info_fails_if_ancient_session() {
let pool = TaskExecutor::new();
let (mut ctx, mut handle) = make_subsystem_context::<(), _>(pool.clone());
let (mut ctx, mut handle) =
make_subsystem_context::<ApprovalVotingMessage, _>(pool.clone());
let session = 5;
@@ -1027,7 +1032,7 @@ pub(crate) mod tests {
#[test]
fn imported_block_info_extracts_force_approve() {
let pool = TaskExecutor::new();
let (mut ctx, mut handle) = make_subsystem_context::<(), _>(pool.clone());
let (mut ctx, mut handle) = make_subsystem_context(pool.clone());
let session = 5;
let session_info = dummy_session_info(session);
@@ -1158,7 +1163,8 @@ pub(crate) mod tests {
let mut overlay_db = OverlayedBackend::new(&db);
let pool = TaskExecutor::new();
let (mut ctx, mut handle) = make_subsystem_context::<(), _>(pool.clone());
let (mut ctx, mut handle) =
make_subsystem_context::<ApprovalVotingMessage, _>(pool.clone());
let session = 5;
let irrelevant = 666;
+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);
+14 -33
View File
@@ -36,8 +36,7 @@ use polkadot_node_primitives::{AvailableData, ErasureChunk};
use polkadot_node_subsystem::{
errors::{ChainApiError, RuntimeApiError},
messages::{AvailabilityStoreMessage, ChainApiMessage},
overseer, ActiveLeavesUpdate, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemContext,
SubsystemError,
overseer, ActiveLeavesUpdate, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemError,
};
use polkadot_node_subsystem_util as util;
use polkadot_primitives::v2::{
@@ -519,23 +518,17 @@ impl KnownUnfinalizedBlocks {
}
}
impl<Context> overseer::Subsystem<Context, SubsystemError> for AvailabilityStoreSubsystem
where
Context: SubsystemContext<Message = AvailabilityStoreMessage>,
Context: overseer::SubsystemContext<Message = AvailabilityStoreMessage>,
{
#[overseer::subsystem(AvailabilityStore, error=SubsystemError, prefix=self::overseer)]
impl<Context> AvailabilityStoreSubsystem {
fn start(self, ctx: Context) -> SpawnedSubsystem {
let future = run(self, ctx).map(|_| Ok(())).boxed();
let future = run::<Context>(self, ctx).map(|_| Ok(())).boxed();
SpawnedSubsystem { name: "availability-store-subsystem", future }
}
}
async fn run<Context>(mut subsystem: AvailabilityStoreSubsystem, mut ctx: Context)
where
Context: SubsystemContext<Message = AvailabilityStoreMessage>,
Context: overseer::SubsystemContext<Message = AvailabilityStoreMessage>,
{
#[overseer::contextbounds(AvailabilityStore, prefix = self::overseer)]
async fn run<Context>(mut subsystem: AvailabilityStoreSubsystem, mut ctx: Context) {
let mut next_pruning = Delay::new(subsystem.pruning_config.pruning_interval).fuse();
loop {
@@ -556,15 +549,12 @@ where
}
}
#[overseer::contextbounds(AvailabilityStore, prefix = self::overseer)]
async fn run_iteration<Context>(
ctx: &mut Context,
subsystem: &mut AvailabilityStoreSubsystem,
mut next_pruning: &mut future::Fuse<Delay>,
) -> Result<bool, Error>
where
Context: SubsystemContext<Message = AvailabilityStoreMessage>,
Context: overseer::SubsystemContext<Message = AvailabilityStoreMessage>,
{
) -> Result<bool, Error> {
select! {
incoming = ctx.recv().fuse() => {
match incoming.map_err(|_| Error::ContextChannelClosed)? {
@@ -608,15 +598,12 @@ where
Ok(false)
}
#[overseer::contextbounds(AvailabilityStore, prefix = self::overseer)]
async fn process_block_activated<Context>(
ctx: &mut Context,
subsystem: &mut AvailabilityStoreSubsystem,
activated: Hash,
) -> Result<(), Error>
where
Context: SubsystemContext<Message = AvailabilityStoreMessage>,
Context: overseer::SubsystemContext<Message = AvailabilityStoreMessage>,
{
) -> Result<(), Error> {
let now = subsystem.clock.now()?;
let block_header = {
@@ -663,6 +650,7 @@ where
Ok(())
}
#[overseer::contextbounds(AvailabilityStore, prefix = self::overseer)]
async fn process_new_head<Context>(
ctx: &mut Context,
db: &Arc<dyn Database>,
@@ -672,11 +660,7 @@ async fn process_new_head<Context>(
now: Duration,
hash: Hash,
header: Header,
) -> Result<(), Error>
where
Context: SubsystemContext<Message = AvailabilityStoreMessage>,
Context: overseer::SubsystemContext<Message = AvailabilityStoreMessage>,
{
) -> Result<(), Error> {
let candidate_events = util::request_candidate_events(hash, ctx.sender()).await.await??;
// We need to request the number of validators based on the parent state,
@@ -814,16 +798,13 @@ macro_rules! peek_num {
};
}
#[overseer::contextbounds(AvailabilityStore, prefix = self::overseer)]
async fn process_block_finalized<Context>(
ctx: &mut Context,
subsystem: &AvailabilityStoreSubsystem,
finalized_hash: Hash,
finalized_number: BlockNumber,
) -> Result<(), Error>
where
Context: SubsystemContext<Message = AvailabilityStoreMessage>,
Context: overseer::SubsystemContext<Message = AvailabilityStoreMessage>,
{
) -> Result<(), Error> {
let now = subsystem.clock.now()?;
let mut next_possible_batch = 0;
+4 -4
View File
@@ -309,13 +309,13 @@ fn store_chunk_works() {
let chunk_msg =
AvailabilityStoreMessage::StoreChunk { candidate_hash, chunk: chunk.clone(), tx };
overseer_send(&mut virtual_overseer, chunk_msg.into()).await;
overseer_send(&mut virtual_overseer, chunk_msg).await;
assert_eq!(rx.await.unwrap(), Ok(()));
let (tx, rx) = oneshot::channel();
let query_chunk = AvailabilityStoreMessage::QueryChunk(candidate_hash, validator_index, tx);
overseer_send(&mut virtual_overseer, query_chunk.into()).await;
overseer_send(&mut virtual_overseer, query_chunk).await;
assert_eq!(rx.await.unwrap().unwrap(), chunk);
virtual_overseer
@@ -341,13 +341,13 @@ fn store_chunk_does_nothing_if_no_entry_already() {
let chunk_msg =
AvailabilityStoreMessage::StoreChunk { candidate_hash, chunk: chunk.clone(), tx };
overseer_send(&mut virtual_overseer, chunk_msg.into()).await;
overseer_send(&mut virtual_overseer, chunk_msg).await;
assert_eq!(rx.await.unwrap(), Err(()));
let (tx, rx) = oneshot::channel();
let query_chunk = AvailabilityStoreMessage::QueryChunk(candidate_hash, validator_index, tx);
overseer_send(&mut virtual_overseer, query_chunk.into()).await;
overseer_send(&mut virtual_overseer, query_chunk).await;
assert!(rx.await.unwrap().is_none());
virtual_overseer
+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(())
+4 -1
View File
@@ -23,7 +23,10 @@ use assert_matches::assert_matches;
use futures::{future, Future};
use polkadot_node_primitives::{BlockData, InvalidCandidate};
use polkadot_node_subsystem::{
messages::{CollatorProtocolMessage, RuntimeApiMessage, RuntimeApiRequest, ValidationFailed},
messages::{
AllMessages, CollatorProtocolMessage, RuntimeApiMessage, RuntimeApiRequest,
ValidationFailed,
},
ActivatedLeaf, ActiveLeavesUpdate, FromOverseer, LeafStatus, OverseerSignal,
};
use polkadot_node_subsystem_test_helpers as test_helpers;
+15 -9
View File
@@ -34,7 +34,7 @@ use polkadot_node_subsystem::{
AvailabilityStoreMessage, BitfieldDistributionMessage, BitfieldSigningMessage,
RuntimeApiMessage, RuntimeApiRequest,
},
ActivatedLeaf, LeafStatus, PerLeafSpan, SubsystemSender,
overseer, ActivatedLeaf, LeafStatus, PerLeafSpan, SubsystemSender,
};
use polkadot_node_subsystem_util::{self as util, JobSender, JobSubsystem, JobTrait, Validator};
use polkadot_primitives::v2::{AvailabilityBitfield, CoreState, Hash, ValidatorIndex};
@@ -53,7 +53,7 @@ const JOB_DELAY: Duration = Duration::from_millis(1500);
const LOG_TARGET: &str = "parachain::bitfield-signing";
/// Each `BitfieldSigningJob` prepares a signed bitfield for a single relay parent.
pub struct BitfieldSigningJob;
pub struct BitfieldSigningJob<Sender>(std::marker::PhantomData<Sender>);
/// Errors we may encounter in the course of executing the `BitfieldSigningSubsystem`.
#[derive(Debug, thiserror::Error)]
@@ -83,7 +83,7 @@ pub enum Error {
async fn get_core_availability(
core: &CoreState,
validator_idx: ValidatorIndex,
sender: &Mutex<&mut impl SubsystemSender>,
sender: &Mutex<&mut impl SubsystemSender<overseer::BitfieldSigningOutgoingMessages>>,
span: &jaeger::Span,
) -> Result<bool, Error> {
if let &CoreState::Occupied(ref core) = core {
@@ -122,7 +122,7 @@ async fn get_core_availability(
/// delegates to the v1 runtime API
async fn get_availability_cores(
relay_parent: Hash,
sender: &mut impl SubsystemSender,
sender: &mut impl SubsystemSender<overseer::BitfieldSigningOutgoingMessages>,
) -> Result<Vec<CoreState>, Error> {
let (tx, rx) = oneshot::channel();
sender
@@ -146,7 +146,7 @@ async fn construct_availability_bitfield(
relay_parent: Hash,
span: &jaeger::Span,
validator_idx: ValidatorIndex,
sender: &mut impl SubsystemSender,
sender: &mut impl SubsystemSender<overseer::BitfieldSigningOutgoingMessages>,
) -> Result<AvailabilityBitfield, Error> {
// get the set of availability cores from the runtime
let availability_cores = {
@@ -182,8 +182,13 @@ async fn construct_availability_bitfield(
Ok(AvailabilityBitfield(core_bits))
}
impl JobTrait for BitfieldSigningJob {
impl<Sender> JobTrait for BitfieldSigningJob<Sender>
where
Sender: overseer::BitfieldSigningSenderTrait + Unpin,
{
type ToJob = BitfieldSigningMessage;
type OutgoingMessages = overseer::BitfieldSigningOutgoingMessages;
type Sender = Sender;
type Error = Error;
type RunArgs = SyncCryptoStorePtr;
type Metrics = Metrics;
@@ -191,12 +196,12 @@ impl JobTrait for BitfieldSigningJob {
const NAME: &'static str = "bitfield-signing-job";
/// Run a job for the parent block indicated
fn run<S: SubsystemSender>(
fn run(
leaf: ActivatedLeaf,
keystore: Self::RunArgs,
metrics: Self::Metrics,
_receiver: mpsc::Receiver<BitfieldSigningMessage>,
mut sender: JobSender<S>,
mut sender: JobSender<Sender>,
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send>> {
let metrics = metrics.clone();
async move {
@@ -286,4 +291,5 @@ impl JobTrait for BitfieldSigningJob {
}
/// `BitfieldSigningSubsystem` manages a number of bitfield signing jobs.
pub type BitfieldSigningSubsystem<Spawner> = JobSubsystem<BitfieldSigningJob, Spawner>;
pub type BitfieldSigningSubsystem<Spawner, Sender> =
JobSubsystem<BitfieldSigningJob<Sender>, Spawner>;
@@ -35,8 +35,8 @@ use polkadot_node_subsystem::{
CandidateValidationMessage, PreCheckOutcome, RuntimeApiMessage, RuntimeApiRequest,
ValidationFailed,
},
overseer, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemContext, SubsystemError,
SubsystemResult, SubsystemSender,
overseer, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemError, SubsystemResult,
SubsystemSender,
};
use polkadot_parachain::primitives::{ValidationParams, ValidationResult as WasmValidationResult};
use polkadot_primitives::v2::{
@@ -93,11 +93,8 @@ impl CandidateValidationSubsystem {
}
}
impl<Context> overseer::Subsystem<Context, SubsystemError> for CandidateValidationSubsystem
where
Context: SubsystemContext<Message = CandidateValidationMessage>,
Context: overseer::SubsystemContext<Message = CandidateValidationMessage>,
{
#[overseer::subsystem(CandidateValidation, error=SubsystemError, prefix=self::overseer)]
impl<Context> CandidateValidationSubsystem {
fn start(self, ctx: Context) -> SpawnedSubsystem {
let future = run(
ctx,
@@ -112,17 +109,14 @@ where
}
}
#[overseer::contextbounds(CandidateValidation, prefix = self::overseer)]
async fn run<Context>(
mut ctx: Context,
metrics: Metrics,
pvf_metrics: polkadot_node_core_pvf::Metrics,
cache_path: PathBuf,
program_path: PathBuf,
) -> SubsystemResult<()>
where
Context: SubsystemContext<Message = CandidateValidationMessage>,
Context: overseer::SubsystemContext<Message = CandidateValidationMessage>,
{
) -> SubsystemResult<()> {
let (validation_host, task) = polkadot_node_core_pvf::start(
polkadot_node_core_pvf::Config::new(cache_path, program_path),
pvf_metrics,
@@ -235,7 +229,7 @@ async fn runtime_api_request<T, Sender>(
receiver: oneshot::Receiver<Result<T, RuntimeApiError>>,
) -> Result<T, RuntimeRequestFailed>
where
Sender: SubsystemSender,
Sender: SubsystemSender<RuntimeApiMessage>,
{
sender
.send_message(RuntimeApiMessage::Request(relay_parent, request).into())
@@ -268,7 +262,7 @@ async fn request_validation_code_by_hash<Sender>(
validation_code_hash: ValidationCodeHash,
) -> Result<Option<ValidationCode>, RuntimeRequestFailed>
where
Sender: SubsystemSender,
Sender: SubsystemSender<RuntimeApiMessage>,
{
let (tx, rx) = oneshot::channel();
runtime_api_request(
@@ -287,7 +281,7 @@ async fn precheck_pvf<Sender>(
validation_code_hash: ValidationCodeHash,
) -> PreCheckOutcome
where
Sender: SubsystemSender,
Sender: SubsystemSender<RuntimeApiMessage>,
{
let validation_code =
match request_validation_code_by_hash(sender, relay_parent, validation_code_hash).await {
@@ -342,7 +336,7 @@ async fn check_assumption_validation_data<Sender>(
assumption: OccupiedCoreAssumption,
) -> AssumptionCheckOutcome
where
Sender: SubsystemSender,
Sender: SubsystemSender<RuntimeApiMessage>,
{
let validation_data = {
let (tx, rx) = oneshot::channel();
@@ -386,7 +380,7 @@ async fn find_assumed_validation_data<Sender>(
descriptor: &CandidateDescriptor,
) -> AssumptionCheckOutcome
where
Sender: SubsystemSender,
Sender: SubsystemSender<RuntimeApiMessage>,
{
// The candidate descriptor has a `persisted_validation_data_hash` which corresponds to
// one of up to two possible values that we can derive from the state of the
@@ -421,7 +415,7 @@ pub async fn find_validation_data<Sender>(
descriptor: &CandidateDescriptor,
) -> Result<Option<(PersistedValidationData, ValidationCode)>, ValidationFailed>
where
Sender: SubsystemSender,
Sender: SubsystemSender<RuntimeApiMessage>,
{
match find_assumed_validation_data(sender, &descriptor).await {
AssumptionCheckOutcome::Matches(validation_data, validation_code) =>
@@ -446,7 +440,7 @@ async fn validate_from_chain_state<Sender>(
metrics: &Metrics,
) -> Result<ValidationResult, ValidationFailed>
where
Sender: SubsystemSender,
Sender: SubsystemSender<RuntimeApiMessage>,
{
let mut new_sender = sender.clone();
let (validation_data, validation_code) =
+4 -6
View File
@@ -39,7 +39,7 @@ use sp_blockchain::HeaderBackend;
use polkadot_node_subsystem::{
messages::ChainApiMessage, overseer, FromOverseer, OverseerSignal, SpawnedSubsystem,
SubsystemContext, SubsystemError, SubsystemResult,
SubsystemError, SubsystemResult,
};
use polkadot_primitives::v2::{Block, BlockId};
@@ -64,11 +64,10 @@ impl<Client> ChainApiSubsystem<Client> {
}
}
impl<Client, Context> overseer::Subsystem<Context, SubsystemError> for ChainApiSubsystem<Client>
#[overseer::subsystem(ChainApi, error = SubsystemError, prefix = self::overseer)]
impl<Client, Context> ChainApiSubsystem<Client>
where
Client: HeaderBackend<Block> + AuxStore + 'static,
Context: SubsystemContext<Message = ChainApiMessage>,
Context: overseer::SubsystemContext<Message = ChainApiMessage>,
{
fn start(self, ctx: Context) -> SpawnedSubsystem {
let future = run::<Client, Context>(ctx, self)
@@ -78,14 +77,13 @@ where
}
}
#[overseer::contextbounds(ChainApi, prefix = self::overseer)]
async fn run<Client, Context>(
mut ctx: Context,
subsystem: ChainApiSubsystem<Client>,
) -> SubsystemResult<()>
where
Client: HeaderBackend<Block> + AuxStore,
Context: SubsystemContext<Message = ChainApiMessage>,
Context: overseer::SubsystemContext<Message = ChainApiMessage>,
{
loop {
match ctx.recv().await? {
+23 -27
View File
@@ -20,7 +20,8 @@ use polkadot_node_primitives::BlockWeight;
use polkadot_node_subsystem::{
errors::ChainApiError,
messages::{ChainApiMessage, ChainSelectionMessage},
overseer, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemContext, SubsystemError,
overseer::{self, SubsystemSender},
FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemError,
};
use polkadot_node_subsystem_util::database::Database;
use polkadot_primitives::v2::{BlockNumber, ConsensusLog, Hash, Header};
@@ -328,11 +329,8 @@ impl ChainSelectionSubsystem {
}
}
impl<Context> overseer::Subsystem<Context, SubsystemError> for ChainSelectionSubsystem
where
Context: SubsystemContext<Message = ChainSelectionMessage>,
Context: overseer::SubsystemContext<Message = ChainSelectionMessage>,
{
#[overseer::subsystem(ChainSelection, error = SubsystemError, prefix = self::overseer)]
impl<Context> ChainSelectionSubsystem {
fn start(self, ctx: Context) -> SpawnedSubsystem {
let backend = db_backend::v1::DbBackend::new(
self.db,
@@ -348,14 +346,13 @@ where
}
}
#[overseer::contextbounds(ChainSelection, prefix = self::overseer)]
async fn run<Context, B>(
mut ctx: Context,
mut backend: B,
stagnant_check_interval: StagnantCheckInterval,
clock: Box<dyn Clock + Send + Sync>,
) where
Context: SubsystemContext<Message = ChainSelectionMessage>,
Context: overseer::SubsystemContext<Message = ChainSelectionMessage>,
B: Backend,
{
loop {
@@ -363,7 +360,7 @@ async fn run<Context, B>(
match res {
Err(e) => {
e.trace();
// All errors right now are considered fatal:
// All errors are considered fatal right now:
break
},
Ok(()) => {
@@ -379,6 +376,7 @@ async fn run<Context, B>(
//
// A return value of `Ok` indicates that an exit should be made, while non-fatal errors
// lead to another call to this function.
#[overseer::contextbounds(ChainSelection, prefix = self::overseer)]
async fn run_until_error<Context, B>(
ctx: &mut Context,
backend: &mut B,
@@ -386,8 +384,6 @@ async fn run_until_error<Context, B>(
clock: &(dyn Clock + Sync),
) -> Result<(), Error>
where
Context: SubsystemContext<Message = ChainSelectionMessage>,
Context: overseer::SubsystemContext<Message = ChainSelectionMessage>,
B: Backend,
{
let mut stagnant_check_stream = stagnant_check_interval.timeout_stream();
@@ -402,7 +398,7 @@ where
FromOverseer::Signal(OverseerSignal::ActiveLeaves(update)) => {
for leaf in update.activated {
let write_ops = handle_active_leaf(
ctx,
ctx.sender(),
&*backend,
clock.timestamp_now() + STAGNANT_TIMEOUT,
leaf.hash,
@@ -419,7 +415,7 @@ where
handle_approved_block(backend, hash)?
}
ChainSelectionMessage::Leaves(tx) => {
let leaves = load_leaves(ctx, &*backend).await?;
let leaves = load_leaves(ctx.sender(), &*backend).await?;
let _ = tx.send(leaves);
}
ChainSelectionMessage::BestLeafContaining(required, tx) => {
@@ -446,11 +442,11 @@ where
}
async fn fetch_finalized(
ctx: &mut impl SubsystemContext,
sender: &mut impl SubsystemSender<ChainApiMessage>,
) -> Result<Option<(Hash, BlockNumber)>, Error> {
let (number_tx, number_rx) = oneshot::channel();
ctx.send_message(ChainApiMessage::FinalizedBlockNumber(number_tx)).await;
sender.send_message(ChainApiMessage::FinalizedBlockNumber(number_tx)).await;
let number = match number_rx.await? {
Ok(number) => number,
@@ -462,7 +458,7 @@ async fn fetch_finalized(
let (hash_tx, hash_rx) = oneshot::channel();
ctx.send_message(ChainApiMessage::FinalizedBlockHash(number, hash_tx)).await;
sender.send_message(ChainApiMessage::FinalizedBlockHash(number, hash_tx)).await;
match hash_rx.await? {
Err(err) => {
@@ -478,11 +474,11 @@ async fn fetch_finalized(
}
async fn fetch_header(
ctx: &mut impl SubsystemContext,
sender: &mut impl SubsystemSender<ChainApiMessage>,
hash: Hash,
) -> Result<Option<Header>, Error> {
let (tx, rx) = oneshot::channel();
ctx.send_message(ChainApiMessage::BlockHeader(hash, tx)).await;
sender.send_message(ChainApiMessage::BlockHeader(hash, tx)).await;
Ok(rx.await?.unwrap_or_else(|err| {
gum::warn!(target: LOG_TARGET, ?hash, ?err, "Missing hash for finalized block number");
@@ -491,11 +487,11 @@ async fn fetch_header(
}
async fn fetch_block_weight(
ctx: &mut impl SubsystemContext,
sender: &mut impl overseer::SubsystemSender<ChainApiMessage>,
hash: Hash,
) -> Result<Option<BlockWeight>, Error> {
let (tx, rx) = oneshot::channel();
ctx.send_message(ChainApiMessage::BlockWeight(hash, tx)).await;
sender.send_message(ChainApiMessage::BlockWeight(hash, tx)).await;
let res = rx.await?;
@@ -507,7 +503,7 @@ async fn fetch_block_weight(
// Handle a new active leaf.
async fn handle_active_leaf(
ctx: &mut impl SubsystemContext,
sender: &mut impl overseer::ChainSelectionSenderTrait,
backend: &impl Backend,
stagnant_at: Timestamp,
hash: Hash,
@@ -519,10 +515,10 @@ async fn handle_active_leaf(
// tree.
l.saturating_sub(1)
},
None => fetch_finalized(ctx).await?.map_or(1, |(_, n)| n),
None => fetch_finalized(sender).await?.map_or(1, |(_, n)| n),
};
let header = match fetch_header(ctx, hash).await? {
let header = match fetch_header(sender, hash).await? {
None => {
gum::warn!(target: LOG_TARGET, ?hash, "Missing header for new head");
return Ok(Vec::new())
@@ -531,7 +527,7 @@ async fn handle_active_leaf(
};
let new_blocks = polkadot_node_subsystem_util::determine_new_blocks(
ctx.sender(),
sender,
|h| backend.load_block_entry(h).map(|b| b.is_some()),
hash,
&header,
@@ -544,7 +540,7 @@ async fn handle_active_leaf(
// determine_new_blocks gives blocks in descending order.
// for this, we want ascending order.
for (hash, header) in new_blocks.into_iter().rev() {
let weight = match fetch_block_weight(ctx, hash).await? {
let weight = match fetch_block_weight(sender, hash).await? {
None => {
gum::warn!(
target: LOG_TARGET,
@@ -654,13 +650,13 @@ fn detect_stagnant(backend: &mut impl Backend, now: Timestamp) -> Result<(), Err
// Load the leaves from the backend. If there are no leaves, then return
// the finalized block.
async fn load_leaves(
ctx: &mut impl SubsystemContext,
sender: &mut impl overseer::SubsystemSender<ChainApiMessage>,
backend: &impl Backend,
) -> Result<Vec<Hash>, Error> {
let leaves: Vec<_> = backend.load_leaves()?.into_hashes_descending().collect();
if leaves.is_empty() {
Ok(fetch_finalized(ctx).await?.map_or(Vec::new(), |(h, _)| vec![h]))
Ok(fetch_finalized(sender).await?.map_or(Vec::new(), |(h, _)| vec![h]))
} else {
Ok(leaves)
}
@@ -34,7 +34,7 @@ use polkadot_node_subsystem::{
BlockDescription, DisputeCoordinatorMessage, DisputeDistributionMessage,
ImportStatementsResult,
},
overseer, ActivatedLeaf, ActiveLeavesUpdate, FromOverseer, OverseerSignal, SubsystemContext,
overseer, ActivatedLeaf, ActiveLeavesUpdate, FromOverseer, OverseerSignal,
};
use polkadot_node_subsystem_util::rolling_session_window::{
RollingSessionWindow, SessionWindowUpdate, SessionsUnavailable,
@@ -83,6 +83,7 @@ pub struct Initialized {
error: Option<SessionsUnavailable>,
}
#[overseer::contextbounds(DisputeCoordinator, prefix = self::overseer)]
impl Initialized {
/// Make initialized subsystem, ready to `run`.
pub fn new(
@@ -123,8 +124,6 @@ impl Initialized {
clock: Box<dyn Clock>,
) -> FatalResult<()>
where
Context: overseer::SubsystemContext<Message = DisputeCoordinatorMessage>,
Context: SubsystemContext<Message = DisputeCoordinatorMessage>,
B: Backend,
{
loop {
@@ -161,8 +160,6 @@ impl Initialized {
clock: &dyn Clock,
) -> Result<()>
where
Context: overseer::SubsystemContext<Message = DisputeCoordinatorMessage>,
Context: SubsystemContext<Message = DisputeCoordinatorMessage>,
B: Backend,
{
for (priority, request) in participations.drain(..) {
@@ -253,10 +250,9 @@ impl Initialized {
}
}
async fn process_active_leaves_update(
async fn process_active_leaves_update<Context>(
&mut self,
ctx: &mut (impl SubsystemContext<Message = DisputeCoordinatorMessage>
+ overseer::SubsystemContext<Message = DisputeCoordinatorMessage>),
ctx: &mut Context,
overlay_db: &mut OverlayedBackend<'_, impl Backend>,
update: ActiveLeavesUpdate,
now: u64,
@@ -268,7 +264,7 @@ impl Initialized {
if let Some(new_leaf) = update.activated {
match self
.rolling_session_window
.cache_session_info_for_head(ctx, new_leaf.hash)
.cache_session_info_for_head(ctx.sender(), new_leaf.hash)
.await
{
Err(e) => {
@@ -318,10 +314,9 @@ impl Initialized {
/// Scrapes on-chain votes (backing votes and concluded disputes) for a active leaf of the
/// relay chain.
async fn process_on_chain_votes(
async fn process_on_chain_votes<Context>(
&mut self,
ctx: &mut (impl SubsystemContext<Message = DisputeCoordinatorMessage>
+ overseer::SubsystemContext<Message = DisputeCoordinatorMessage>),
ctx: &mut Context,
overlay_db: &mut OverlayedBackend<'_, impl Backend>,
votes: ScrapedOnChainVotes,
now: u64,
@@ -497,9 +492,9 @@ impl Initialized {
Ok(())
}
async fn handle_incoming(
async fn handle_incoming<Context>(
&mut self,
ctx: &mut impl SubsystemContext,
ctx: &mut Context,
overlay_db: &mut OverlayedBackend<'_, impl Backend>,
message: DisputeCoordinatorMessage,
now: Timestamp,
@@ -634,9 +629,9 @@ impl Initialized {
Ok(())
}
async fn handle_import_statements(
async fn handle_import_statements<Context>(
&mut self,
ctx: &mut impl SubsystemContext,
ctx: &mut Context,
overlay_db: &mut OverlayedBackend<'_, impl Backend>,
candidate_hash: CandidateHash,
candidate_receipt: MaybeCandidateReceipt,
@@ -923,9 +918,9 @@ impl Initialized {
Ok(ImportStatementsResult::ValidImport)
}
async fn issue_local_statement(
async fn issue_local_statement<Context>(
&mut self,
ctx: &mut impl SubsystemContext,
ctx: &mut Context,
overlay_db: &mut OverlayedBackend<'_, impl Backend>,
candidate_hash: CandidateHash,
candidate_receipt: CandidateReceipt,
@@ -1054,10 +1049,10 @@ enum MuxedMessage {
Participation(participation::WorkerMessage),
}
#[overseer::contextbounds(DisputeCoordinator, prefix = self::overseer)]
impl MuxedMessage {
async fn receive(
ctx: &mut (impl SubsystemContext<Message = DisputeCoordinatorMessage>
+ overseer::SubsystemContext<Message = DisputeCoordinatorMessage>),
async fn receive<Context>(
ctx: &mut Context,
from_sender: &mut participation::WorkerMessageReceiver,
) -> FatalResult<Self> {
// We are only fusing here to make `select` happy, in reality we will quit if the stream
@@ -32,8 +32,7 @@ use sc_keystore::LocalKeystore;
use polkadot_node_primitives::{CandidateVotes, DISPUTE_WINDOW};
use polkadot_node_subsystem::{
messages::DisputeCoordinatorMessage, overseer, ActivatedLeaf, FromOverseer, OverseerSignal,
SpawnedSubsystem, SubsystemContext, SubsystemError,
overseer, ActivatedLeaf, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemError,
};
use polkadot_node_subsystem_util::{
database::Database, rolling_session_window::RollingSessionWindow,
@@ -124,11 +123,8 @@ impl Config {
}
}
impl<Context> overseer::Subsystem<Context, SubsystemError> for DisputeCoordinatorSubsystem
where
Context: SubsystemContext<Message = DisputeCoordinatorMessage>,
Context: overseer::SubsystemContext<Message = DisputeCoordinatorMessage>,
{
#[overseer::subsystem(DisputeCoordinator, error=SubsystemError, prefix=self::overseer)]
impl<Context: Send> DisputeCoordinatorSubsystem {
fn start(self, ctx: Context) -> SpawnedSubsystem {
let future = async {
let backend = DbBackend::new(self.store.clone(), self.config.column_config());
@@ -142,6 +138,7 @@ where
}
}
#[overseer::contextbounds(DisputeCoordinator, prefix = self::overseer)]
impl DisputeCoordinatorSubsystem {
/// Create a new instance of the subsystem.
pub fn new(
@@ -161,8 +158,6 @@ impl DisputeCoordinatorSubsystem {
clock: Box<dyn Clock>,
) -> FatalResult<()>
where
Context: overseer::SubsystemContext<Message = DisputeCoordinatorMessage>,
Context: SubsystemContext<Message = DisputeCoordinatorMessage>,
B: Backend + 'static,
{
let res = self.initialize(&mut ctx, backend, &*clock).await?;
@@ -194,8 +189,6 @@ impl DisputeCoordinatorSubsystem {
)>,
>
where
Context: overseer::SubsystemContext<Message = DisputeCoordinatorMessage>,
Context: SubsystemContext<Message = DisputeCoordinatorMessage>,
B: Backend + 'static,
{
loop {
@@ -260,11 +253,7 @@ impl DisputeCoordinatorSubsystem {
Vec<ScrapedOnChainVotes>,
SpamSlots,
ChainScraper,
)>
where
Context: overseer::SubsystemContext<Message = DisputeCoordinatorMessage>,
Context: SubsystemContext<Message = DisputeCoordinatorMessage>,
{
)> {
// Prune obsolete disputes:
db::v1::note_current_session(overlay_db, rolling_session_window.latest_session())?;
@@ -358,17 +347,15 @@ impl DisputeCoordinatorSubsystem {
}
/// Wait for `ActiveLeavesUpdate` on startup, returns `None` if `Conclude` signal came first.
#[overseer::contextbounds(DisputeCoordinator, prefix = self::overseer)]
async fn get_rolling_session_window<Context>(
ctx: &mut Context,
) -> Result<Option<(ActivatedLeaf, RollingSessionWindow)>>
where
Context: overseer::SubsystemContext<Message = DisputeCoordinatorMessage>,
Context: SubsystemContext<Message = DisputeCoordinatorMessage>,
{
if let Some(leaf) = wait_for_first_leaf(ctx).await? {
) -> Result<Option<(ActivatedLeaf, RollingSessionWindow)>> {
if let Some(leaf) = { wait_for_first_leaf(ctx) }.await? {
let sender = ctx.sender().clone();
Ok(Some((
leaf.clone(),
RollingSessionWindow::new(ctx, DISPUTE_WINDOW, leaf.hash)
RollingSessionWindow::new(sender, DISPUTE_WINDOW, leaf.hash)
.await
.map_err(JfyiError::RollingSessionWindow)?,
)))
@@ -378,11 +365,8 @@ where
}
/// Wait for `ActiveLeavesUpdate`, returns `None` if `Conclude` signal came first.
async fn wait_for_first_leaf<Context>(ctx: &mut Context) -> Result<Option<ActivatedLeaf>>
where
Context: overseer::SubsystemContext<Message = DisputeCoordinatorMessage>,
Context: SubsystemContext<Message = DisputeCoordinatorMessage>,
{
#[overseer::contextbounds(DisputeCoordinator, prefix = self::overseer)]
async fn wait_for_first_leaf<Context>(ctx: &mut Context) -> Result<Option<ActivatedLeaf>> {
loop {
match ctx.recv().await? {
FromOverseer::Signal(OverseerSignal::Conclude) => return Ok(None),
@@ -28,7 +28,7 @@ use futures_timer::Delay;
use polkadot_node_primitives::{ValidationResult, APPROVAL_EXECUTION_TIMEOUT};
use polkadot_node_subsystem::{
messages::{AvailabilityRecoveryMessage, AvailabilityStoreMessage, CandidateValidationMessage},
ActiveLeavesUpdate, RecoveryError, SubsystemContext, SubsystemSender,
overseer, ActiveLeavesUpdate, RecoveryError,
};
use polkadot_node_subsystem_util::runtime::get_validation_code_by_hash;
use polkadot_primitives::v2::{BlockNumber, CandidateHash, CandidateReceipt, Hash, SessionIndex};
@@ -123,6 +123,7 @@ impl WorkerMessage {
}
}
#[overseer::contextbounds(DisputeCoordinator, prefix = self::overseer)]
impl Participation {
/// Get ready for managing dispute participation requests.
///
@@ -144,7 +145,7 @@ impl Participation {
/// `on_active_leaves_update`, the participation will be launched right away.
///
/// Returns: false, if queues are already full.
pub async fn queue_participation<Context: SubsystemContext>(
pub async fn queue_participation<Context>(
&mut self,
ctx: &mut Context,
priority: ParticipationPriority,
@@ -174,7 +175,7 @@ impl Participation {
///
/// Returns: The received `ParticipationStatement` or a fatal error, in case
/// something went wrong when dequeuing more requests (tasks could not be spawned).
pub async fn get_participation_result<Context: SubsystemContext>(
pub async fn get_participation_result<Context>(
&mut self,
ctx: &mut Context,
msg: WorkerMessage,
@@ -190,7 +191,7 @@ impl Participation {
///
/// Make sure we to dequeue participations if that became possible and update most recent
/// block.
pub async fn process_active_leaves_update<Context: SubsystemContext>(
pub async fn process_active_leaves_update<Context>(
&mut self,
ctx: &mut Context,
update: &ActiveLeavesUpdate,
@@ -212,7 +213,8 @@ impl Participation {
}
/// Dequeue until `MAX_PARALLEL_PARTICIPATIONS` is reached.
async fn dequeue_until_capacity<Context: SubsystemContext>(
async fn dequeue_until_capacity<Context>(
&mut self,
ctx: &mut Context,
recent_head: Hash,
@@ -228,7 +230,7 @@ impl Participation {
}
/// Fork a participation task in the background.
fn fork_participation<Context: SubsystemContext>(
fn fork_participation<Context>(
&mut self,
ctx: &mut Context,
req: ParticipationRequest,
@@ -248,7 +250,7 @@ impl Participation {
async fn participate(
mut result_sender: WorkerMessageSender,
mut sender: impl SubsystemSender,
mut sender: impl overseer::DisputeCoordinatorSenderTrait,
block_hash: Hash,
req: ParticipationRequest,
) {
@@ -259,15 +261,12 @@ async fn participate(
// available data
let (recover_available_data_tx, recover_available_data_rx) = oneshot::channel();
sender
.send_message(
AvailabilityRecoveryMessage::RecoverAvailableData(
req.candidate_receipt().clone(),
req.session(),
None,
recover_available_data_tx,
)
.into(),
)
.send_message(AvailabilityRecoveryMessage::RecoverAvailableData(
req.candidate_receipt().clone(),
req.session(),
None,
recover_available_data_tx,
))
.await;
let available_data = match recover_available_data_rx.await {
@@ -326,15 +325,12 @@ async fn participate(
// in the dispute
let (store_available_data_tx, store_available_data_rx) = oneshot::channel();
sender
.send_message(
AvailabilityStoreMessage::StoreAvailableData {
candidate_hash: *req.candidate_hash(),
n_validators: req.n_validators() as u32,
available_data: available_data.clone(),
tx: store_available_data_tx,
}
.into(),
)
.send_message(AvailabilityStoreMessage::StoreAvailableData {
candidate_hash: *req.candidate_hash(),
n_validators: req.n_validators() as u32,
available_data: available_data.clone(),
tx: store_available_data_tx,
})
.await;
match store_available_data_rx.await {
@@ -364,17 +360,14 @@ async fn participate(
// same level of leeway.
let (validation_tx, validation_rx) = oneshot::channel();
sender
.send_message(
CandidateValidationMessage::ValidateFromExhaustive(
available_data.validation_data,
validation_code,
req.candidate_receipt().clone(),
available_data.pov,
APPROVAL_EXECUTION_TIMEOUT,
validation_tx,
)
.into(),
)
.send_message(CandidateValidationMessage::ValidateFromExhaustive(
available_data.validation_data,
validation_code,
req.candidate_receipt().clone(),
available_data.pov,
APPROVAL_EXECUTION_TIMEOUT,
validation_tx,
))
.await;
// we cast votes (either positive or negative) depending on the outcome of
@@ -20,7 +20,7 @@ use std::{
};
use futures::channel::oneshot;
use polkadot_node_subsystem::{messages::ChainApiMessage, SubsystemSender};
use polkadot_node_subsystem::{messages::ChainApiMessage, overseer};
use polkadot_primitives::v2::{BlockNumber, CandidateHash, CandidateReceipt, Hash, SessionIndex};
use crate::{
@@ -163,7 +163,7 @@ impl Queues {
/// Returns error in case a queue was found full already.
pub async fn queue(
&mut self,
sender: &mut impl SubsystemSender,
sender: &mut impl overseer::DisputeCoordinatorSenderTrait,
priority: ParticipationPriority,
req: ParticipationRequest,
) -> Result<()> {
@@ -305,7 +305,7 @@ impl CandidateComparator {
/// `Ok(None)` in case we could not lookup the candidate's relay parent, returns a
/// `FatalError` in case the chain API call fails with an unexpected error.
pub async fn new(
sender: &mut impl SubsystemSender,
sender: &mut impl overseer::DisputeCoordinatorSenderTrait,
candidate: &CandidateReceipt,
) -> FatalResult<Option<Self>> {
let candidate_hash = candidate.hash();
@@ -350,11 +350,11 @@ impl Ord for CandidateComparator {
}
async fn get_block_number(
sender: &mut impl SubsystemSender,
sender: &mut impl overseer::DisputeCoordinatorSenderTrait,
relay_parent: Hash,
) -> FatalResult<Option<BlockNumber>> {
let (tx, rx) = oneshot::channel();
sender.send_message(ChainApiMessage::BlockNumber(relay_parent, tx).into()).await;
sender.send_message(ChainApiMessage::BlockNumber(relay_parent, tx)).await;
rx.await
.map_err(|_| FatalError::ChainApiSenderDropped)?
.map_err(FatalError::ChainApiAncestors)
@@ -53,16 +53,15 @@ pub fn make_our_subsystem_context<S>(
make_subsystem_context(spawn)
}
async fn participate(
ctx: &mut impl SubsystemContext,
participation: &mut Participation,
) -> Result<()> {
#[overseer::contextbounds(DisputeCoordinator, prefix = self::overseer)]
async fn participate<Context>(ctx: &mut Context, participation: &mut Participation) -> Result<()> {
let commitments = CandidateCommitments::default();
participate_with_commitments_hash(ctx, participation, commitments.hash()).await
}
async fn participate_with_commitments_hash(
ctx: &mut impl SubsystemContext,
#[overseer::contextbounds(DisputeCoordinator, prefix = self::overseer)]
async fn participate_with_commitments_hash<Context>(
ctx: &mut Context,
participation: &mut Participation,
commitments_hash: Hash,
) -> Result<()> {
@@ -81,8 +80,9 @@ async fn participate_with_commitments_hash(
.await
}
async fn activate_leaf(
ctx: &mut impl SubsystemContext,
#[overseer::contextbounds(DisputeCoordinator, prefix = self::overseer)]
async fn activate_leaf<Context>(
ctx: &mut Context,
participation: &mut Participation,
block_number: BlockNumber,
) -> FatalResult<()> {
@@ -21,7 +21,8 @@ use lru::LruCache;
use polkadot_node_primitives::MAX_FINALITY_LAG;
use polkadot_node_subsystem::{
messages::ChainApiMessage, ActivatedLeaf, ActiveLeavesUpdate, ChainApiError, SubsystemSender,
messages::ChainApiMessage, overseer, ActivatedLeaf, ActiveLeavesUpdate, ChainApiError,
SubsystemSender,
};
use polkadot_node_subsystem_util::runtime::{get_candidate_events, get_on_chain_votes};
use polkadot_primitives::v2::{
@@ -81,10 +82,13 @@ impl ChainScraper {
/// Create a properly initialized `OrderingProvider`.
///
/// Returns: `Self` and any scraped votes.
pub async fn new<Sender: SubsystemSender>(
pub async fn new<Sender>(
sender: &mut Sender,
initial_head: ActivatedLeaf,
) -> Result<(Self, Vec<ScrapedOnChainVotes>)> {
) -> Result<(Self, Vec<ScrapedOnChainVotes>)>
where
Sender: overseer::DisputeCoordinatorSenderTrait,
{
let mut s = Self {
included_candidates: HashSet::new(),
candidates_by_block_number: BTreeMap::new(),
@@ -106,11 +110,14 @@ impl ChainScraper {
/// and updates current heads, so we can query candidates for all non finalized blocks.
///
/// Returns: On chain vote for the leaf and any ancestors we might not yet have seen.
pub async fn process_active_leaves_update<Sender: SubsystemSender>(
pub async fn process_active_leaves_update<Sender>(
&mut self,
sender: &mut Sender,
update: &ActiveLeavesUpdate,
) -> crate::error::Result<Vec<ScrapedOnChainVotes>> {
) -> crate::error::Result<Vec<ScrapedOnChainVotes>>
where
Sender: overseer::DisputeCoordinatorSenderTrait,
{
let activated = match update.activated.as_ref() {
Some(activated) => activated,
None => return Ok(Vec::new()),
@@ -160,12 +167,15 @@ impl ChainScraper {
/// Process candidate events of a block.
///
/// Keep track of all included candidates.
async fn process_candidate_events(
async fn process_candidate_events<Sender>(
&mut self,
sender: &mut impl SubsystemSender,
sender: &mut Sender,
block_number: BlockNumber,
block_hash: Hash,
) -> Result<()> {
) -> Result<()>
where
Sender: overseer::DisputeCoordinatorSenderTrait,
{
// Get included events:
let included =
get_candidate_events(sender, block_hash)
@@ -196,12 +206,15 @@ impl ChainScraper {
/// either at the block present in cache or at the last finalized block.
///
/// Both `head` and the latest finalized block are **not** included in the result.
async fn get_unfinalized_block_ancestors<Sender: SubsystemSender>(
async fn get_unfinalized_block_ancestors<Sender>(
&mut self,
sender: &mut Sender,
mut head: Hash,
mut head_number: BlockNumber,
) -> Result<Vec<Hash>> {
) -> Result<Vec<Hash>>
where
Sender: overseer::DisputeCoordinatorSenderTrait,
{
let target_ancestor = get_finalized_block_number(sender).await?;
let mut ancestors = Vec::new();
@@ -256,26 +269,29 @@ impl ChainScraper {
}
}
async fn get_finalized_block_number(sender: &mut impl SubsystemSender) -> FatalResult<BlockNumber> {
async fn get_finalized_block_number<Sender>(sender: &mut Sender) -> FatalResult<BlockNumber>
where
Sender: overseer::DisputeCoordinatorSenderTrait,
{
let (number_tx, number_rx) = oneshot::channel();
send_message_fatal(sender, ChainApiMessage::FinalizedBlockNumber(number_tx), number_rx).await
}
async fn get_block_ancestors(
sender: &mut impl SubsystemSender,
async fn get_block_ancestors<Sender>(
sender: &mut Sender,
head: Hash,
num_ancestors: BlockNumber,
) -> FatalResult<Vec<Hash>> {
) -> FatalResult<Vec<Hash>>
where
Sender: overseer::DisputeCoordinatorSenderTrait,
{
let (tx, rx) = oneshot::channel();
sender
.send_message(
ChainApiMessage::Ancestors {
hash: head,
k: num_ancestors as usize,
response_channel: tx,
}
.into(),
)
.send_message(ChainApiMessage::Ancestors {
hash: head,
k: num_ancestors as usize,
response_channel: tx,
})
.await;
rx.await
@@ -289,9 +305,9 @@ async fn send_message_fatal<Sender, Response>(
receiver: oneshot::Receiver<std::result::Result<Response, ChainApiError>>,
) -> FatalResult<Response>
where
Sender: SubsystemSender,
Sender: SubsystemSender<ChainApiMessage>,
{
sender.send_message(message.into()).await;
sender.send_message(message).await;
receiver
.await
+40 -36
View File
@@ -32,7 +32,7 @@ use polkadot_node_subsystem::{
CandidateBackingMessage, ChainApiMessage, DisputeCoordinatorMessage, ProvisionableData,
ProvisionerInherentData, ProvisionerMessage,
},
ActivatedLeaf, LeafStatus, PerLeafSpan, SubsystemSender,
overseer, ActivatedLeaf, LeafStatus, PerLeafSpan,
};
use polkadot_node_subsystem_util::{
request_availability_cores, request_persisted_validation_data, JobSender, JobSubsystem,
@@ -95,8 +95,12 @@ impl InherentAfter {
}
}
/// Provisioner run arguments.
#[derive(Debug, Clone, Copy)]
pub struct ProvisionerConfig;
/// A per-relay-parent job for the provisioning subsystem.
pub struct ProvisionerJob {
pub struct ProvisionerJob<Sender> {
leaf: ActivatedLeaf,
receiver: mpsc::Receiver<ProvisionerMessage>,
backed_candidates: Vec<CandidateReceipt>,
@@ -104,14 +108,16 @@ pub struct ProvisionerJob {
metrics: Metrics,
inherent_after: InherentAfter,
awaiting_inherent: Vec<oneshot::Sender<ProvisionerInherentData>>,
_phantom: std::marker::PhantomData<Sender>,
}
/// Provisioner run arguments.
#[derive(Debug, Clone, Copy)]
pub struct ProvisionerConfig;
impl JobTrait for ProvisionerJob {
impl<Sender> JobTrait for ProvisionerJob<Sender>
where
Sender: overseer::ProvisionerSenderTrait + std::marker::Unpin,
{
type ToJob = ProvisionerMessage;
type OutgoingMessages = overseer::ProvisionerOutgoingMessages;
type Sender = Sender;
type Error = Error;
type RunArgs = ProvisionerConfig;
type Metrics = Metrics;
@@ -121,12 +127,12 @@ impl JobTrait for ProvisionerJob {
/// Run a job for the parent block indicated
//
// this function is in charge of creating and executing the job's main loop
fn run<S: SubsystemSender>(
fn run(
leaf: ActivatedLeaf,
_: Self::RunArgs,
metrics: Self::Metrics,
receiver: mpsc::Receiver<ProvisionerMessage>,
mut sender: JobSender<S>,
mut sender: JobSender<Sender>,
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send>> {
let span = leaf.span.clone();
async move {
@@ -139,7 +145,10 @@ impl JobTrait for ProvisionerJob {
}
}
impl ProvisionerJob {
impl<Sender> ProvisionerJob<Sender>
where
Sender: overseer::ProvisionerSenderTrait,
{
fn new(
leaf: ActivatedLeaf,
metrics: Metrics,
@@ -153,14 +162,11 @@ impl ProvisionerJob {
metrics,
inherent_after: InherentAfter::new_from_now(),
awaiting_inherent: Vec::new(),
_phantom: std::marker::PhantomData::<Sender>::default(),
}
}
async fn run_loop(
mut self,
sender: &mut impl SubsystemSender,
span: PerLeafSpan,
) -> Result<(), Error> {
async fn run_loop(mut self, sender: &mut Sender, span: PerLeafSpan) -> Result<(), Error> {
loop {
futures::select! {
msg = self.receiver.next() => match msg {
@@ -197,7 +203,7 @@ impl ProvisionerJob {
async fn send_inherent_data(
&mut self,
sender: &mut impl SubsystemSender,
sender: &mut Sender,
return_senders: Vec<oneshot::Sender<ProvisionerInherentData>>,
) {
if let Err(err) = send_inherent_data(
@@ -275,7 +281,7 @@ async fn send_inherent_data(
bitfields: &[SignedAvailabilityBitfield],
candidates: &[CandidateReceipt],
return_senders: Vec<oneshot::Sender<ProvisionerInherentData>>,
from_job: &mut impl SubsystemSender,
from_job: &mut impl overseer::ProvisionerSenderTrait,
metrics: &Metrics,
) -> Result<(), Error> {
let availability_cores = request_availability_cores(leaf.hash, from_job)
@@ -394,7 +400,7 @@ async fn select_candidates(
bitfields: &[SignedAvailabilityBitfield],
candidates: &[CandidateReceipt],
relay_parent: Hash,
sender: &mut impl SubsystemSender,
sender: &mut impl overseer::ProvisionerSenderTrait,
) -> Result<Vec<BackedCandidate>, Error> {
let block_number = get_block_number_under_construction(relay_parent, sender).await?;
@@ -472,14 +478,11 @@ async fn select_candidates(
// now get the backed candidates corresponding to these candidate receipts
let (tx, rx) = oneshot::channel();
sender
.send_message(
CandidateBackingMessage::GetBackedCandidates(
relay_parent,
selected_candidates.clone(),
tx,
)
.into(),
)
.send_message(CandidateBackingMessage::GetBackedCandidates(
relay_parent,
selected_candidates.clone(),
tx,
))
.await;
let mut candidates = rx.await.map_err(|err| Error::CanceledBackedCandidates(err))?;
@@ -530,10 +533,10 @@ async fn select_candidates(
/// in the event of an invalid `relay_parent`, returns `Ok(0)`
async fn get_block_number_under_construction(
relay_parent: Hash,
sender: &mut impl SubsystemSender,
sender: &mut impl overseer::ProvisionerSenderTrait,
) -> Result<BlockNumber, Error> {
let (tx, rx) = oneshot::channel();
sender.send_message(ChainApiMessage::BlockNumber(relay_parent, tx).into()).await;
sender.send_message(ChainApiMessage::BlockNumber(relay_parent, tx)).await;
match rx.await.map_err(|err| Error::CanceledBlockNumber(err))? {
Ok(Some(n)) => Ok(n + 1),
@@ -591,7 +594,7 @@ enum RequestType {
/// Request open disputes identified by `CandidateHash` and the `SessionIndex`.
async fn request_disputes(
sender: &mut impl SubsystemSender,
sender: &mut impl overseer::ProvisionerSenderTrait,
active_or_recent: RequestType,
) -> Vec<(SessionIndex, CandidateHash)> {
let (tx, rx) = oneshot::channel();
@@ -600,7 +603,7 @@ async fn request_disputes(
RequestType::Active => DisputeCoordinatorMessage::ActiveDisputes(tx),
};
// Bounded by block production - `ProvisionerMessage::RequestInherentData`.
sender.send_unbounded_message(msg.into());
sender.send_unbounded_message(msg);
let recent_disputes = match rx.await {
Ok(r) => r,
@@ -614,14 +617,15 @@ async fn request_disputes(
/// Request the relevant dispute statements for a set of disputes identified by `CandidateHash` and the `SessionIndex`.
async fn request_votes(
sender: &mut impl SubsystemSender,
sender: &mut impl overseer::ProvisionerSenderTrait,
disputes_to_query: Vec<(SessionIndex, CandidateHash)>,
) -> Vec<(SessionIndex, CandidateHash, CandidateVotes)> {
let (tx, rx) = oneshot::channel();
// Bounded by block production - `ProvisionerMessage::RequestInherentData`.
sender.send_unbounded_message(
DisputeCoordinatorMessage::QueryCandidateVotes(disputes_to_query, tx).into(),
);
sender.send_unbounded_message(DisputeCoordinatorMessage::QueryCandidateVotes(
disputes_to_query,
tx,
));
match rx.await {
Ok(v) => v,
@@ -665,7 +669,7 @@ fn extend_by_random_subset_without_repetition(
const MAX_DISPUTES_FORWARDED_TO_RUNTIME: usize = 1_000;
async fn select_disputes(
sender: &mut impl SubsystemSender,
sender: &mut impl overseer::ProvisionerSenderTrait,
metrics: &metrics::Metrics,
_leaf: &ActivatedLeaf,
) -> Result<MultiDisputeStatementSet, Error> {
@@ -804,4 +808,4 @@ async fn select_disputes(
}
/// The provisioner subsystem.
pub type ProvisionerSubsystem<Spawner> = JobSubsystem<ProvisionerJob, Spawner>;
pub type ProvisionerSubsystem<Spawner, Sender> = JobSubsystem<ProvisionerJob<Sender>, Spawner>;
@@ -15,14 +15,17 @@
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
use crate::error::GetOnchainDisputesError;
use polkadot_node_subsystem::SubsystemSender;
use polkadot_node_subsystem::overseer;
use polkadot_primitives::v2::{CandidateHash, DisputeState, Hash, SessionIndex};
use std::collections::HashMap;
pub async fn get_onchain_disputes(
_sender: &mut impl SubsystemSender,
pub async fn get_onchain_disputes<Sender>(
_sender: &mut Sender,
_relay_parent: Hash,
) -> Result<HashMap<(SessionIndex, CandidateHash), DisputeState>, GetOnchainDisputesError> {
) -> Result<HashMap<(SessionIndex, CandidateHash), DisputeState>, GetOnchainDisputesError>
where
Sender: overseer::ProvisionerSenderTrait,
{
let _onchain = Result::<
HashMap<(SessionIndex, CandidateHash), DisputeState>,
GetOnchainDisputesError,
@@ -46,8 +49,8 @@ mod staging_impl {
};
/// Gets the on-chain disputes at a given block number and returns them as a `HashSet` so that searching in them is cheap.
pub async fn get_onchain_disputes(
sender: &mut impl SubsystemSender,
pub async fn get_onchain_disputes<Sender>(
sender: &mut Sender,
relay_parent: Hash,
) -> Result<HashMap<(SessionIndex, CandidateHash), DisputeState>, GetOnchainDisputesError> {
gum::trace!(target: LOG_TARGET, ?relay_parent, "Fetching on-chain disputes");
+15 -23
View File
@@ -22,9 +22,9 @@
use futures::{channel::oneshot, future::BoxFuture, prelude::*, stream::FuturesUnordered};
use polkadot_node_subsystem::{
messages::{CandidateValidationMessage, PreCheckOutcome, PvfCheckerMessage},
overseer, ActiveLeavesUpdate, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemContext,
SubsystemError, SubsystemResult, SubsystemSender,
messages::{CandidateValidationMessage, PreCheckOutcome, PvfCheckerMessage, RuntimeApiMessage},
overseer, ActiveLeavesUpdate, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemError,
SubsystemResult, SubsystemSender,
};
use polkadot_primitives::v2::{
BlockNumber, Hash, PvfCheckStatement, SessionIndex, ValidationCodeHash, ValidatorId,
@@ -60,11 +60,8 @@ impl PvfCheckerSubsystem {
}
}
impl<Context> overseer::Subsystem<Context, SubsystemError> for PvfCheckerSubsystem
where
Context: SubsystemContext<Message = PvfCheckerMessage>,
Context: overseer::SubsystemContext<Message = PvfCheckerMessage>,
{
#[overseer::subsystem(PvfChecker, error=SubsystemError, prefix = self::overseer)]
impl<Context> PvfCheckerSubsystem {
fn start(self, ctx: Context) -> SpawnedSubsystem {
if self.enabled {
let future = run(ctx, self.keystore, self.metrics)
@@ -123,15 +120,12 @@ struct State {
FuturesUnordered<BoxFuture<'static, Option<(PreCheckOutcome, ValidationCodeHash)>>>,
}
#[overseer::contextbounds(PvfChecker, prefix = self::overseer)]
async fn run<Context>(
mut ctx: Context,
keystore: SyncCryptoStorePtr,
metrics: Metrics,
) -> SubsystemResult<()>
where
Context: SubsystemContext<Message = PvfCheckerMessage>,
Context: overseer::SubsystemContext<Message = PvfCheckerMessage>,
{
) -> SubsystemResult<()> {
let mut state = State {
credentials: None,
recent_block: None,
@@ -179,7 +173,7 @@ where
/// Handle an incoming PVF pre-check result from the candidate-validation subsystem.
async fn handle_pvf_check(
state: &mut State,
sender: &mut impl SubsystemSender,
sender: &mut impl overseer::PvfCheckerSenderTrait,
keystore: &SyncCryptoStorePtr,
metrics: &Metrics,
outcome: PreCheckOutcome,
@@ -247,7 +241,7 @@ struct Conclude;
async fn handle_from_overseer(
state: &mut State,
sender: &mut impl SubsystemSender,
sender: &mut impl overseer::PvfCheckerSenderTrait,
keystore: &SyncCryptoStorePtr,
metrics: &Metrics,
from_overseer: FromOverseer<PvfCheckerMessage>,
@@ -273,7 +267,7 @@ async fn handle_from_overseer(
async fn handle_leaves_update(
state: &mut State,
sender: &mut impl SubsystemSender,
sender: &mut impl overseer::PvfCheckerSenderTrait,
keystore: &SyncCryptoStorePtr,
metrics: &Metrics,
update: ActiveLeavesUpdate,
@@ -355,7 +349,7 @@ struct ActivationEffect {
/// Returns `None` if the PVF pre-checking runtime API is not supported for the given leaf hash.
async fn examine_activation(
state: &mut State,
sender: &mut impl SubsystemSender,
sender: &mut impl overseer::PvfCheckerSenderTrait,
keystore: &SyncCryptoStorePtr,
leaf_hash: Hash,
leaf_number: BlockNumber,
@@ -414,7 +408,7 @@ async fn examine_activation(
/// Checks the active validators for the given leaf. If we have a signing key for one of them,
/// returns the [`SigningCredentials`].
async fn check_signing_credentials(
sender: &mut impl SubsystemSender,
sender: &mut impl SubsystemSender<RuntimeApiMessage>,
keystore: &SyncCryptoStorePtr,
leaf: Hash,
) -> Option<SigningCredentials> {
@@ -443,7 +437,7 @@ async fn check_signing_credentials(
///
/// If the validator already voted for the given code, this function does nothing.
async fn sign_and_submit_pvf_check_statement(
sender: &mut impl SubsystemSender,
sender: &mut impl overseer::PvfCheckerSenderTrait,
keystore: &SyncCryptoStorePtr,
voted: &mut HashSet<ValidationCodeHash>,
credentials: &SigningCredentials,
@@ -535,7 +529,7 @@ async fn sign_and_submit_pvf_check_statement(
/// into the `currently_checking` set.
async fn initiate_precheck(
state: &mut State,
sender: &mut impl SubsystemSender,
sender: &mut impl overseer::PvfCheckerSenderTrait,
relay_parent: Hash,
validation_code_hash: ValidationCodeHash,
metrics: &Metrics,
@@ -544,9 +538,7 @@ async fn initiate_precheck(
let (tx, rx) = oneshot::channel();
sender
.send_message(
CandidateValidationMessage::PreCheck(relay_parent, validation_code_hash, tx).into(),
)
.send_message(CandidateValidationMessage::PreCheck(relay_parent, validation_code_hash, tx))
.await;
let timer = metrics.time_pre_check_judgement();
@@ -26,7 +26,7 @@ use polkadot_primitives::v2::{
};
pub(crate) async fn session_index_for_child(
sender: &mut impl SubsystemSender,
sender: &mut impl SubsystemSender<RuntimeApiMessage>,
relay_parent: Hash,
) -> Result<SessionIndex, RuntimeRequestError> {
let (tx, rx) = oneshot::channel();
@@ -34,7 +34,7 @@ pub(crate) async fn session_index_for_child(
}
pub(crate) async fn validators(
sender: &mut impl SubsystemSender,
sender: &mut impl SubsystemSender<RuntimeApiMessage>,
relay_parent: Hash,
) -> Result<Vec<ValidatorId>, RuntimeRequestError> {
let (tx, rx) = oneshot::channel();
@@ -42,7 +42,7 @@ pub(crate) async fn validators(
}
pub(crate) async fn submit_pvf_check_statement(
sender: &mut impl SubsystemSender,
sender: &mut impl SubsystemSender<RuntimeApiMessage>,
relay_parent: Hash,
stmt: PvfCheckStatement,
signature: ValidatorSignature,
@@ -58,7 +58,7 @@ pub(crate) async fn submit_pvf_check_statement(
}
pub(crate) async fn pvfs_require_precheck(
sender: &mut impl SubsystemSender,
sender: &mut impl SubsystemSender<RuntimeApiMessage>,
relay_parent: Hash,
) -> Result<Vec<ValidationCodeHash>, RuntimeRequestError> {
let (tx, rx) = oneshot::channel();
@@ -73,7 +73,7 @@ pub(crate) enum RuntimeRequestError {
}
pub(crate) async fn runtime_api_request<T>(
sender: &mut impl SubsystemSender,
sender: &mut impl SubsystemSender<RuntimeApiMessage>,
relay_parent: Hash,
request: RuntimeApiRequest,
receiver: oneshot::Receiver<Result<T, RuntimeApiSubsystemError>>,
+4 -7
View File
@@ -25,8 +25,7 @@
use polkadot_node_subsystem::{
errors::RuntimeApiError,
messages::{RuntimeApiMessage, RuntimeApiRequest as Request},
overseer, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemContext, SubsystemError,
SubsystemResult,
overseer, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemError, SubsystemResult,
};
use polkadot_primitives::{
runtime_api::ParachainHost,
@@ -92,12 +91,11 @@ impl<Client> RuntimeApiSubsystem<Client> {
}
}
impl<Client, Context> overseer::Subsystem<Context, SubsystemError> for RuntimeApiSubsystem<Client>
#[overseer::subsystem(RuntimeApi, error = SubsystemError, prefix = self::overseer)]
impl<Client, Context> RuntimeApiSubsystem<Client>
where
Client: ProvideRuntimeApi<Block> + Send + 'static + Sync,
Client::Api: ParachainHost<Block> + BabeApi<Block> + AuthorityDiscoveryApi<Block>,
Context: SubsystemContext<Message = RuntimeApiMessage>,
Context: overseer::SubsystemContext<Message = RuntimeApiMessage>,
{
fn start(self, ctx: Context) -> SpawnedSubsystem {
SpawnedSubsystem { future: run(ctx, self).boxed(), name: "runtime-api-subsystem" }
@@ -333,6 +331,7 @@ where
}
}
#[overseer::contextbounds(RuntimeApi, prefix = self::overseer)]
async fn run<Client, Context>(
mut ctx: Context,
mut subsystem: RuntimeApiSubsystem<Client>,
@@ -340,8 +339,6 @@ async fn run<Client, Context>(
where
Client: ProvideRuntimeApi<Block> + Send + Sync + 'static,
Client::Api: ParachainHost<Block> + BabeApi<Block> + AuthorityDiscoveryApi<Block>,
Context: SubsystemContext<Message = RuntimeApiMessage>,
Context: overseer::SubsystemContext<Message = RuntimeApiMessage>,
{
loop {
select! {