mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 14:01:06 +00:00
refactor+feat: allow subsystems to send only declared messages, generate graphviz (#5314)
Closes #3774 Closes #3826
This commit is contained in:
committed by
GitHub
parent
26340b9054
commit
511891dcce
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(())
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) =
|
||||
|
||||
@@ -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? {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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>>,
|
||||
|
||||
@@ -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! {
|
||||
|
||||
Reference in New Issue
Block a user