mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 15:51:12 +00:00
Simplify subsystem jobs (#2037)
* Simplify subsystem jobs This pr simplifies the subsystem jobs interface. Instead of requiring an extra message that is used to signal that a job should be ended, a job now ends when the receiver returns `None`. Besides that it changes the interface to enforce that messages to a job provide a relay parent. * Drop ToJobTrait * Remove FromJob We always convert this message to FromJobCommand anyway.
This commit is contained in:
@@ -40,8 +40,7 @@ use polkadot_subsystem::{
|
||||
messages::{
|
||||
AllMessages, AvailabilityStoreMessage, CandidateBackingMessage, CandidateSelectionMessage,
|
||||
CandidateValidationMessage, NewBackedCandidate, PoVDistributionMessage, ProvisionableData,
|
||||
ProvisionerMessage, RuntimeApiMessage, StatementDistributionMessage, ValidationFailed,
|
||||
RuntimeApiRequest,
|
||||
ProvisionerMessage, StatementDistributionMessage, ValidationFailed, RuntimeApiRequest,
|
||||
},
|
||||
};
|
||||
use polkadot_node_subsystem_util::{
|
||||
@@ -93,9 +92,9 @@ struct CandidateBackingJob {
|
||||
/// The hash of the relay parent on top of which this job is doing it's work.
|
||||
parent: Hash,
|
||||
/// Inbound message channel receiving part.
|
||||
rx_to: mpsc::Receiver<ToJob>,
|
||||
rx_to: mpsc::Receiver<CandidateBackingMessage>,
|
||||
/// Outbound message channel sending part.
|
||||
tx_from: mpsc::Sender<FromJob>,
|
||||
tx_from: mpsc::Sender<FromJobCommand>,
|
||||
/// The `ParaId` assigned to this validator
|
||||
assignment: ParaId,
|
||||
/// The collator required to author the candidate, if any.
|
||||
@@ -151,84 +150,6 @@ impl TableContextTrait for TableContext {
|
||||
}
|
||||
}
|
||||
|
||||
/// A message type that is sent from `CandidateBackingSubsystem` to `CandidateBackingJob`.
|
||||
pub enum ToJob {
|
||||
/// A `CandidateBackingMessage`.
|
||||
CandidateBacking(CandidateBackingMessage),
|
||||
/// Stop working.
|
||||
Stop,
|
||||
}
|
||||
|
||||
impl TryFrom<AllMessages> for ToJob {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(msg: AllMessages) -> Result<Self, Self::Error> {
|
||||
match msg {
|
||||
AllMessages::CandidateBacking(msg) => Ok(ToJob::CandidateBacking(msg)),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CandidateBackingMessage> for ToJob {
|
||||
fn from(msg: CandidateBackingMessage) -> Self {
|
||||
Self::CandidateBacking(msg)
|
||||
}
|
||||
}
|
||||
|
||||
impl util::ToJobTrait for ToJob {
|
||||
const STOP: Self = ToJob::Stop;
|
||||
|
||||
fn relay_parent(&self) -> Option<Hash> {
|
||||
match self {
|
||||
Self::CandidateBacking(cb) => cb.relay_parent(),
|
||||
Self::Stop => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A message type that is sent from `CandidateBackingJob` to `CandidateBackingSubsystem`.
|
||||
enum FromJob {
|
||||
AvailabilityStore(AvailabilityStoreMessage),
|
||||
RuntimeApiMessage(RuntimeApiMessage),
|
||||
CandidateValidation(CandidateValidationMessage),
|
||||
CandidateSelection(CandidateSelectionMessage),
|
||||
Provisioner(ProvisionerMessage),
|
||||
PoVDistribution(PoVDistributionMessage),
|
||||
StatementDistribution(StatementDistributionMessage),
|
||||
}
|
||||
|
||||
impl From<FromJob> for FromJobCommand {
|
||||
fn from(f: FromJob) -> FromJobCommand {
|
||||
FromJobCommand::SendMessage(match f {
|
||||
FromJob::AvailabilityStore(msg) => AllMessages::AvailabilityStore(msg),
|
||||
FromJob::RuntimeApiMessage(msg) => AllMessages::RuntimeApi(msg),
|
||||
FromJob::CandidateValidation(msg) => AllMessages::CandidateValidation(msg),
|
||||
FromJob::CandidateSelection(msg) => AllMessages::CandidateSelection(msg),
|
||||
FromJob::StatementDistribution(msg) => AllMessages::StatementDistribution(msg),
|
||||
FromJob::PoVDistribution(msg) => AllMessages::PoVDistribution(msg),
|
||||
FromJob::Provisioner(msg) => AllMessages::Provisioner(msg),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<AllMessages> for FromJob {
|
||||
type Error = &'static str;
|
||||
|
||||
fn try_from(f: AllMessages) -> Result<Self, Self::Error> {
|
||||
match f {
|
||||
AllMessages::AvailabilityStore(msg) => Ok(FromJob::AvailabilityStore(msg)),
|
||||
AllMessages::RuntimeApi(msg) => Ok(FromJob::RuntimeApiMessage(msg)),
|
||||
AllMessages::CandidateValidation(msg) => Ok(FromJob::CandidateValidation(msg)),
|
||||
AllMessages::CandidateSelection(msg) => Ok(FromJob::CandidateSelection(msg)),
|
||||
AllMessages::StatementDistribution(msg) => Ok(FromJob::StatementDistribution(msg)),
|
||||
AllMessages::PoVDistribution(msg) => Ok(FromJob::PoVDistribution(msg)),
|
||||
AllMessages::Provisioner(msg) => Ok(FromJob::Provisioner(msg)),
|
||||
_ => Err("can't convert this AllMessages variant to FromJob"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct InvalidErasureRoot;
|
||||
|
||||
// It looks like it's not possible to do an `impl From` given the current state of
|
||||
@@ -301,12 +222,10 @@ fn table_attested_to_backed(
|
||||
impl CandidateBackingJob {
|
||||
/// Run asynchronously.
|
||||
async fn run_loop(mut self) -> Result<(), Error> {
|
||||
while let Some(msg) = self.rx_to.next().await {
|
||||
match msg {
|
||||
ToJob::CandidateBacking(msg) => {
|
||||
self.process_msg(msg).await?;
|
||||
}
|
||||
ToJob::Stop => break,
|
||||
loop {
|
||||
match self.rx_to.next().await {
|
||||
Some(msg) => self.process_msg(msg).await?,
|
||||
None => break,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -317,9 +236,7 @@ impl CandidateBackingJob {
|
||||
&mut self,
|
||||
candidate: CandidateReceipt,
|
||||
) -> Result<(), Error> {
|
||||
self.tx_from.send(FromJob::CandidateSelection(
|
||||
CandidateSelectionMessage::Invalid(self.parent, candidate)
|
||||
)).await?;
|
||||
self.tx_from.send(AllMessages::from(CandidateSelectionMessage::Invalid(self.parent, candidate)).into()).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -664,7 +581,7 @@ impl CandidateBackingJob {
|
||||
}
|
||||
|
||||
async fn send_to_provisioner(&mut self, msg: ProvisionerMessage) -> Result<(), Error> {
|
||||
self.tx_from.send(FromJob::Provisioner(msg)).await?;
|
||||
self.tx_from.send(AllMessages::from(msg).into()).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -674,9 +591,9 @@ impl CandidateBackingJob {
|
||||
descriptor: CandidateDescriptor,
|
||||
pov: Arc<PoV>,
|
||||
) -> Result<(), Error> {
|
||||
self.tx_from.send(FromJob::PoVDistribution(
|
||||
self.tx_from.send(AllMessages::from(
|
||||
PoVDistributionMessage::DistributePoV(self.parent, descriptor, pov),
|
||||
)).await.map_err(Into::into)
|
||||
).into()).await.map_err(Into::into)
|
||||
}
|
||||
|
||||
async fn request_pov_from_distribution(
|
||||
@@ -685,9 +602,9 @@ impl CandidateBackingJob {
|
||||
) -> Result<Arc<PoV>, Error> {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
|
||||
self.tx_from.send(FromJob::PoVDistribution(
|
||||
self.tx_from.send(AllMessages::from(
|
||||
PoVDistributionMessage::FetchPoV(self.parent, descriptor, tx)
|
||||
)).await?;
|
||||
).into()).await?;
|
||||
|
||||
Ok(rx.await?)
|
||||
}
|
||||
@@ -699,13 +616,14 @@ impl CandidateBackingJob {
|
||||
) -> Result<ValidationResult, Error> {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
|
||||
self.tx_from.send(FromJob::CandidateValidation(
|
||||
self.tx_from.send(
|
||||
AllMessages::from(
|
||||
CandidateValidationMessage::ValidateFromChainState(
|
||||
candidate,
|
||||
pov,
|
||||
tx,
|
||||
)
|
||||
)
|
||||
).into(),
|
||||
).await?;
|
||||
|
||||
Ok(rx.await??)
|
||||
@@ -719,7 +637,7 @@ impl CandidateBackingJob {
|
||||
available_data: AvailableData,
|
||||
) -> Result<(), Error> {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
self.tx_from.send(FromJob::AvailabilityStore(
|
||||
self.tx_from.send(AllMessages::from(
|
||||
AvailabilityStoreMessage::StoreAvailableData(
|
||||
candidate_hash,
|
||||
id,
|
||||
@@ -727,7 +645,7 @@ impl CandidateBackingJob {
|
||||
available_data,
|
||||
tx,
|
||||
)
|
||||
)
|
||||
).into(),
|
||||
).await?;
|
||||
|
||||
let _ = rx.await?;
|
||||
@@ -777,15 +695,14 @@ impl CandidateBackingJob {
|
||||
async fn distribute_signed_statement(&mut self, s: SignedFullStatement) -> Result<(), Error> {
|
||||
let smsg = StatementDistributionMessage::Share(self.parent, s);
|
||||
|
||||
self.tx_from.send(FromJob::StatementDistribution(smsg)).await?;
|
||||
self.tx_from.send(AllMessages::from(smsg).into()).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl util::JobTrait for CandidateBackingJob {
|
||||
type ToJob = ToJob;
|
||||
type FromJob = FromJob;
|
||||
type ToJob = CandidateBackingMessage;
|
||||
type Error = Error;
|
||||
type RunArgs = SyncCryptoStorePtr;
|
||||
type Metrics = Metrics;
|
||||
@@ -798,7 +715,7 @@ impl util::JobTrait for CandidateBackingJob {
|
||||
keystore: SyncCryptoStorePtr,
|
||||
metrics: Metrics,
|
||||
rx_to: mpsc::Receiver<Self::ToJob>,
|
||||
mut tx_from: mpsc::Sender<Self::FromJob>,
|
||||
mut tx_from: mpsc::Sender<FromJobCommand>,
|
||||
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send>> {
|
||||
async move {
|
||||
macro_rules! try_runtime_api {
|
||||
@@ -1000,7 +917,7 @@ impl metrics::Metrics for Metrics {
|
||||
}
|
||||
}
|
||||
|
||||
delegated_subsystem!(CandidateBackingJob(SyncCryptoStorePtr, Metrics) <- ToJob as CandidateBackingSubsystem);
|
||||
delegated_subsystem!(CandidateBackingJob(SyncCryptoStorePtr, Metrics) <- CandidateBackingMessage as CandidateBackingSubsystem);
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
@@ -1013,7 +930,7 @@ mod tests {
|
||||
GroupRotationInfo,
|
||||
};
|
||||
use polkadot_subsystem::{
|
||||
messages::RuntimeApiRequest,
|
||||
messages::{RuntimeApiRequest, RuntimeApiMessage},
|
||||
ActiveLeavesUpdate, FromOverseer, OverseerSignal,
|
||||
};
|
||||
use polkadot_node_primitives::InvalidCandidate;
|
||||
|
||||
@@ -14,4 +14,3 @@ polkadot-node-subsystem-util = { path = "../../subsystem-util" }
|
||||
sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
wasm-timer = "0.2.5"
|
||||
thiserror = "1.0.22"
|
||||
derive_more = "0.99.11"
|
||||
|
||||
@@ -25,16 +25,15 @@ use sp_keystore::{Error as KeystoreError, SyncCryptoStorePtr};
|
||||
use polkadot_node_subsystem::{
|
||||
messages::{
|
||||
AllMessages, AvailabilityStoreMessage, BitfieldDistributionMessage,
|
||||
BitfieldSigningMessage, CandidateBackingMessage, RuntimeApiMessage, RuntimeApiRequest,
|
||||
BitfieldSigningMessage, RuntimeApiMessage, RuntimeApiRequest,
|
||||
},
|
||||
errors::RuntimeApiError,
|
||||
};
|
||||
use polkadot_node_subsystem_util::{
|
||||
self as util, JobManager, JobTrait, ToJobTrait, Validator, FromJobCommand,
|
||||
metrics::{self, prometheus},
|
||||
self as util, JobManager, JobTrait, Validator, FromJobCommand, metrics::{self, prometheus},
|
||||
};
|
||||
use polkadot_primitives::v1::{AvailabilityBitfield, CoreState, Hash, ValidatorIndex};
|
||||
use std::{convert::TryFrom, pin::Pin, time::Duration, iter::FromIterator};
|
||||
use std::{pin::Pin, time::Duration, iter::FromIterator};
|
||||
use wasm_timer::{Delay, Instant};
|
||||
use thiserror::Error;
|
||||
|
||||
@@ -45,76 +44,6 @@ const LOG_TARGET: &str = "bitfield_signing";
|
||||
/// Each `BitfieldSigningJob` prepares a signed bitfield for a single relay parent.
|
||||
pub struct BitfieldSigningJob;
|
||||
|
||||
/// Messages which a `BitfieldSigningJob` is prepared to receive.
|
||||
#[allow(missing_docs)]
|
||||
pub enum ToJob {
|
||||
BitfieldSigning(BitfieldSigningMessage),
|
||||
Stop,
|
||||
}
|
||||
|
||||
impl ToJobTrait for ToJob {
|
||||
const STOP: Self = ToJob::Stop;
|
||||
|
||||
fn relay_parent(&self) -> Option<Hash> {
|
||||
match self {
|
||||
Self::BitfieldSigning(bsm) => bsm.relay_parent(),
|
||||
Self::Stop => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<AllMessages> for ToJob {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(msg: AllMessages) -> Result<Self, Self::Error> {
|
||||
match msg {
|
||||
AllMessages::BitfieldSigning(bsm) => Ok(ToJob::BitfieldSigning(bsm)),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BitfieldSigningMessage> for ToJob {
|
||||
fn from(bsm: BitfieldSigningMessage) -> ToJob {
|
||||
ToJob::BitfieldSigning(bsm)
|
||||
}
|
||||
}
|
||||
|
||||
/// Messages which may be sent from a `BitfieldSigningJob`.
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Debug, derive_more::From)]
|
||||
pub enum FromJob {
|
||||
AvailabilityStore(AvailabilityStoreMessage),
|
||||
BitfieldDistribution(BitfieldDistributionMessage),
|
||||
CandidateBacking(CandidateBackingMessage),
|
||||
RuntimeApi(RuntimeApiMessage),
|
||||
}
|
||||
|
||||
impl From<FromJob> for FromJobCommand {
|
||||
fn from(from_job: FromJob) -> FromJobCommand {
|
||||
FromJobCommand::SendMessage(match from_job {
|
||||
FromJob::AvailabilityStore(asm) => AllMessages::AvailabilityStore(asm),
|
||||
FromJob::BitfieldDistribution(bdm) => AllMessages::BitfieldDistribution(bdm),
|
||||
FromJob::CandidateBacking(cbm) => AllMessages::CandidateBacking(cbm),
|
||||
FromJob::RuntimeApi(ram) => AllMessages::RuntimeApi(ram),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<AllMessages> for FromJob {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(msg: AllMessages) -> Result<Self, Self::Error> {
|
||||
match msg {
|
||||
AllMessages::AvailabilityStore(asm) => Ok(Self::AvailabilityStore(asm)),
|
||||
AllMessages::BitfieldDistribution(bdm) => Ok(Self::BitfieldDistribution(bdm)),
|
||||
AllMessages::CandidateBacking(cbm) => Ok(Self::CandidateBacking(cbm)),
|
||||
AllMessages::RuntimeApi(ram) => Ok(Self::RuntimeApi(ram)),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Errors we may encounter in the course of executing the `BitfieldSigningSubsystem`.
|
||||
#[derive(Debug, Error)]
|
||||
pub enum Error {
|
||||
@@ -145,7 +74,7 @@ async fn get_core_availability(
|
||||
relay_parent: Hash,
|
||||
core: CoreState,
|
||||
validator_idx: ValidatorIndex,
|
||||
sender: &Mutex<&mut mpsc::Sender<FromJob>>,
|
||||
sender: &Mutex<&mut mpsc::Sender<FromJobCommand>>,
|
||||
) -> Result<bool, Error> {
|
||||
if let CoreState::Occupied(core) = core {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
@@ -153,10 +82,10 @@ async fn get_core_availability(
|
||||
.lock()
|
||||
.await
|
||||
.send(
|
||||
RuntimeApiMessage::Request(
|
||||
AllMessages::from(RuntimeApiMessage::Request(
|
||||
relay_parent,
|
||||
RuntimeApiRequest::CandidatePendingAvailability(core.para_id, tx),
|
||||
).into(),
|
||||
)).into(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
@@ -174,11 +103,11 @@ async fn get_core_availability(
|
||||
.lock()
|
||||
.await
|
||||
.send(
|
||||
AvailabilityStoreMessage::QueryChunkAvailability(
|
||||
AllMessages::from(AvailabilityStoreMessage::QueryChunkAvailability(
|
||||
committed_candidate_receipt.hash(),
|
||||
validator_idx,
|
||||
tx,
|
||||
).into(),
|
||||
)).into(),
|
||||
)
|
||||
.await?;
|
||||
return rx.await.map_err(Into::into);
|
||||
@@ -188,9 +117,14 @@ async fn get_core_availability(
|
||||
}
|
||||
|
||||
/// delegates to the v1 runtime API
|
||||
async fn get_availability_cores(relay_parent: Hash, sender: &mut mpsc::Sender<FromJob>) -> Result<Vec<CoreState>, Error> {
|
||||
async fn get_availability_cores(
|
||||
relay_parent: Hash,
|
||||
sender: &mut mpsc::Sender<FromJobCommand>,
|
||||
) -> Result<Vec<CoreState>, Error> {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
sender.send(RuntimeApiMessage::Request(relay_parent, RuntimeApiRequest::AvailabilityCores(tx)).into()).await?;
|
||||
sender
|
||||
.send(AllMessages::from(RuntimeApiMessage::Request(relay_parent, RuntimeApiRequest::AvailabilityCores(tx))).into())
|
||||
.await?;
|
||||
match rx.await {
|
||||
Ok(Ok(out)) => Ok(out),
|
||||
Ok(Err(runtime_err)) => Err(runtime_err.into()),
|
||||
@@ -206,7 +140,7 @@ async fn get_availability_cores(relay_parent: Hash, sender: &mut mpsc::Sender<Fr
|
||||
async fn construct_availability_bitfield(
|
||||
relay_parent: Hash,
|
||||
validator_idx: ValidatorIndex,
|
||||
sender: &mut mpsc::Sender<FromJob>,
|
||||
sender: &mut mpsc::Sender<FromJobCommand>,
|
||||
) -> Result<AvailabilityBitfield, Error> {
|
||||
// get the set of availability cores from the runtime
|
||||
let availability_cores = get_availability_cores(relay_parent, sender).await?;
|
||||
@@ -275,8 +209,7 @@ impl metrics::Metrics for Metrics {
|
||||
}
|
||||
|
||||
impl JobTrait for BitfieldSigningJob {
|
||||
type ToJob = ToJob;
|
||||
type FromJob = FromJob;
|
||||
type ToJob = BitfieldSigningMessage;
|
||||
type Error = Error;
|
||||
type RunArgs = SyncCryptoStorePtr;
|
||||
type Metrics = Metrics;
|
||||
@@ -289,8 +222,8 @@ impl JobTrait for BitfieldSigningJob {
|
||||
relay_parent: Hash,
|
||||
keystore: Self::RunArgs,
|
||||
metrics: Self::Metrics,
|
||||
_receiver: mpsc::Receiver<ToJob>,
|
||||
mut sender: mpsc::Sender<FromJob>,
|
||||
_receiver: mpsc::Receiver<BitfieldSigningMessage>,
|
||||
mut sender: mpsc::Sender<FromJobCommand>,
|
||||
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send>> {
|
||||
let metrics = metrics.clone();
|
||||
async move {
|
||||
@@ -330,7 +263,11 @@ impl JobTrait for BitfieldSigningJob {
|
||||
metrics.on_bitfield_signed();
|
||||
|
||||
sender
|
||||
.send(BitfieldDistributionMessage::DistributeBitfield(relay_parent, signed_bitfield).into())
|
||||
.send(
|
||||
AllMessages::from(
|
||||
BitfieldDistributionMessage::DistributeBitfield(relay_parent, signed_bitfield),
|
||||
).into(),
|
||||
)
|
||||
.await
|
||||
.map_err(Into::into)
|
||||
}
|
||||
@@ -345,8 +282,7 @@ pub type BitfieldSigningSubsystem<Spawner, Context> = JobManager<Spawner, Contex
|
||||
mod tests {
|
||||
use super::*;
|
||||
use futures::{pin_mut, executor::block_on};
|
||||
use polkadot_primitives::v1::{OccupiedCore};
|
||||
use FromJob::*;
|
||||
use polkadot_primitives::v1::OccupiedCore;
|
||||
|
||||
fn occupied_core(para_id: u32) -> CoreState {
|
||||
CoreState::Occupied(OccupiedCore {
|
||||
@@ -373,12 +309,18 @@ mod tests {
|
||||
loop {
|
||||
futures::select! {
|
||||
m = receiver.next() => match m.unwrap() {
|
||||
RuntimeApi(RuntimeApiMessage::Request(rp, RuntimeApiRequest::AvailabilityCores(tx))) => {
|
||||
FromJobCommand::SendMessage(
|
||||
AllMessages::RuntimeApi(
|
||||
RuntimeApiMessage::Request(rp, RuntimeApiRequest::AvailabilityCores(tx)),
|
||||
),
|
||||
) => {
|
||||
assert_eq!(relay_parent, rp);
|
||||
tx.send(Ok(vec![CoreState::Free, occupied_core(1), occupied_core(2)])).unwrap();
|
||||
},
|
||||
RuntimeApi(
|
||||
RuntimeApiMessage::Request(rp, RuntimeApiRequest::CandidatePendingAvailability(para_id, tx))
|
||||
FromJobCommand::SendMessage(
|
||||
AllMessages::RuntimeApi(
|
||||
RuntimeApiMessage::Request(rp, RuntimeApiRequest::CandidatePendingAvailability(para_id, tx)),
|
||||
),
|
||||
) => {
|
||||
assert_eq!(relay_parent, rp);
|
||||
|
||||
@@ -388,7 +330,11 @@ mod tests {
|
||||
tx.send(Ok(None)).unwrap();
|
||||
}
|
||||
},
|
||||
AvailabilityStore(AvailabilityStoreMessage::QueryChunkAvailability(_, vidx, tx)) => {
|
||||
FromJobCommand::SendMessage(
|
||||
AllMessages::AvailabilityStore(
|
||||
AvailabilityStoreMessage::QueryChunkAvailability(_, vidx, tx),
|
||||
),
|
||||
) => {
|
||||
assert_eq!(validator_index, vidx);
|
||||
|
||||
tx.send(true).unwrap();
|
||||
|
||||
@@ -30,86 +30,21 @@ use polkadot_node_subsystem::{
|
||||
},
|
||||
};
|
||||
use polkadot_node_subsystem_util::{
|
||||
self as util, delegated_subsystem, JobTrait, ToJobTrait, FromJobCommand,
|
||||
metrics::{self, prometheus},
|
||||
self as util, delegated_subsystem, JobTrait, FromJobCommand, metrics::{self, prometheus},
|
||||
};
|
||||
use polkadot_primitives::v1::{CandidateReceipt, CollatorId, Hash, Id as ParaId, PoV};
|
||||
use std::{convert::TryFrom, pin::Pin};
|
||||
use std::pin::Pin;
|
||||
use thiserror::Error;
|
||||
|
||||
const LOG_TARGET: &'static str = "candidate_selection";
|
||||
|
||||
struct CandidateSelectionJob {
|
||||
sender: mpsc::Sender<FromJob>,
|
||||
receiver: mpsc::Receiver<ToJob>,
|
||||
sender: mpsc::Sender<FromJobCommand>,
|
||||
receiver: mpsc::Receiver<CandidateSelectionMessage>,
|
||||
metrics: Metrics,
|
||||
seconded_candidate: Option<CollatorId>,
|
||||
}
|
||||
|
||||
/// This enum defines the messages that the provisioner is prepared to receive.
|
||||
#[derive(Debug)]
|
||||
pub enum ToJob {
|
||||
/// The provisioner message is the main input to the provisioner.
|
||||
CandidateSelection(CandidateSelectionMessage),
|
||||
/// This message indicates that the provisioner should shut itself down.
|
||||
Stop,
|
||||
}
|
||||
|
||||
impl ToJobTrait for ToJob {
|
||||
const STOP: Self = Self::Stop;
|
||||
|
||||
fn relay_parent(&self) -> Option<Hash> {
|
||||
match self {
|
||||
Self::CandidateSelection(csm) => csm.relay_parent(),
|
||||
Self::Stop => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<AllMessages> for ToJob {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(msg: AllMessages) -> Result<Self, Self::Error> {
|
||||
match msg {
|
||||
AllMessages::CandidateSelection(csm) => Ok(Self::CandidateSelection(csm)),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CandidateSelectionMessage> for ToJob {
|
||||
fn from(csm: CandidateSelectionMessage) -> Self {
|
||||
Self::CandidateSelection(csm)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum FromJob {
|
||||
Backing(CandidateBackingMessage),
|
||||
Collator(CollatorProtocolMessage),
|
||||
}
|
||||
|
||||
impl From<FromJob> for FromJobCommand {
|
||||
fn from(from_job: FromJob) -> FromJobCommand {
|
||||
FromJobCommand::SendMessage(match from_job {
|
||||
FromJob::Backing(msg) => AllMessages::CandidateBacking(msg),
|
||||
FromJob::Collator(msg) => AllMessages::CollatorProtocol(msg),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<AllMessages> for FromJob {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(msg: AllMessages) -> Result<Self, Self::Error> {
|
||||
match msg {
|
||||
AllMessages::CandidateBacking(msg) => Ok(FromJob::Backing(msg)),
|
||||
AllMessages::CollatorProtocol(msg) => Ok(FromJob::Collator(msg)),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
enum Error {
|
||||
#[error(transparent)]
|
||||
@@ -123,40 +58,32 @@ enum Error {
|
||||
}
|
||||
|
||||
impl JobTrait for CandidateSelectionJob {
|
||||
type ToJob = ToJob;
|
||||
type FromJob = FromJob;
|
||||
type ToJob = CandidateSelectionMessage;
|
||||
type Error = Error;
|
||||
type RunArgs = ();
|
||||
type Metrics = Metrics;
|
||||
|
||||
const NAME: &'static str = "CandidateSelectionJob";
|
||||
|
||||
/// Run a job for the parent block indicated
|
||||
//
|
||||
// this function is in charge of creating and executing the job's main loop
|
||||
#[tracing::instrument(skip(_relay_parent, _run_args, metrics, receiver, sender), fields(subsystem = LOG_TARGET))]
|
||||
fn run(
|
||||
_relay_parent: Hash,
|
||||
_run_args: Self::RunArgs,
|
||||
metrics: Self::Metrics,
|
||||
receiver: mpsc::Receiver<ToJob>,
|
||||
sender: mpsc::Sender<FromJob>,
|
||||
receiver: mpsc::Receiver<CandidateSelectionMessage>,
|
||||
sender: mpsc::Sender<FromJobCommand>,
|
||||
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send>> {
|
||||
Box::pin(async move {
|
||||
let job = CandidateSelectionJob::new(metrics, sender, receiver);
|
||||
|
||||
// it isn't necessary to break run_loop into its own function,
|
||||
// but it's convenient to separate the concerns in this way
|
||||
job.run_loop().await
|
||||
})
|
||||
async move {
|
||||
CandidateSelectionJob::new(metrics, sender, receiver).run_loop().await
|
||||
}.boxed()
|
||||
}
|
||||
}
|
||||
|
||||
impl CandidateSelectionJob {
|
||||
pub fn new(
|
||||
metrics: Metrics,
|
||||
sender: mpsc::Sender<FromJob>,
|
||||
receiver: mpsc::Receiver<ToJob>,
|
||||
sender: mpsc::Sender<FromJobCommand>,
|
||||
receiver: mpsc::Receiver<CandidateSelectionMessage>,
|
||||
) -> Self {
|
||||
Self {
|
||||
sender,
|
||||
@@ -166,28 +93,23 @@ impl CandidateSelectionJob {
|
||||
}
|
||||
}
|
||||
|
||||
async fn run_loop(mut self) -> Result<(), Error> {
|
||||
self.run_loop_borrowed().await
|
||||
}
|
||||
|
||||
/// this function exists for testing and should not generally be used; use `run_loop` instead.
|
||||
async fn run_loop_borrowed(&mut self) -> Result<(), Error> {
|
||||
while let Some(msg) = self.receiver.next().await {
|
||||
match msg {
|
||||
ToJob::CandidateSelection(CandidateSelectionMessage::Collation(
|
||||
async fn run_loop(&mut self) -> Result<(), Error> {
|
||||
loop {
|
||||
match self.receiver.next().await {
|
||||
Some(CandidateSelectionMessage::Collation(
|
||||
relay_parent,
|
||||
para_id,
|
||||
collator_id,
|
||||
)) => {
|
||||
self.handle_collation(relay_parent, para_id, collator_id).await;
|
||||
}
|
||||
ToJob::CandidateSelection(CandidateSelectionMessage::Invalid(
|
||||
Some(CandidateSelectionMessage::Invalid(
|
||||
_,
|
||||
candidate_receipt,
|
||||
)) => {
|
||||
self.handle_invalid(candidate_receipt).await;
|
||||
}
|
||||
ToJob::Stop => break,
|
||||
None => break,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,16 +205,16 @@ async fn get_collation(
|
||||
relay_parent: Hash,
|
||||
para_id: ParaId,
|
||||
collator_id: CollatorId,
|
||||
mut sender: mpsc::Sender<FromJob>,
|
||||
mut sender: mpsc::Sender<FromJobCommand>,
|
||||
) -> Result<(CandidateReceipt, PoV), Error> {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
sender
|
||||
.send(FromJob::Collator(CollatorProtocolMessage::FetchCollation(
|
||||
.send(AllMessages::from(CollatorProtocolMessage::FetchCollation(
|
||||
relay_parent,
|
||||
collator_id,
|
||||
para_id,
|
||||
tx,
|
||||
)))
|
||||
)).into())
|
||||
.await?;
|
||||
rx.await.map_err(Into::into)
|
||||
}
|
||||
@@ -301,15 +223,15 @@ async fn second_candidate(
|
||||
relay_parent: Hash,
|
||||
candidate_receipt: CandidateReceipt,
|
||||
pov: PoV,
|
||||
sender: &mut mpsc::Sender<FromJob>,
|
||||
sender: &mut mpsc::Sender<FromJobCommand>,
|
||||
metrics: &Metrics,
|
||||
) -> Result<(), Error> {
|
||||
match sender
|
||||
.send(FromJob::Backing(CandidateBackingMessage::Second(
|
||||
.send(AllMessages::from(CandidateBackingMessage::Second(
|
||||
relay_parent,
|
||||
candidate_receipt,
|
||||
pov,
|
||||
)))
|
||||
)).into())
|
||||
.await
|
||||
{
|
||||
Err(err) => {
|
||||
@@ -326,12 +248,12 @@ async fn second_candidate(
|
||||
|
||||
async fn forward_invalidity_note(
|
||||
received_from: &CollatorId,
|
||||
sender: &mut mpsc::Sender<FromJob>,
|
||||
sender: &mut mpsc::Sender<FromJobCommand>,
|
||||
) -> Result<(), Error> {
|
||||
sender
|
||||
.send(FromJob::Collator(CollatorProtocolMessage::ReportCollator(
|
||||
.send(AllMessages::from(CollatorProtocolMessage::ReportCollator(
|
||||
received_from.clone(),
|
||||
)))
|
||||
)).into())
|
||||
.await
|
||||
.map_err(Into::into)
|
||||
}
|
||||
@@ -420,7 +342,7 @@ impl metrics::Metrics for Metrics {
|
||||
}
|
||||
}
|
||||
|
||||
delegated_subsystem!(CandidateSelectionJob((), Metrics) <- ToJob as CandidateSelectionSubsystem);
|
||||
delegated_subsystem!(CandidateSelectionJob((), Metrics) <- CandidateSelectionMessage as CandidateSelectionSubsystem);
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
@@ -436,7 +358,7 @@ mod tests {
|
||||
postconditions: Postconditions,
|
||||
) where
|
||||
Preconditions: FnOnce(&mut CandidateSelectionJob),
|
||||
TestBuilder: FnOnce(mpsc::Sender<ToJob>, mpsc::Receiver<FromJob>) -> Test,
|
||||
TestBuilder: FnOnce(mpsc::Sender<CandidateSelectionMessage>, mpsc::Receiver<FromJobCommand>) -> Test,
|
||||
Test: Future<Output = ()>,
|
||||
Postconditions: FnOnce(CandidateSelectionJob, Result<(), Error>),
|
||||
{
|
||||
@@ -453,7 +375,7 @@ mod tests {
|
||||
|
||||
let (_, job_result) = futures::executor::block_on(future::join(
|
||||
test(to_job_tx, from_job_rx),
|
||||
job.run_loop_borrowed(),
|
||||
job.run_loop(),
|
||||
));
|
||||
|
||||
postconditions(job, job_result);
|
||||
@@ -479,12 +401,10 @@ mod tests {
|
||||
|_job| {},
|
||||
|mut to_job, mut from_job| async move {
|
||||
to_job
|
||||
.send(ToJob::CandidateSelection(
|
||||
CandidateSelectionMessage::Collation(
|
||||
relay_parent,
|
||||
para_id,
|
||||
collator_id_clone.clone(),
|
||||
),
|
||||
.send(CandidateSelectionMessage::Collation(
|
||||
relay_parent,
|
||||
para_id,
|
||||
collator_id_clone.clone(),
|
||||
))
|
||||
.await
|
||||
.unwrap();
|
||||
@@ -492,12 +412,12 @@ mod tests {
|
||||
|
||||
while let Some(msg) = from_job.next().await {
|
||||
match msg {
|
||||
FromJob::Collator(CollatorProtocolMessage::FetchCollation(
|
||||
FromJobCommand::SendMessage(AllMessages::CollatorProtocol(CollatorProtocolMessage::FetchCollation(
|
||||
got_relay_parent,
|
||||
collator_id,
|
||||
got_para_id,
|
||||
return_sender,
|
||||
)) => {
|
||||
))) => {
|
||||
assert_eq!(got_relay_parent, relay_parent);
|
||||
assert_eq!(got_para_id, para_id);
|
||||
assert_eq!(collator_id, collator_id_clone);
|
||||
@@ -506,11 +426,11 @@ mod tests {
|
||||
.send((candidate_receipt.clone(), pov.clone()))
|
||||
.unwrap();
|
||||
}
|
||||
FromJob::Backing(CandidateBackingMessage::Second(
|
||||
FromJobCommand::SendMessage(AllMessages::CandidateBacking(CandidateBackingMessage::Second(
|
||||
got_relay_parent,
|
||||
got_candidate_receipt,
|
||||
got_pov,
|
||||
)) => {
|
||||
))) => {
|
||||
assert_eq!(got_relay_parent, relay_parent);
|
||||
assert_eq!(got_candidate_receipt, candidate_receipt);
|
||||
assert_eq!(got_pov, pov);
|
||||
@@ -546,12 +466,10 @@ mod tests {
|
||||
|job| job.seconded_candidate = Some(prev_collator_id.clone()),
|
||||
|mut to_job, mut from_job| async move {
|
||||
to_job
|
||||
.send(ToJob::CandidateSelection(
|
||||
CandidateSelectionMessage::Collation(
|
||||
relay_parent,
|
||||
para_id,
|
||||
collator_id_clone,
|
||||
),
|
||||
.send(CandidateSelectionMessage::Collation(
|
||||
relay_parent,
|
||||
para_id,
|
||||
collator_id_clone,
|
||||
))
|
||||
.await
|
||||
.unwrap();
|
||||
@@ -559,11 +477,11 @@ mod tests {
|
||||
|
||||
while let Some(msg) = from_job.next().await {
|
||||
match msg {
|
||||
FromJob::Backing(CandidateBackingMessage::Second(
|
||||
FromJobCommand::SendMessage(AllMessages::CandidateBacking(CandidateBackingMessage::Second(
|
||||
_got_relay_parent,
|
||||
_got_candidate_receipt,
|
||||
_got_pov,
|
||||
)) => {
|
||||
))) => {
|
||||
*was_seconded_clone.lock().await = true;
|
||||
}
|
||||
other => panic!("unexpected message from job: {:?}", other),
|
||||
@@ -595,18 +513,16 @@ mod tests {
|
||||
|job| job.seconded_candidate = Some(collator_id.clone()),
|
||||
|mut to_job, mut from_job| async move {
|
||||
to_job
|
||||
.send(ToJob::CandidateSelection(
|
||||
CandidateSelectionMessage::Invalid(relay_parent, candidate_receipt),
|
||||
))
|
||||
.send(CandidateSelectionMessage::Invalid(relay_parent, candidate_receipt))
|
||||
.await
|
||||
.unwrap();
|
||||
std::mem::drop(to_job);
|
||||
|
||||
while let Some(msg) = from_job.next().await {
|
||||
match msg {
|
||||
FromJob::Collator(CollatorProtocolMessage::ReportCollator(
|
||||
FromJobCommand::SendMessage(AllMessages::CollatorProtocol(CollatorProtocolMessage::ReportCollator(
|
||||
got_collator_id,
|
||||
)) => {
|
||||
))) => {
|
||||
assert_eq!(got_collator_id, collator_id_clone);
|
||||
|
||||
*sent_report_clone.lock().await = true;
|
||||
|
||||
@@ -26,99 +26,31 @@ use futures::{
|
||||
};
|
||||
use polkadot_node_subsystem::{
|
||||
errors::{ChainApiError, RuntimeApiError},
|
||||
messages::{
|
||||
AllMessages, ChainApiMessage, ProvisionableData, ProvisionerInherentData,
|
||||
ProvisionerMessage, RuntimeApiMessage,
|
||||
},
|
||||
messages::{ChainApiMessage, ProvisionableData, ProvisionerInherentData, ProvisionerMessage, AllMessages},
|
||||
};
|
||||
use polkadot_node_subsystem_util::{
|
||||
self as util,
|
||||
delegated_subsystem, FromJobCommand,
|
||||
request_availability_cores, request_persisted_validation_data, JobTrait, ToJobTrait,
|
||||
metrics::{self, prometheus},
|
||||
self as util, delegated_subsystem, FromJobCommand,
|
||||
request_availability_cores, request_persisted_validation_data, JobTrait, metrics::{self, prometheus},
|
||||
};
|
||||
use polkadot_primitives::v1::{
|
||||
BackedCandidate, BlockNumber, CoreState, Hash, OccupiedCoreAssumption,
|
||||
SignedAvailabilityBitfield, ValidatorIndex,
|
||||
};
|
||||
use std::{convert::TryFrom, pin::Pin};
|
||||
use std::collections::BTreeMap;
|
||||
use std::{pin::Pin, collections::BTreeMap};
|
||||
use thiserror::Error;
|
||||
|
||||
const LOG_TARGET: &str = "provisioner";
|
||||
|
||||
struct ProvisioningJob {
|
||||
relay_parent: Hash,
|
||||
sender: mpsc::Sender<FromJob>,
|
||||
receiver: mpsc::Receiver<ToJob>,
|
||||
sender: mpsc::Sender<FromJobCommand>,
|
||||
receiver: mpsc::Receiver<ProvisionerMessage>,
|
||||
provisionable_data_channels: Vec<mpsc::Sender<ProvisionableData>>,
|
||||
backed_candidates: Vec<BackedCandidate>,
|
||||
signed_bitfields: Vec<SignedAvailabilityBitfield>,
|
||||
metrics: Metrics,
|
||||
}
|
||||
|
||||
/// This enum defines the messages that the provisioner is prepared to receive.
|
||||
pub enum ToJob {
|
||||
/// The provisioner message is the main input to the provisioner.
|
||||
Provisioner(ProvisionerMessage),
|
||||
/// This message indicates that the provisioner should shut itself down.
|
||||
Stop,
|
||||
}
|
||||
|
||||
impl ToJobTrait for ToJob {
|
||||
const STOP: Self = Self::Stop;
|
||||
|
||||
fn relay_parent(&self) -> Option<Hash> {
|
||||
match self {
|
||||
Self::Provisioner(pm) => pm.relay_parent(),
|
||||
Self::Stop => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<AllMessages> for ToJob {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(msg: AllMessages) -> Result<Self, Self::Error> {
|
||||
match msg {
|
||||
AllMessages::Provisioner(pm) => Ok(Self::Provisioner(pm)),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ProvisionerMessage> for ToJob {
|
||||
fn from(pm: ProvisionerMessage) -> Self {
|
||||
Self::Provisioner(pm)
|
||||
}
|
||||
}
|
||||
|
||||
enum FromJob {
|
||||
ChainApi(ChainApiMessage),
|
||||
Runtime(RuntimeApiMessage),
|
||||
}
|
||||
|
||||
impl From<FromJob> for FromJobCommand {
|
||||
fn from(from_job: FromJob) -> FromJobCommand {
|
||||
FromJobCommand::SendMessage(match from_job {
|
||||
FromJob::ChainApi(cam) => AllMessages::ChainApi(cam),
|
||||
FromJob::Runtime(ram) => AllMessages::RuntimeApi(ram),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<AllMessages> for FromJob {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(msg: AllMessages) -> Result<Self, Self::Error> {
|
||||
match msg {
|
||||
AllMessages::ChainApi(chain) => Ok(FromJob::ChainApi(chain)),
|
||||
AllMessages::RuntimeApi(runtime) => Ok(FromJob::Runtime(runtime)),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
enum Error {
|
||||
#[error(transparent)]
|
||||
@@ -141,8 +73,7 @@ enum Error {
|
||||
}
|
||||
|
||||
impl JobTrait for ProvisioningJob {
|
||||
type ToJob = ToJob;
|
||||
type FromJob = FromJob;
|
||||
type ToJob = ProvisionerMessage;
|
||||
type Error = Error;
|
||||
type RunArgs = ();
|
||||
type Metrics = Metrics;
|
||||
@@ -157,8 +88,8 @@ impl JobTrait for ProvisioningJob {
|
||||
relay_parent: Hash,
|
||||
_run_args: Self::RunArgs,
|
||||
metrics: Self::Metrics,
|
||||
receiver: mpsc::Receiver<ToJob>,
|
||||
sender: mpsc::Sender<FromJob>,
|
||||
receiver: mpsc::Receiver<ProvisionerMessage>,
|
||||
sender: mpsc::Sender<FromJobCommand>,
|
||||
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send>> {
|
||||
async move {
|
||||
let job = ProvisioningJob::new(relay_parent, metrics, sender, receiver);
|
||||
@@ -175,8 +106,8 @@ impl ProvisioningJob {
|
||||
pub fn new(
|
||||
relay_parent: Hash,
|
||||
metrics: Metrics,
|
||||
sender: mpsc::Sender<FromJob>,
|
||||
receiver: mpsc::Receiver<ToJob>,
|
||||
sender: mpsc::Sender<FromJobCommand>,
|
||||
receiver: mpsc::Receiver<ProvisionerMessage>,
|
||||
) -> Self {
|
||||
Self {
|
||||
relay_parent,
|
||||
@@ -190,13 +121,13 @@ impl ProvisioningJob {
|
||||
}
|
||||
|
||||
async fn run_loop(mut self) -> Result<(), Error> {
|
||||
while let Some(msg) = self.receiver.next().await {
|
||||
use ProvisionerMessage::{
|
||||
ProvisionableData, RequestBlockAuthorshipData, RequestInherentData,
|
||||
};
|
||||
use ProvisionerMessage::{
|
||||
ProvisionableData, RequestBlockAuthorshipData, RequestInherentData,
|
||||
};
|
||||
|
||||
match msg {
|
||||
ToJob::Provisioner(RequestInherentData(_, return_sender)) => {
|
||||
loop {
|
||||
match self.receiver.next().await {
|
||||
Some(RequestInherentData(_, return_sender)) => {
|
||||
let _timer = self.metrics.time_request_inherent_data();
|
||||
|
||||
if let Err(err) = send_inherent_data(
|
||||
@@ -214,10 +145,10 @@ impl ProvisioningJob {
|
||||
self.metrics.on_inherent_data_request(Ok(()));
|
||||
}
|
||||
}
|
||||
ToJob::Provisioner(RequestBlockAuthorshipData(_, sender)) => {
|
||||
Some(RequestBlockAuthorshipData(_, sender)) => {
|
||||
self.provisionable_data_channels.push(sender)
|
||||
}
|
||||
ToJob::Provisioner(ProvisionableData(_, data)) => {
|
||||
Some(ProvisionableData(_, data)) => {
|
||||
let _timer = self.metrics.time_provisionable_data();
|
||||
|
||||
let mut bad_indices = Vec::new();
|
||||
@@ -252,7 +183,7 @@ impl ProvisioningJob {
|
||||
.map(|(_, item)| item)
|
||||
.collect();
|
||||
}
|
||||
ToJob::Stop => break,
|
||||
None => break,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,7 +229,7 @@ async fn send_inherent_data(
|
||||
bitfields: &[SignedAvailabilityBitfield],
|
||||
candidates: &[BackedCandidate],
|
||||
return_sender: oneshot::Sender<ProvisionerInherentData>,
|
||||
mut from_job: mpsc::Sender<FromJob>,
|
||||
mut from_job: mpsc::Sender<FromJobCommand>,
|
||||
) -> Result<(), Error> {
|
||||
let availability_cores = request_availability_cores(relay_parent, &mut from_job)
|
||||
.await?
|
||||
@@ -368,7 +299,7 @@ async fn select_candidates(
|
||||
bitfields: &[SignedAvailabilityBitfield],
|
||||
candidates: &[BackedCandidate],
|
||||
relay_parent: Hash,
|
||||
sender: &mut mpsc::Sender<FromJob>,
|
||||
sender: &mut mpsc::Sender<FromJobCommand>,
|
||||
) -> Result<Vec<BackedCandidate>, Error> {
|
||||
let block_number = get_block_number_under_construction(relay_parent, sender).await?;
|
||||
|
||||
@@ -432,14 +363,14 @@ async fn select_candidates(
|
||||
#[tracing::instrument(level = "trace", skip(sender), fields(subsystem = LOG_TARGET))]
|
||||
async fn get_block_number_under_construction(
|
||||
relay_parent: Hash,
|
||||
sender: &mut mpsc::Sender<FromJob>,
|
||||
sender: &mut mpsc::Sender<FromJobCommand>,
|
||||
) -> Result<BlockNumber, Error> {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
sender
|
||||
.send(FromJob::ChainApi(ChainApiMessage::BlockNumber(
|
||||
.send(AllMessages::from(ChainApiMessage::BlockNumber(
|
||||
relay_parent,
|
||||
tx,
|
||||
)))
|
||||
)).into())
|
||||
.await
|
||||
.map_err(|e| Error::ChainApiMessageSend(e))?;
|
||||
match rx.await? {
|
||||
@@ -558,7 +489,7 @@ impl metrics::Metrics for Metrics {
|
||||
}
|
||||
|
||||
|
||||
delegated_subsystem!(ProvisioningJob((), Metrics) <- ToJob as ProvisioningSubsystem);
|
||||
delegated_subsystem!(ProvisioningJob((), Metrics) <- ProvisionerMessage as ProvisioningSubsystem);
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
@@ -193,13 +193,13 @@ mod select_candidates {
|
||||
use futures_timer::Delay;
|
||||
use super::super::*;
|
||||
use super::{build_occupied_core, default_bitvec, occupied_core, scheduled_core};
|
||||
use polkadot_node_subsystem::messages::RuntimeApiRequest::{
|
||||
AvailabilityCores, PersistedValidationData as PersistedValidationDataReq,
|
||||
use polkadot_node_subsystem::messages::{
|
||||
AllMessages, RuntimeApiMessage,
|
||||
RuntimeApiRequest::{AvailabilityCores, PersistedValidationData as PersistedValidationDataReq},
|
||||
};
|
||||
use polkadot_primitives::v1::{
|
||||
BlockNumber, CandidateDescriptor, CommittedCandidateReceipt, PersistedValidationData,
|
||||
};
|
||||
use FromJob::{ChainApi, Runtime};
|
||||
|
||||
const BLOCK_UNDER_PRODUCTION: BlockNumber = 128;
|
||||
|
||||
@@ -207,9 +207,9 @@ mod select_candidates {
|
||||
overseer_factory: OverseerFactory,
|
||||
test_factory: TestFactory,
|
||||
) where
|
||||
OverseerFactory: FnOnce(mpsc::Receiver<FromJob>) -> Overseer,
|
||||
OverseerFactory: FnOnce(mpsc::Receiver<FromJobCommand>) -> Overseer,
|
||||
Overseer: Future<Output = ()>,
|
||||
TestFactory: FnOnce(mpsc::Sender<FromJob>) -> Test,
|
||||
TestFactory: FnOnce(mpsc::Sender<FromJobCommand>) -> Test,
|
||||
Test: Future<Output = ()>,
|
||||
{
|
||||
let (tx, rx) = mpsc::channel(64);
|
||||
@@ -297,20 +297,20 @@ mod select_candidates {
|
||||
]
|
||||
}
|
||||
|
||||
async fn mock_overseer(mut receiver: mpsc::Receiver<FromJob>) {
|
||||
async fn mock_overseer(mut receiver: mpsc::Receiver<FromJobCommand>) {
|
||||
use ChainApiMessage::BlockNumber;
|
||||
use RuntimeApiMessage::Request;
|
||||
|
||||
while let Some(from_job) = receiver.next().await {
|
||||
match from_job {
|
||||
ChainApi(BlockNumber(_relay_parent, tx)) => {
|
||||
FromJobCommand::SendMessage(AllMessages::ChainApi(BlockNumber(_relay_parent, tx))) => {
|
||||
tx.send(Ok(Some(BLOCK_UNDER_PRODUCTION - 1))).unwrap()
|
||||
}
|
||||
Runtime(Request(
|
||||
FromJobCommand::SendMessage(AllMessages::RuntimeApi(Request(
|
||||
_parent_hash,
|
||||
PersistedValidationDataReq(_para_id, _assumption, tx),
|
||||
)) => tx.send(Ok(Some(Default::default()))).unwrap(),
|
||||
Runtime(Request(_parent_hash, AvailabilityCores(tx))) => {
|
||||
))) => tx.send(Ok(Some(Default::default()))).unwrap(),
|
||||
FromJobCommand::SendMessage(AllMessages::RuntimeApi(Request(_parent_hash, AvailabilityCores(tx)))) => {
|
||||
tx.send(Ok(mock_availability_cores())).unwrap()
|
||||
}
|
||||
// non-exhaustive matches are fine for testing
|
||||
@@ -321,14 +321,14 @@ mod select_candidates {
|
||||
|
||||
#[test]
|
||||
fn handles_overseer_failure() {
|
||||
let overseer = |rx: mpsc::Receiver<FromJob>| async move {
|
||||
let overseer = |rx: mpsc::Receiver<FromJobCommand>| async move {
|
||||
// drop the receiver so it closes and the sender can't send, then just sleep long enough that
|
||||
// this is almost certainly not the first of the two futures to complete
|
||||
std::mem::drop(rx);
|
||||
Delay::new(std::time::Duration::from_secs(1)).await;
|
||||
};
|
||||
|
||||
let test = |mut tx: mpsc::Sender<FromJob>| async move {
|
||||
let test = |mut tx: mpsc::Sender<FromJobCommand>| async move {
|
||||
// wait so that the overseer can drop the rx before we attempt to send
|
||||
Delay::new(std::time::Duration::from_millis(50)).await;
|
||||
let result = select_candidates(&[], &[], &[], Default::default(), &mut tx).await;
|
||||
@@ -341,7 +341,7 @@ mod select_candidates {
|
||||
|
||||
#[test]
|
||||
fn can_succeed() {
|
||||
test_harness(mock_overseer, |mut tx: mpsc::Sender<FromJob>| async move {
|
||||
test_harness(mock_overseer, |mut tx: mpsc::Sender<FromJobCommand>| async move {
|
||||
let result = select_candidates(&[], &[], &[], Default::default(), &mut tx).await;
|
||||
println!("{:?}", result);
|
||||
assert!(result.is_ok());
|
||||
@@ -403,7 +403,7 @@ mod select_candidates {
|
||||
.map(|&idx| candidates[idx].clone())
|
||||
.collect();
|
||||
|
||||
test_harness(mock_overseer, |mut tx: mpsc::Sender<FromJob>| async move {
|
||||
test_harness(mock_overseer, |mut tx: mpsc::Sender<FromJobCommand>| async move {
|
||||
let result =
|
||||
select_candidates(&mock_cores, &[], &candidates, Default::default(), &mut tx)
|
||||
.await;
|
||||
|
||||
Reference in New Issue
Block a user