Use cached session index to obtain executor params (#1190)

* Import changes from archieved repo

* Revert erroneous changes

* Fix more tests

* Resolve discussions

* Fix MORE tests

* approval-voting: launch_approval better interface (#1355)

---------

Co-authored-by: Javier Viola <javier@parity.io>
Co-authored-by: ordian <noreply@reusable.software>
Co-authored-by: ordian <write@reusable.software>
This commit is contained in:
s0me0ne-unkn0wn
2023-09-01 20:07:32 +02:00
committed by GitHub
parent ccdf636c49
commit a2b6470607
29 changed files with 819 additions and 331 deletions
@@ -598,7 +598,9 @@ pub(crate) mod tests {
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::{Id as ParaId, IndexedVec, SessionInfo, ValidatorId, ValidatorIndex};
use polkadot_primitives::{
ExecutorParams, Id as ParaId, IndexedVec, SessionInfo, ValidatorId, ValidatorIndex,
};
pub(crate) use sp_consensus_babe::{
digests::{CompatibleDigestItem, PreDigest, SecondaryVRFPreDigest},
AllowedSlots, BabeEpochConfiguration, Epoch as BabeEpoch,
@@ -835,6 +837,20 @@ pub(crate) mod tests {
si_tx.send(Ok(Some(session_info.clone()))).unwrap();
}
);
assert_matches!(
handle.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(
req_block_hash,
RuntimeApiRequest::SessionExecutorParams(idx, si_tx),
)
) => {
assert_eq!(session, idx);
assert_eq!(req_block_hash, hash);
si_tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
}
);
});
futures::executor::block_on(futures::future::join(test_fut, aux_fut));
@@ -952,6 +968,20 @@ pub(crate) mod tests {
si_tx.send(Ok(Some(session_info.clone()))).unwrap();
}
);
assert_matches!(
handle.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(
req_block_hash,
RuntimeApiRequest::SessionExecutorParams(idx, si_tx),
)
) => {
assert_eq!(session, idx);
assert_eq!(req_block_hash, hash);
si_tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
}
);
});
futures::executor::block_on(futures::future::join(test_fut, aux_fut));
@@ -1172,6 +1202,20 @@ pub(crate) mod tests {
si_tx.send(Ok(Some(session_info.clone()))).unwrap();
}
);
assert_matches!(
handle.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(
req_block_hash,
RuntimeApiRequest::SessionExecutorParams(idx, si_tx),
)
) => {
assert_eq!(session, idx);
assert_eq!(req_block_hash, hash);
si_tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
}
);
});
futures::executor::block_on(futures::future::join(test_fut, aux_fut));
@@ -1374,6 +1418,20 @@ pub(crate) mod tests {
}
);
assert_matches!(
handle.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(
req_block_hash,
RuntimeApiRequest::SessionExecutorParams(idx, si_tx),
)
) => {
assert_eq!(session, idx);
assert_eq!(req_block_hash, hash);
si_tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
}
);
assert_matches!(
handle.recv().await,
AllMessages::ApprovalDistribution(ApprovalDistributionMessage::NewBlocks(
+50 -28
View File
@@ -45,13 +45,13 @@ use polkadot_node_subsystem_util::{
self,
database::Database,
metrics::{self, prometheus},
runtime::{Config as RuntimeInfoConfig, RuntimeInfo},
runtime::{Config as RuntimeInfoConfig, ExtendedSessionInfo, RuntimeInfo},
TimeoutExt,
};
use polkadot_primitives::{
ApprovalVote, BlockNumber, CandidateHash, CandidateIndex, CandidateReceipt, DisputeStatement,
GroupIndex, Hash, PvfExecTimeoutKind, SessionIndex, SessionInfo, ValidDisputeStatementKind,
ValidatorId, ValidatorIndex, ValidatorPair, ValidatorSignature,
ExecutorParams, GroupIndex, Hash, PvfExecTimeoutKind, SessionIndex, SessionInfo,
ValidDisputeStatementKind, ValidatorId, ValidatorIndex, ValidatorPair, ValidatorSignature,
};
use sc_keystore::LocalKeystore;
use sp_application_crypto::Pair;
@@ -643,6 +643,32 @@ impl CurrentlyCheckingSet {
}
}
async fn get_extended_session_info<'a, Sender>(
runtime_info: &'a mut RuntimeInfo,
sender: &mut Sender,
relay_parent: Hash,
session_index: SessionIndex,
) -> Option<&'a ExtendedSessionInfo>
where
Sender: SubsystemSender<RuntimeApiMessage>,
{
match runtime_info
.get_session_info_by_index(sender, relay_parent, session_index)
.await
{
Ok(extended_info) => Some(&extended_info),
Err(_) => {
gum::debug!(
target: LOG_TARGET,
session = session_index,
?relay_parent,
"Can't obtain SessionInfo or ExecutorParams"
);
None
},
}
}
async fn get_session_info<'a, Sender>(
runtime_info: &'a mut RuntimeInfo,
sender: &mut Sender,
@@ -652,21 +678,9 @@ async fn get_session_info<'a, Sender>(
where
Sender: SubsystemSender<RuntimeApiMessage>,
{
match runtime_info
.get_session_info_by_index(sender, relay_parent, session_index)
get_extended_session_info(runtime_info, sender, relay_parent, session_index)
.await
{
Ok(extended_info) => Some(&extended_info.session_info),
Err(_) => {
gum::debug!(
target: LOG_TARGET,
session = session_index,
?relay_parent,
"Can't obtain SessionInfo"
);
None
},
}
.map(|extended_info| &extended_info.session_info)
}
struct State {
@@ -746,6 +760,7 @@ enum Action {
relay_block_hash: Hash,
candidate_index: CandidateIndex,
session: SessionIndex,
executor_params: ExecutorParams,
candidate: CandidateReceipt,
backing_group: GroupIndex,
},
@@ -968,6 +983,7 @@ async fn handle_actions<Context>(
relay_block_hash,
candidate_index,
session,
executor_params,
candidate,
backing_group,
} => {
@@ -1008,6 +1024,7 @@ async fn handle_actions<Context>(
},
None => {
let ctx = &mut *ctx;
currently_checking_set
.insert_relay_block_hash(
candidate_hash,
@@ -1022,6 +1039,7 @@ async fn handle_actions<Context>(
validator_index,
block_hash,
backing_group,
executor_params,
&launch_approval_span,
)
.await
@@ -2328,17 +2346,18 @@ async fn process_wakeup<Context>(
_ => return Ok(Vec::new()),
};
let session_info = match get_session_info(
session_info_provider,
ctx.sender(),
block_entry.parent_hash(),
block_entry.session(),
)
.await
{
Some(i) => i,
None => return Ok(Vec::new()),
};
let ExtendedSessionInfo { ref session_info, ref executor_params, .. } =
match get_extended_session_info(
session_info_provider,
ctx.sender(),
block_entry.parent_hash(),
block_entry.session(),
)
.await
{
Some(i) => i,
None => return Ok(Vec::new()),
};
let block_tick = slot_number_to_tick(state.slot_duration_millis, block_entry.slot());
let no_show_duration = slot_number_to_tick(
@@ -2425,6 +2444,7 @@ async fn process_wakeup<Context>(
relay_block_hash: relay_block,
candidate_index: i as _,
session: block_entry.session(),
executor_params: executor_params.clone(),
candidate: candidate_receipt,
backing_group,
});
@@ -2466,6 +2486,7 @@ async fn launch_approval<Context>(
validator_index: ValidatorIndex,
block_hash: Hash,
backing_group: GroupIndex,
executor_params: ExecutorParams,
span: &jaeger::Span,
) -> SubsystemResult<RemoteHandle<ApprovalState>> {
let (a_tx, a_rx) = oneshot::channel();
@@ -2611,6 +2632,7 @@ async fn launch_approval<Context>(
validation_code,
candidate.clone(),
available_data.pov,
executor_params,
PvfExecTimeoutKind::Approval,
val_tx,
))
@@ -910,6 +910,19 @@ async fn import_block(
si_tx.send(Ok(Some(session_info.clone()))).unwrap();
}
);
assert_matches!(
overseer_recv(overseer).await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(
req_block_hash,
RuntimeApiRequest::SessionExecutorParams(_, si_tx),
)
) => {
// Make sure all SessionExecutorParams calls are not made for the leaf (but for its relay parent)
assert_ne!(req_block_hash, hashes[(number-1) as usize].0);
si_tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
}
);
}
assert_matches!(
@@ -2376,7 +2389,7 @@ async fn handle_double_assignment_import(
assert_matches!(
overseer_recv(virtual_overseer).await,
AllMessages::CandidateValidation(CandidateValidationMessage::ValidateFromExhaustive(_, _, _, _, timeout, tx)) if timeout == PvfExecTimeoutKind::Approval => {
AllMessages::CandidateValidation(CandidateValidationMessage::ValidateFromExhaustive(_, _, _, _, _, timeout, tx)) if timeout == PvfExecTimeoutKind::Approval => {
tx.send(Ok(ValidationResult::Valid(Default::default(), Default::default())))
.unwrap();
}
+13 -5
View File
@@ -96,8 +96,8 @@ use polkadot_node_subsystem::{
use polkadot_node_subsystem_util::{
self as util,
backing_implicit_view::{FetchError as ImplicitViewFetchError, View as ImplicitView},
request_from_runtime, request_session_index_for_child, request_validator_groups,
request_validators,
executor_params_at_relay_parent, request_from_runtime, request_session_index_for_child,
request_validator_groups, request_validators,
runtime::{
self, prospective_parachains_mode, request_min_backing_votes, ProspectiveParachainsMode,
},
@@ -105,9 +105,9 @@ use polkadot_node_subsystem_util::{
};
use polkadot_primitives::{
BackedCandidate, CandidateCommitments, CandidateHash, CandidateReceipt,
CommittedCandidateReceipt, CoreIndex, CoreState, Hash, Id as ParaId, PersistedValidationData,
PvfExecTimeoutKind, SigningContext, ValidationCode, ValidatorId, ValidatorIndex,
ValidatorSignature, ValidityAttestation,
CommittedCandidateReceipt, CoreIndex, CoreState, ExecutorParams, Hash, Id as ParaId,
PersistedValidationData, PvfExecTimeoutKind, SigningContext, ValidationCode, ValidatorId,
ValidatorIndex, ValidatorSignature, ValidityAttestation,
};
use sp_keystore::KeystorePtr;
use statement_table::{
@@ -555,6 +555,7 @@ async fn request_candidate_validation(
code: ValidationCode,
candidate_receipt: CandidateReceipt,
pov: Arc<PoV>,
executor_params: ExecutorParams,
) -> Result<ValidationResult, Error> {
let (tx, rx) = oneshot::channel();
@@ -564,6 +565,7 @@ async fn request_candidate_validation(
code,
candidate_receipt,
pov,
executor_params,
PvfExecTimeoutKind::Backing,
tx,
))
@@ -630,6 +632,11 @@ async fn validate_and_make_available(
}
};
let executor_params = match executor_params_at_relay_parent(relay_parent, &mut sender).await {
Ok(ep) => ep,
Err(e) => return Err(Error::UtilError(e)),
};
let pov = match pov {
PoVData::Ready(pov) => pov,
PoVData::FetchFromValidator { from_validator, candidate_hash, pov_hash } =>
@@ -665,6 +672,7 @@ async fn validate_and_make_available(
validation_code,
candidate.clone(),
pov.clone(),
executor_params,
)
.await?
};
+257 -1
View File
@@ -348,6 +348,24 @@ fn backing_second_works() {
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionIndexForChild(tx))
) => {
tx.send(Ok(1u32.into())).unwrap();
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionExecutorParams(sess_idx, tx))
) if sess_idx == 1 => {
tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::CandidateValidation(
@@ -356,6 +374,7 @@ fn backing_second_works() {
_validation_code,
candidate_receipt,
_pov,
_,
timeout,
tx,
),
@@ -494,6 +513,24 @@ fn backing_works() {
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionIndexForChild(tx))
) => {
tx.send(Ok(1u32.into())).unwrap();
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionExecutorParams(sess_idx, tx))
) if sess_idx == 1 => {
tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
}
);
// Sending a `Statement::Seconded` for our assignment will start
// validation process. The first thing requested is the PoV.
assert_matches!(
@@ -519,6 +556,7 @@ fn backing_works() {
_validation_code,
candidate_receipt,
_pov,
_,
timeout,
tx,
),
@@ -678,6 +716,24 @@ fn backing_works_while_validation_ongoing() {
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionIndexForChild(tx))
) => {
tx.send(Ok(1u32.into())).unwrap();
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionExecutorParams(sess_idx, tx))
) if sess_idx == 1 => {
tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
}
);
// Sending a `Statement::Seconded` for our assignment will start
// validation process. The first thing requested is PoV from the
// `PoVDistribution`.
@@ -704,6 +760,7 @@ fn backing_works_while_validation_ongoing() {
_validation_code,
candidate_receipt,
_pov,
_,
timeout,
tx,
),
@@ -850,6 +907,24 @@ fn backing_misbehavior_works() {
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionIndexForChild(tx))
) => {
tx.send(Ok(1u32.into())).unwrap();
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionExecutorParams(sess_idx, tx))
) if sess_idx == 1 => {
tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::AvailabilityDistribution(
@@ -871,6 +946,7 @@ fn backing_misbehavior_works() {
_validation_code,
candidate_receipt,
_pov,
_,
timeout,
tx,
),
@@ -1036,6 +1112,24 @@ fn backing_dont_second_invalid() {
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionIndexForChild(tx))
) => {
tx.send(Ok(1u32.into())).unwrap();
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionExecutorParams(sess_idx, tx))
) if sess_idx == 1 => {
tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::CandidateValidation(
@@ -1044,6 +1138,7 @@ fn backing_dont_second_invalid() {
_validation_code,
candidate_receipt,
_pov,
_,
timeout,
tx,
),
@@ -1082,6 +1177,24 @@ fn backing_dont_second_invalid() {
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionIndexForChild(tx))
) => {
tx.send(Ok(1u32.into())).unwrap();
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionExecutorParams(sess_idx, tx))
) if sess_idx == 1 => {
tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::CandidateValidation(
@@ -1090,6 +1203,7 @@ fn backing_dont_second_invalid() {
_validation_code,
candidate_receipt,
_pov,
_,
timeout,
tx,
),
@@ -1200,6 +1314,24 @@ fn backing_second_after_first_fails_works() {
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionIndexForChild(tx))
) => {
tx.send(Ok(1u32.into())).unwrap();
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionExecutorParams(sess_idx, tx))
) if sess_idx == 1 => {
tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
}
);
// Subsystem requests PoV and requests validation.
assert_matches!(
virtual_overseer.recv().await,
@@ -1223,6 +1355,7 @@ fn backing_second_after_first_fails_works() {
_validation_code,
candidate_receipt,
_pov,
_,
timeout,
tx,
),
@@ -1289,6 +1422,24 @@ fn backing_second_after_first_fails_works() {
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionIndexForChild(tx))
) => {
tx.send(Ok(1u32.into())).unwrap();
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionExecutorParams(sess_idx, tx))
) if sess_idx == 1 => {
tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::CandidateValidation(
@@ -1357,6 +1508,24 @@ fn backing_works_after_failed_validation() {
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionIndexForChild(tx))
) => {
tx.send(Ok(1u32.into())).unwrap();
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionExecutorParams(sess_idx, tx))
) if sess_idx == 1 => {
tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
}
);
// Subsystem requests PoV and requests validation.
assert_matches!(
virtual_overseer.recv().await,
@@ -1380,6 +1549,7 @@ fn backing_works_after_failed_validation() {
_validation_code,
candidate_receipt,
_pov,
_,
timeout,
tx,
),
@@ -1566,6 +1736,24 @@ fn retry_works() {
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionIndexForChild(tx))
) => {
tx.send(Ok(1u32.into())).unwrap();
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionExecutorParams(sess_idx, tx))
) if sess_idx == 1 => {
tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
}
);
// Subsystem requests PoV and requests validation.
// We cancel - should mean retry on next backing statement.
assert_matches!(
@@ -1586,7 +1774,7 @@ fn retry_works() {
virtual_overseer.send(FromOrchestra::Communication { msg: statement }).await;
// Not deterministic which message comes first:
for _ in 0u32..3 {
for _ in 0u32..5 {
match virtual_overseer.recv().await {
AllMessages::Provisioner(ProvisionerMessage::ProvisionableData(
_,
@@ -1605,6 +1793,18 @@ fn retry_works() {
)) if hash == validation_code.hash() => {
tx.send(Ok(Some(validation_code.clone()))).unwrap();
},
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
_,
RuntimeApiRequest::SessionIndexForChild(tx),
)) => {
tx.send(Ok(1u32.into())).unwrap();
},
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
_,
RuntimeApiRequest::SessionExecutorParams(sess_idx, tx),
)) if sess_idx == 1 => {
tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
},
msg => {
assert!(false, "Unexpected message: {:?}", msg);
},
@@ -1624,6 +1824,24 @@ fn retry_works() {
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionIndexForChild(tx))
) => {
tx.send(Ok(1u32.into())).unwrap();
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionExecutorParams(sess_idx, tx))
) if sess_idx == 1 => {
tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::AvailabilityDistribution(
@@ -1647,6 +1865,7 @@ fn retry_works() {
_validation_code,
candidate_receipt,
_pov,
_,
timeout,
..
),
@@ -1821,6 +2040,24 @@ fn cannot_second_multiple_candidates_per_parent() {
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionIndexForChild(tx))
) => {
tx.send(Ok(1u32.into())).unwrap();
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionExecutorParams(sess_idx, tx))
) if sess_idx == 1 => {
tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::CandidateValidation(
@@ -1829,6 +2066,7 @@ fn cannot_second_multiple_candidates_per_parent() {
_validation_code,
candidate_receipt,
_pov,
_,
timeout,
tx,
),
@@ -1907,6 +2145,24 @@ fn cannot_second_multiple_candidates_per_parent() {
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionIndexForChild(tx))
) => {
tx.send(Ok(1u32.into())).unwrap();
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionExecutorParams(sess_idx, tx))
) if sess_idx == 1 => {
tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::CandidateValidation(
@@ -217,6 +217,24 @@ async fn assert_validate_seconded_candidate(
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionIndexForChild(tx))
) => {
tx.send(Ok(1u32.into())).unwrap();
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionExecutorParams(sess_idx, tx))
) if sess_idx == 1 => {
tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
}
);
if fetch_pov {
assert_matches!(
virtual_overseer.recv().await,
@@ -239,6 +257,7 @@ async fn assert_validate_seconded_candidate(
_validation_code,
candidate_receipt,
_pov,
_,
timeout,
tx,
)) if &_pvd == pvd &&
@@ -1339,7 +1358,7 @@ fn concurrent_dependent_candidates() {
tx.send(pov.clone()).unwrap();
},
AllMessages::CandidateValidation(
CandidateValidationMessage::ValidateFromExhaustive(.., candidate, _, _, tx),
CandidateValidationMessage::ValidateFromExhaustive(.., candidate, _, _, _, tx),
) => {
let candidate_hash = candidate.hash();
let (head_data, pvd) = if candidate_hash == candidate_a_hash {
@@ -1396,6 +1415,20 @@ fn concurrent_dependent_candidates() {
break
}
},
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
_,
RuntimeApiRequest::SessionIndexForChild(tx),
)) => {
tx.send(Ok(1u32.into())).unwrap();
},
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
_,
RuntimeApiRequest::SessionExecutorParams(sess_idx, tx),
)) => {
assert_eq!(sess_idx, 1);
tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
},
_ => panic!("unexpected message received from overseer: {:?}", msg),
}
}
@@ -164,6 +164,7 @@ async fn run<Context>(
CandidateValidationMessage::ValidateFromChainState(
candidate_receipt,
pov,
executor_params,
timeout,
response_sender,
) => {
@@ -179,6 +180,7 @@ async fn run<Context>(
validation_host,
candidate_receipt,
pov,
executor_params,
timeout,
&metrics,
)
@@ -196,23 +198,23 @@ async fn run<Context>(
validation_code,
candidate_receipt,
pov,
executor_params,
timeout,
response_sender,
) => {
let bg = {
let mut sender = ctx.sender().clone();
let metrics = metrics.clone();
let validation_host = validation_host.clone();
async move {
let _timer = metrics.time_validate_from_exhaustive();
let res = validate_candidate_exhaustive(
&mut sender,
validation_host,
persisted_validation_data,
validation_code,
candidate_receipt,
pov,
executor_params,
timeout,
&metrics,
)
@@ -497,6 +499,7 @@ async fn validate_from_chain_state<Sender>(
validation_host: ValidationHost,
candidate_receipt: CandidateReceipt,
pov: Arc<PoV>,
executor_params: ExecutorParams,
exec_timeout_kind: PvfExecTimeoutKind,
metrics: &Metrics,
) -> Result<ValidationResult, ValidationFailed>
@@ -511,12 +514,12 @@ where
};
let validation_result = validate_candidate_exhaustive(
sender,
validation_host,
validation_data,
validation_code,
candidate_receipt.clone(),
pov,
executor_params,
exec_timeout_kind,
metrics,
)
@@ -546,19 +549,16 @@ where
validation_result
}
async fn validate_candidate_exhaustive<Sender>(
sender: &mut Sender,
async fn validate_candidate_exhaustive(
mut validation_backend: impl ValidationBackend + Send,
persisted_validation_data: PersistedValidationData,
validation_code: ValidationCode,
candidate_receipt: CandidateReceipt,
pov: Arc<PoV>,
executor_params: ExecutorParams,
exec_timeout_kind: PvfExecTimeoutKind,
metrics: &Metrics,
) -> Result<ValidationResult, ValidationFailed>
where
Sender: SubsystemSender<RuntimeApiMessage>,
{
) -> Result<ValidationResult, ValidationFailed> {
let _timer = metrics.time_validate_candidate_exhaustive();
let validation_code_hash = validation_code.hash();
@@ -615,27 +615,6 @@ where
relay_parent_storage_root: persisted_validation_data.relay_parent_storage_root,
};
let executor_params = if let Ok(executor_params) =
executor_params_at_relay_parent(candidate_receipt.descriptor.relay_parent, sender).await
{
gum::debug!(
target: LOG_TARGET,
?validation_code_hash,
?para_id,
"Acquired executor params for the session: {:?}",
executor_params,
);
executor_params
} else {
gum::warn!(
target: LOG_TARGET,
?validation_code_hash,
?para_id,
"Failed to acquire executor params for the session",
);
return Ok(ValidationResult::Invalid(InvalidCandidate::BadParent))
};
let result = validation_backend
.validate_candidate_with_retry(
raw_validation_code.to_vec(),
@@ -26,37 +26,6 @@ use polkadot_primitives::{HeadData, Id as ParaId, UpwardMessage};
use sp_core::testing::TaskExecutor;
use sp_keyring::Sr25519Keyring;
fn test_with_executor_params<T: futures::Future<Output = R>, R, M>(
mut ctx_handle: test_helpers::TestSubsystemContextHandle<M>,
test: impl FnOnce() -> T,
) -> R {
let test_fut = test();
let overseer = async move {
assert_matches!(
ctx_handle.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionIndexForChild(tx))
) => {
tx.send(Ok(1u32.into())).unwrap();
}
);
assert_matches!(
ctx_handle.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionExecutorParams(_, tx))
) => {
tx.send(Ok(Some(ExecutorParams::default()))).unwrap();
}
);
};
futures::pin_mut!(test_fut);
futures::pin_mut!(overseer);
let v = executor::block_on(future::join(test_fut, overseer));
v.0
}
#[test]
fn correctly_checks_included_assumption() {
let validation_data: PersistedValidationData = Default::default();
@@ -460,23 +429,16 @@ fn candidate_validation_ok_is_ok() {
let candidate_receipt = CandidateReceipt { descriptor, commitments_hash: commitments.hash() };
let pool = TaskExecutor::new();
let (mut ctx, ctx_handle) =
test_helpers::make_subsystem_context::<AllMessages, _>(pool.clone());
let metrics = Metrics::default();
let v = test_with_executor_params(ctx_handle, || {
validate_candidate_exhaustive(
ctx.sender(),
MockValidateCandidateBackend::with_hardcoded_result(Ok(validation_result)),
validation_data.clone(),
validation_code,
candidate_receipt,
Arc::new(pov),
PvfExecTimeoutKind::Backing,
&metrics,
)
})
let v = executor::block_on(validate_candidate_exhaustive(
MockValidateCandidateBackend::with_hardcoded_result(Ok(validation_result)),
validation_data.clone(),
validation_code,
candidate_receipt,
Arc::new(pov),
ExecutorParams::default(),
PvfExecTimeoutKind::Backing,
&Default::default(),
))
.unwrap();
assert_matches!(v, ValidationResult::Valid(outputs, used_validation_data) => {
@@ -517,27 +479,21 @@ fn candidate_validation_bad_return_is_invalid() {
let candidate_receipt = CandidateReceipt { descriptor, commitments_hash: Hash::zero() };
let pool = TaskExecutor::new();
let (mut ctx, ctx_handle) =
test_helpers::make_subsystem_context::<AllMessages, _>(pool.clone());
let metrics = Metrics::default();
let v = executor::block_on(validate_candidate_exhaustive(
MockValidateCandidateBackend::with_hardcoded_result(Err(
ValidationError::InvalidCandidate(WasmInvalidCandidate::HardTimeout),
)),
validation_data,
validation_code,
candidate_receipt,
Arc::new(pov),
ExecutorParams::default(),
PvfExecTimeoutKind::Backing,
&Default::default(),
))
.unwrap();
let v = test_with_executor_params(ctx_handle, || {
validate_candidate_exhaustive(
ctx.sender(),
MockValidateCandidateBackend::with_hardcoded_result(Err(
ValidationError::InvalidCandidate(WasmInvalidCandidate::HardTimeout),
)),
validation_data,
validation_code,
candidate_receipt,
Arc::new(pov),
PvfExecTimeoutKind::Backing,
&metrics,
)
});
assert_matches!(v, Ok(ValidationResult::Invalid(InvalidCandidate::Timeout)));
assert_matches!(v, ValidationResult::Invalid(InvalidCandidate::Timeout));
}
// Test that we vote valid if we get `AmbiguousWorkerDeath`, retry, and then succeed.
@@ -588,26 +544,19 @@ fn candidate_validation_one_ambiguous_error_is_valid() {
let candidate_receipt = CandidateReceipt { descriptor, commitments_hash: commitments.hash() };
let pool = TaskExecutor::new();
let (mut ctx, ctx_handle) =
test_helpers::make_subsystem_context::<AllMessages, _>(pool.clone());
let metrics = Metrics::default();
let v = test_with_executor_params(ctx_handle, || {
validate_candidate_exhaustive(
ctx.sender(),
MockValidateCandidateBackend::with_hardcoded_result_list(vec![
Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::AmbiguousWorkerDeath)),
Ok(validation_result),
]),
validation_data.clone(),
validation_code,
candidate_receipt,
Arc::new(pov),
PvfExecTimeoutKind::Backing,
&metrics,
)
})
let v = executor::block_on(validate_candidate_exhaustive(
MockValidateCandidateBackend::with_hardcoded_result_list(vec![
Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::AmbiguousWorkerDeath)),
Ok(validation_result),
]),
validation_data.clone(),
validation_code,
candidate_receipt,
Arc::new(pov),
ExecutorParams::default(),
PvfExecTimeoutKind::Backing,
&Default::default(),
))
.unwrap();
assert_matches!(v, ValidationResult::Valid(outputs, used_validation_data) => {
@@ -648,26 +597,19 @@ fn candidate_validation_multiple_ambiguous_errors_is_invalid() {
let candidate_receipt = CandidateReceipt { descriptor, commitments_hash: Hash::zero() };
let pool = TaskExecutor::new();
let (mut ctx, ctx_handle) =
test_helpers::make_subsystem_context::<AllMessages, _>(pool.clone());
let metrics = Metrics::default();
let v = test_with_executor_params(ctx_handle, || {
validate_candidate_exhaustive(
ctx.sender(),
MockValidateCandidateBackend::with_hardcoded_result_list(vec![
Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::AmbiguousWorkerDeath)),
Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::AmbiguousWorkerDeath)),
]),
validation_data,
validation_code,
candidate_receipt,
Arc::new(pov),
PvfExecTimeoutKind::Backing,
&metrics,
)
})
let v = executor::block_on(validate_candidate_exhaustive(
MockValidateCandidateBackend::with_hardcoded_result_list(vec![
Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::AmbiguousWorkerDeath)),
Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::AmbiguousWorkerDeath)),
]),
validation_data,
validation_code,
candidate_receipt,
Arc::new(pov),
ExecutorParams::default(),
PvfExecTimeoutKind::Backing,
&Default::default(),
))
.unwrap();
assert_matches!(v, ValidationResult::Invalid(InvalidCandidate::ExecutionError(_)));
@@ -702,29 +644,22 @@ fn candidate_validation_retry_internal_errors() {
let candidate_receipt = CandidateReceipt { descriptor, commitments_hash: Hash::zero() };
let pool = TaskExecutor::new();
let (mut ctx, ctx_handle) =
test_helpers::make_subsystem_context::<AllMessages, _>(pool.clone());
let metrics = Metrics::default();
let v = test_with_executor_params(ctx_handle, || {
validate_candidate_exhaustive(
ctx.sender(),
MockValidateCandidateBackend::with_hardcoded_result_list(vec![
Err(InternalValidationError::HostCommunication("foo".into()).into()),
// Throw an AWD error, we should still retry again.
Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::AmbiguousWorkerDeath)),
// Throw another internal error.
Err(InternalValidationError::HostCommunication("bar".into()).into()),
]),
validation_data,
validation_code,
candidate_receipt,
Arc::new(pov),
PvfExecTimeoutKind::Backing,
&metrics,
)
});
let v = executor::block_on(validate_candidate_exhaustive(
MockValidateCandidateBackend::with_hardcoded_result_list(vec![
Err(InternalValidationError::HostCommunication("foo".into()).into()),
// Throw an AWD error, we should still retry again.
Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::AmbiguousWorkerDeath)),
// Throw another internal error.
Err(InternalValidationError::HostCommunication("bar".into()).into()),
]),
validation_data,
validation_code,
candidate_receipt,
Arc::new(pov),
ExecutorParams::default(),
PvfExecTimeoutKind::Backing,
&Default::default(),
));
assert_matches!(v, Err(ValidationFailed(s)) if s.contains("bar"));
}
@@ -758,29 +693,22 @@ fn candidate_validation_retry_panic_errors() {
let candidate_receipt = CandidateReceipt { descriptor, commitments_hash: Hash::zero() };
let pool = TaskExecutor::new();
let (mut ctx, ctx_handle) =
test_helpers::make_subsystem_context::<AllMessages, _>(pool.clone());
let metrics = Metrics::default();
let v = test_with_executor_params(ctx_handle, || {
validate_candidate_exhaustive(
ctx.sender(),
MockValidateCandidateBackend::with_hardcoded_result_list(vec![
Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::Panic("foo".into()))),
// Throw an AWD error, we should still retry again.
Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::AmbiguousWorkerDeath)),
// Throw another panic error.
Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::Panic("bar".into()))),
]),
validation_data,
validation_code,
candidate_receipt,
Arc::new(pov),
PvfExecTimeoutKind::Backing,
&metrics,
)
});
let v = executor::block_on(validate_candidate_exhaustive(
MockValidateCandidateBackend::with_hardcoded_result_list(vec![
Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::Panic("foo".into()))),
// Throw an AWD error, we should still retry again.
Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::AmbiguousWorkerDeath)),
// Throw another panic error.
Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::Panic("bar".into()))),
]),
validation_data,
validation_code,
candidate_receipt,
Arc::new(pov),
ExecutorParams::default(),
PvfExecTimeoutKind::Backing,
&Default::default(),
));
assert_matches!(v, Ok(ValidationResult::Invalid(InvalidCandidate::ExecutionError(s))) if s == "bar".to_string());
}
@@ -813,25 +741,18 @@ fn candidate_validation_timeout_is_internal_error() {
let candidate_receipt = CandidateReceipt { descriptor, commitments_hash: Hash::zero() };
let pool = TaskExecutor::new();
let (mut ctx, ctx_handle) =
test_helpers::make_subsystem_context::<AllMessages, _>(pool.clone());
let metrics = Metrics::default();
let v = test_with_executor_params(ctx_handle, || {
validate_candidate_exhaustive(
ctx.sender(),
MockValidateCandidateBackend::with_hardcoded_result(Err(
ValidationError::InvalidCandidate(WasmInvalidCandidate::HardTimeout),
)),
validation_data,
validation_code,
candidate_receipt,
Arc::new(pov),
PvfExecTimeoutKind::Backing,
&metrics,
)
});
let v = executor::block_on(validate_candidate_exhaustive(
MockValidateCandidateBackend::with_hardcoded_result(Err(
ValidationError::InvalidCandidate(WasmInvalidCandidate::HardTimeout),
)),
validation_data,
validation_code,
candidate_receipt,
Arc::new(pov),
ExecutorParams::default(),
PvfExecTimeoutKind::Backing,
&Default::default(),
));
assert_matches!(v, Ok(ValidationResult::Invalid(InvalidCandidate::Timeout)));
}
@@ -867,23 +788,16 @@ fn candidate_validation_commitment_hash_mismatch_is_invalid() {
hrmp_watermark: 12345,
};
let pool = TaskExecutor::new();
let (mut ctx, ctx_handle) =
test_helpers::make_subsystem_context::<AllMessages, _>(pool.clone());
let metrics = Metrics::default();
let result = test_with_executor_params(ctx_handle, || {
validate_candidate_exhaustive(
ctx.sender(),
MockValidateCandidateBackend::with_hardcoded_result(Ok(validation_result)),
validation_data,
validation_code,
candidate_receipt,
Arc::new(pov),
PvfExecTimeoutKind::Backing,
&metrics,
)
})
let result = executor::block_on(validate_candidate_exhaustive(
MockValidateCandidateBackend::with_hardcoded_result(Ok(validation_result)),
validation_data,
validation_code,
candidate_receipt,
Arc::new(pov),
ExecutorParams::default(),
PvfExecTimeoutKind::Backing,
&Default::default(),
))
.unwrap();
// Ensure `post validation` check on the commitments hash works as expected.
@@ -919,11 +833,9 @@ fn candidate_validation_code_mismatch_is_invalid() {
let candidate_receipt = CandidateReceipt { descriptor, commitments_hash: Hash::zero() };
let pool = TaskExecutor::new();
let (mut ctx, _ctx_handle) =
test_helpers::make_subsystem_context::<AllMessages, _>(pool.clone());
let (_ctx, _ctx_handle) = test_helpers::make_subsystem_context::<AllMessages, _>(pool.clone());
let v = executor::block_on(validate_candidate_exhaustive(
ctx.sender(),
MockValidateCandidateBackend::with_hardcoded_result(Err(
ValidationError::InvalidCandidate(WasmInvalidCandidate::HardTimeout),
)),
@@ -931,6 +843,7 @@ fn candidate_validation_code_mismatch_is_invalid() {
validation_code,
candidate_receipt,
Arc::new(pov),
ExecutorParams::default(),
PvfExecTimeoutKind::Backing,
&Default::default(),
))
@@ -981,23 +894,16 @@ fn compressed_code_works() {
let candidate_receipt = CandidateReceipt { descriptor, commitments_hash: commitments.hash() };
let pool = TaskExecutor::new();
let (mut ctx, ctx_handle) =
test_helpers::make_subsystem_context::<AllMessages, _>(pool.clone());
let metrics = Metrics::default();
let v = test_with_executor_params(ctx_handle, || {
validate_candidate_exhaustive(
ctx.sender(),
MockValidateCandidateBackend::with_hardcoded_result(Ok(validation_result)),
validation_data,
validation_code,
candidate_receipt,
Arc::new(pov),
PvfExecTimeoutKind::Backing,
&metrics,
)
});
let v = executor::block_on(validate_candidate_exhaustive(
MockValidateCandidateBackend::with_hardcoded_result(Ok(validation_result)),
validation_data,
validation_code,
candidate_receipt,
Arc::new(pov),
ExecutorParams::default(),
PvfExecTimeoutKind::Backing,
&Default::default(),
));
assert_matches!(v, Ok(ValidationResult::Valid(_, _)));
}
@@ -1037,16 +943,15 @@ fn code_decompression_failure_is_error() {
let candidate_receipt = CandidateReceipt { descriptor, commitments_hash: Hash::zero() };
let pool = TaskExecutor::new();
let (mut ctx, _ctx_handle) =
test_helpers::make_subsystem_context::<AllMessages, _>(pool.clone());
let (_ctx, _ctx_handle) = test_helpers::make_subsystem_context::<AllMessages, _>(pool.clone());
let v = executor::block_on(validate_candidate_exhaustive(
ctx.sender(),
MockValidateCandidateBackend::with_hardcoded_result(Ok(validation_result)),
validation_data,
validation_code,
candidate_receipt,
Arc::new(pov),
ExecutorParams::default(),
PvfExecTimeoutKind::Backing,
&Default::default(),
));
@@ -1090,16 +995,15 @@ fn pov_decompression_failure_is_invalid() {
let candidate_receipt = CandidateReceipt { descriptor, commitments_hash: Hash::zero() };
let pool = TaskExecutor::new();
let (mut ctx, _ctx_handle) =
test_helpers::make_subsystem_context::<AllMessages, _>(pool.clone());
let (_ctx, _ctx_handle) = test_helpers::make_subsystem_context::<AllMessages, _>(pool.clone());
let v = executor::block_on(validate_candidate_exhaustive(
ctx.sender(),
MockValidateCandidateBackend::with_hardcoded_result(Ok(validation_result)),
validation_data,
validation_code,
candidate_receipt,
Arc::new(pov),
ExecutorParams::default(),
PvfExecTimeoutKind::Backing,
&Default::default(),
));
@@ -34,8 +34,9 @@ use polkadot_node_primitives::{
use polkadot_node_subsystem::overseer;
use polkadot_node_subsystem_util::runtime::RuntimeInfo;
use polkadot_primitives::{
CandidateReceipt, DisputeStatement, Hash, IndexedVec, SessionIndex, SessionInfo,
ValidDisputeStatementKind, ValidatorId, ValidatorIndex, ValidatorPair, ValidatorSignature,
CandidateReceipt, DisputeStatement, ExecutorParams, Hash, IndexedVec, SessionIndex,
SessionInfo, ValidDisputeStatementKind, ValidatorId, ValidatorIndex, ValidatorPair,
ValidatorSignature,
};
use sc_keystore::LocalKeystore;
@@ -47,6 +48,8 @@ pub struct CandidateEnvironment<'a> {
session_index: SessionIndex,
/// Session for above index.
session: &'a SessionInfo,
/// Executor parameters for the session.
executor_params: &'a ExecutorParams,
/// Validator indices controlled by this node.
controlled_indices: HashSet<ValidatorIndex>,
}
@@ -63,17 +66,17 @@ impl<'a> CandidateEnvironment<'a> {
session_index: SessionIndex,
relay_parent: Hash,
) -> Option<CandidateEnvironment<'a>> {
let session_info = match runtime_info
let (session, executor_params) = match runtime_info
.get_session_info_by_index(ctx.sender(), relay_parent, session_index)
.await
{
Ok(extended_session_info) => &extended_session_info.session_info,
Ok(extended_session_info) =>
(&extended_session_info.session_info, &extended_session_info.executor_params),
Err(_) => return None,
};
let controlled_indices =
find_controlled_validator_indices(keystore, &session_info.validators);
Some(Self { session_index, session: session_info, controlled_indices })
let controlled_indices = find_controlled_validator_indices(keystore, &session.validators);
Some(Self { session_index, session, executor_params, controlled_indices })
}
/// Validators in the candidate's session.
@@ -86,6 +89,11 @@ impl<'a> CandidateEnvironment<'a> {
&self.session
}
/// Executor parameters for the candidate's session
pub fn executor_params(&self) -> &ExecutorParams {
&self.executor_params
}
/// Retrieve `SessionIndex` for this environment.
pub fn session_index(&self) -> SessionIndex {
self.session_index
@@ -1160,6 +1160,7 @@ impl Initialized {
ParticipationRequest::new(
new_state.candidate_receipt().clone(),
session,
env.executor_params().clone(),
request_timer,
),
)
@@ -398,6 +398,7 @@ impl DisputeCoordinatorSubsystem {
ParticipationRequest::new(
vote_state.votes().candidate_receipt.clone(),
session,
env.executor_params().clone(),
request_timer,
),
));
@@ -366,6 +366,7 @@ async fn participate(
validation_code,
req.candidate_receipt().clone(),
available_data.pov,
req.executor_params(),
PvfExecTimeoutKind::Approval,
validation_tx,
))
@@ -21,7 +21,9 @@ use std::{
use futures::channel::oneshot;
use polkadot_node_subsystem::{messages::ChainApiMessage, overseer};
use polkadot_primitives::{BlockNumber, CandidateHash, CandidateReceipt, Hash, SessionIndex};
use polkadot_primitives::{
BlockNumber, CandidateHash, CandidateReceipt, ExecutorParams, Hash, SessionIndex,
};
use crate::{
error::{FatalError, FatalResult, Result},
@@ -73,6 +75,7 @@ pub struct ParticipationRequest {
candidate_hash: CandidateHash,
candidate_receipt: CandidateReceipt,
session: SessionIndex,
executor_params: ExecutorParams,
request_timer: Option<prometheus::HistogramTimer>, // Sends metric data when request is dropped
}
@@ -120,9 +123,16 @@ impl ParticipationRequest {
pub fn new(
candidate_receipt: CandidateReceipt,
session: SessionIndex,
executor_params: ExecutorParams,
request_timer: Option<prometheus::HistogramTimer>,
) -> Self {
Self { candidate_hash: candidate_receipt.hash(), candidate_receipt, session, request_timer }
Self {
candidate_hash: candidate_receipt.hash(),
candidate_receipt,
session,
executor_params,
request_timer,
}
}
pub fn candidate_receipt(&'_ self) -> &'_ CandidateReceipt {
@@ -134,6 +144,9 @@ impl ParticipationRequest {
pub fn session(&self) -> SessionIndex {
self.session
}
pub fn executor_params(&self) -> ExecutorParams {
self.executor_params.clone()
}
pub fn discard_timer(&mut self) {
if let Some(timer) = self.request_timer.take() {
timer.stop_and_discard();
@@ -150,11 +163,17 @@ impl ParticipationRequest {
#[cfg(test)]
impl PartialEq for ParticipationRequest {
fn eq(&self, other: &Self) -> bool {
let ParticipationRequest { candidate_receipt, candidate_hash, session, request_timer: _ } =
self;
let ParticipationRequest {
candidate_receipt,
candidate_hash,
session,
executor_params,
request_timer: _,
} = self;
candidate_receipt == other.candidate_receipt() &&
candidate_hash == other.candidate_hash() &&
*session == other.session()
*session == other.session() &&
executor_params.hash() == other.executor_params.hash()
}
}
#[cfg(test)]
@@ -27,7 +27,7 @@ fn make_participation_request(hash: Hash) -> ParticipationRequest {
// make it differ:
receipt.commitments_hash = hash;
let request_timer = Metrics::default().time_participation_pipeline();
ParticipationRequest::new(receipt, 1, request_timer)
ParticipationRequest::new(receipt, 1, Default::default(), request_timer)
}
/// Make dummy comparator for request, based on the given block number.
@@ -46,6 +46,7 @@ fn clone_request(request: &ParticipationRequest) -> ParticipationRequest {
candidate_receipt: request.candidate_receipt.clone(),
candidate_hash: request.candidate_hash,
session: request.session,
executor_params: request.executor_params.clone(),
request_timer: None,
}
}
@@ -73,7 +73,8 @@ async fn participate_with_commitments_hash<Context>(
let session = 1;
let request_timer = participation.metrics.time_participation_pipeline();
let req = ParticipationRequest::new(candidate_receipt, session, request_timer);
let req =
ParticipationRequest::new(candidate_receipt, session, Default::default(), request_timer);
participation
.queue_participation(ctx, ParticipationPriority::BestEffort, req)
@@ -120,7 +121,7 @@ pub async fn participation_full_happy_path(
assert_matches!(
ctx_handle.recv().await,
AllMessages::CandidateValidation(
CandidateValidationMessage::ValidateFromExhaustive(_, _, candidate_receipt, _, timeout, tx)
CandidateValidationMessage::ValidateFromExhaustive(_, _, candidate_receipt, _, _, timeout, tx)
) if timeout == PvfExecTimeoutKind::Approval => {
if expected_commitments_hash != candidate_receipt.commitments_hash {
tx.send(Ok(ValidationResult::Invalid(InvalidCandidate::CommitmentsHashMismatch))).unwrap();
@@ -455,7 +456,7 @@ fn cast_invalid_vote_if_validation_fails_or_is_invalid() {
assert_matches!(
ctx_handle.recv().await,
AllMessages::CandidateValidation(
CandidateValidationMessage::ValidateFromExhaustive(_, _, _, _, timeout, tx)
CandidateValidationMessage::ValidateFromExhaustive(_, _, _, _, _, timeout, tx)
) if timeout == PvfExecTimeoutKind::Approval => {
tx.send(Ok(ValidationResult::Invalid(InvalidCandidate::Timeout))).unwrap();
},
@@ -492,7 +493,7 @@ fn cast_invalid_vote_if_commitments_dont_match() {
assert_matches!(
ctx_handle.recv().await,
AllMessages::CandidateValidation(
CandidateValidationMessage::ValidateFromExhaustive(_, _, _, _, timeout, tx)
CandidateValidationMessage::ValidateFromExhaustive(_, _, _, _, _, timeout, tx)
) if timeout == PvfExecTimeoutKind::Approval => {
tx.send(Ok(ValidationResult::Invalid(InvalidCandidate::CommitmentsHashMismatch))).unwrap();
},
@@ -529,7 +530,7 @@ fn cast_valid_vote_if_validation_passes() {
assert_matches!(
ctx_handle.recv().await,
AllMessages::CandidateValidation(
CandidateValidationMessage::ValidateFromExhaustive(_, _, _, _, timeout, tx)
CandidateValidationMessage::ValidateFromExhaustive(_, _, _, _, _, timeout, tx)
) if timeout == PvfExecTimeoutKind::Approval => {
tx.send(Ok(ValidationResult::Valid(dummy_candidate_commitments(None), PersistedValidationData::default()))).unwrap();
},
@@ -63,9 +63,9 @@ use polkadot_node_subsystem_test_helpers::{
};
use polkadot_primitives::{
ApprovalVote, BlockNumber, CandidateCommitments, CandidateEvent, CandidateHash,
CandidateReceipt, CoreIndex, DisputeStatement, GroupIndex, Hash, HeadData, Header, IndexedVec,
MultiDisputeStatementSet, ScrapedOnChainVotes, SessionIndex, SessionInfo, SigningContext,
ValidDisputeStatementKind, ValidatorId, ValidatorIndex, ValidatorSignature,
CandidateReceipt, CoreIndex, DisputeStatement, ExecutorParams, GroupIndex, Hash, HeadData,
Header, IndexedVec, MultiDisputeStatementSet, ScrapedOnChainVotes, SessionIndex, SessionInfo,
SigningContext, ValidDisputeStatementKind, ValidatorId, ValidatorIndex, ValidatorSignature,
};
use crate::{
@@ -347,6 +347,17 @@ impl TestState {
let _ = tx.send(Ok(Some(self.session_info())));
}
);
assert_matches!(
overseer_recv(virtual_overseer).await,
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
h,
RuntimeApiRequest::SessionExecutorParams(session_index, tx),
)) => {
assert_eq!(h, block_hash);
assert_eq!(session_index, i);
let _ = tx.send(Ok(Some(ExecutorParams::default())));
}
);
}
}
@@ -3482,6 +3493,16 @@ fn session_info_is_requested_only_once() {
let _ = tx.send(Ok(Some(test_state.session_info())));
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
_,
RuntimeApiRequest::SessionExecutorParams(session_index, tx),
)) => {
assert_eq!(session_index, 2);
let _ = tx.send(Ok(Some(ExecutorParams::default())));
}
);
test_state
})
});
@@ -3532,6 +3553,16 @@ fn session_info_big_jump_works() {
let _ = tx.send(Ok(Some(test_state.session_info())));
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
_,
RuntimeApiRequest::SessionExecutorParams(session_index, tx),
)) => {
assert_eq!(session_index, expected_idx);
let _ = tx.send(Ok(Some(ExecutorParams::default())));
}
);
}
test_state
})
@@ -3582,6 +3613,16 @@ fn session_info_small_jump_works() {
let _ = tx.send(Ok(Some(test_state.session_info())));
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
_,
RuntimeApiRequest::SessionExecutorParams(session_index, tx),
)) => {
assert_eq!(session_index, expected_idx);
let _ = tx.send(Ok(Some(ExecutorParams::default())));
}
);
}
test_state
})
+1 -1
View File
@@ -258,7 +258,7 @@ async fn execute_queue_doesnt_stall_with_varying_executor_params() {
#[tokio::test]
async fn deleting_prepared_artifact_does_not_dispute() {
let host = TestHost::new();
let cache_dir = host.cache_dir.path().clone();
let cache_dir = host.cache_dir.path();
let result = host
.validate_candidate(