1#![deny(unused_crate_dependencies)]
23#![warn(missing_docs)]
24
25use polkadot_node_subsystem::{
26 errors::RuntimeApiError,
27 messages::{RuntimeApiMessage, RuntimeApiRequest as Request},
28 overseer, FromOrchestra, OverseerSignal, SpawnedSubsystem, SubsystemError, SubsystemResult,
29};
30use polkadot_node_subsystem_types::RuntimeApiSubsystemClient;
31use polkadot_primitives::Hash;
32
33use cache::{RequestResult, RequestResultCache};
34use futures::{channel::oneshot, prelude::*, select, stream::FuturesUnordered};
35use std::sync::Arc;
36
37mod cache;
38
39mod metrics;
40use self::metrics::Metrics;
41
42#[cfg(test)]
43mod tests;
44
45const LOG_TARGET: &str = "parachain::runtime-api";
46
47const MAX_PARALLEL_REQUESTS: usize = 4;
50
51const API_REQUEST_TASK_NAME: &str = "polkadot-runtime-api-request";
53
54pub struct RuntimeApiSubsystem<Client> {
56 client: Arc<Client>,
57 metrics: Metrics,
58 spawn_handle: Box<dyn overseer::gen::Spawner>,
59 active_requests: FuturesUnordered<oneshot::Receiver<Option<RequestResult>>>,
61 requests_cache: RequestResultCache,
63}
64
65impl<Client> RuntimeApiSubsystem<Client> {
66 pub fn new(
68 client: Arc<Client>,
69 metrics: Metrics,
70 spawner: impl overseer::gen::Spawner + 'static,
71 ) -> Self {
72 RuntimeApiSubsystem {
73 client,
74 metrics,
75 spawn_handle: Box::new(spawner),
76 active_requests: Default::default(),
77 requests_cache: RequestResultCache::default(),
78 }
79 }
80}
81
82#[overseer::subsystem(RuntimeApi, error = SubsystemError, prefix = self::overseer)]
83impl<Client, Context> RuntimeApiSubsystem<Client>
84where
85 Client: RuntimeApiSubsystemClient + Send + Sync + 'static,
86{
87 fn start(self, ctx: Context) -> SpawnedSubsystem {
88 SpawnedSubsystem { future: run(ctx, self).boxed(), name: "runtime-api-subsystem" }
89 }
90}
91
92impl<Client> RuntimeApiSubsystem<Client>
93where
94 Client: RuntimeApiSubsystemClient + Send + 'static + Sync,
95{
96 fn store_cache(&mut self, result: RequestResult) {
97 use RequestResult::*;
98
99 match result {
100 Authorities(relay_parent, authorities) =>
101 self.requests_cache.cache_authorities(relay_parent, authorities),
102 Validators(relay_parent, validators) =>
103 self.requests_cache.cache_validators(relay_parent, validators),
104 MinimumBackingVotes(session_index, minimum_backing_votes) => self
105 .requests_cache
106 .cache_minimum_backing_votes(session_index, minimum_backing_votes),
107 ValidatorGroups(relay_parent, groups) =>
108 self.requests_cache.cache_validator_groups(relay_parent, groups),
109 AvailabilityCores(relay_parent, cores) =>
110 self.requests_cache.cache_availability_cores(relay_parent, cores),
111 PersistedValidationData(relay_parent, para_id, assumption, data) => self
112 .requests_cache
113 .cache_persisted_validation_data((relay_parent, para_id, assumption), data),
114 AssumedValidationData(
115 _relay_parent,
116 para_id,
117 expected_persisted_validation_data_hash,
118 data,
119 ) => self.requests_cache.cache_assumed_validation_data(
120 (para_id, expected_persisted_validation_data_hash),
121 data,
122 ),
123 CheckValidationOutputs(relay_parent, para_id, commitments, b) => self
124 .requests_cache
125 .cache_check_validation_outputs((relay_parent, para_id, commitments), b),
126 SessionIndexForChild(relay_parent, session_index) =>
127 self.requests_cache.cache_session_index_for_child(relay_parent, session_index),
128 ValidationCode(relay_parent, para_id, assumption, code) => self
129 .requests_cache
130 .cache_validation_code((relay_parent, para_id, assumption), code),
131 ValidationCodeByHash(_relay_parent, validation_code_hash, code) =>
132 self.requests_cache.cache_validation_code_by_hash(validation_code_hash, code),
133 CandidatePendingAvailability(relay_parent, para_id, candidate) => self
134 .requests_cache
135 .cache_candidate_pending_availability((relay_parent, para_id), candidate),
136 CandidatesPendingAvailability(relay_parent, para_id, candidates) => self
137 .requests_cache
138 .cache_candidates_pending_availability((relay_parent, para_id), candidates),
139 CandidateEvents(relay_parent, events) =>
140 self.requests_cache.cache_candidate_events(relay_parent, events),
141 SessionExecutorParams(_relay_parent, session_index, index) =>
142 self.requests_cache.cache_session_executor_params(session_index, index),
143 SessionInfo(_relay_parent, session_index, info) =>
144 if let Some(info) = info {
145 self.requests_cache.cache_session_info(session_index, info);
146 },
147 DmqContents(relay_parent, para_id, messages) =>
148 self.requests_cache.cache_dmq_contents((relay_parent, para_id), messages),
149 InboundHrmpChannelsContents(relay_parent, para_id, contents) => self
150 .requests_cache
151 .cache_inbound_hrmp_channel_contents((relay_parent, para_id), contents),
152 CurrentBabeEpoch(relay_parent, epoch) =>
153 self.requests_cache.cache_current_babe_epoch(relay_parent, epoch),
154 FetchOnChainVotes(relay_parent, scraped) =>
155 self.requests_cache.cache_on_chain_votes(relay_parent, scraped),
156 PvfsRequirePrecheck(relay_parent, pvfs) =>
157 self.requests_cache.cache_pvfs_require_precheck(relay_parent, pvfs),
158 SubmitPvfCheckStatement(()) => {},
159 ValidationCodeHash(relay_parent, para_id, assumption, hash) => self
160 .requests_cache
161 .cache_validation_code_hash((relay_parent, para_id, assumption), hash),
162 Version(relay_parent, version) =>
163 self.requests_cache.cache_version(relay_parent, version),
164 Disputes(relay_parent, disputes) =>
165 self.requests_cache.cache_disputes(relay_parent, disputes),
166 UnappliedSlashes(relay_parent, unapplied_slashes) =>
167 self.requests_cache.cache_unapplied_slashes(relay_parent, unapplied_slashes),
168 UnappliedSlashesV2(relay_parent, unapplied_slashes_v2) => self
169 .requests_cache
170 .cache_unapplied_slashes_v2(relay_parent, unapplied_slashes_v2),
171 KeyOwnershipProof(relay_parent, validator_id, key_ownership_proof) => self
172 .requests_cache
173 .cache_key_ownership_proof((relay_parent, validator_id), key_ownership_proof),
174 ApprovalVotingParams(_relay_parent, session_index, params) =>
175 self.requests_cache.cache_approval_voting_params(session_index, params),
176 SubmitReportDisputeLost(_) => {},
177 DisabledValidators(relay_parent, disabled_validators) =>
178 self.requests_cache.cache_disabled_validators(relay_parent, disabled_validators),
179 ParaBackingState(relay_parent, para_id, constraints) => self
180 .requests_cache
181 .cache_para_backing_state((relay_parent, para_id), constraints),
182 AsyncBackingParams(relay_parent, params) =>
183 self.requests_cache.cache_async_backing_params(relay_parent, params),
184 NodeFeatures(session_index, params) =>
185 self.requests_cache.cache_node_features(session_index, params),
186 ClaimQueue(relay_parent, sender) => {
187 self.requests_cache.cache_claim_queue(relay_parent, sender);
188 },
189 BackingConstraints(relay_parent, para_id, constraints) => self
190 .requests_cache
191 .cache_backing_constraints((relay_parent, para_id), constraints),
192 SchedulingLookahead(session_index, scheduling_lookahead) => self
193 .requests_cache
194 .cache_scheduling_lookahead(session_index, scheduling_lookahead),
195 ValidationCodeBombLimit(session_index, limit) =>
196 self.requests_cache.cache_validation_code_bomb_limit(session_index, limit),
197 ParaIds(session_index, para_ids) => {
198 self.requests_cache.cache_para_ids(session_index, para_ids);
199 },
200 }
201 }
202
203 fn query_cache(&mut self, relay_parent: Hash, request: Request) -> Option<Request> {
204 macro_rules! query {
205 ($cache_api_name:ident (), $sender:expr) => {{
207 let sender = $sender;
208 if let Some(value) = self.requests_cache.$cache_api_name(&relay_parent) {
209 let _ = sender.send(Ok(value.clone()));
210 self.metrics.on_cached_request();
211 None
212 } else {
213 Some(sender)
214 }
215 }};
216 ($cache_api_name:ident ($($param:expr),+), $sender:expr) => {{
218 let sender = $sender;
219 if let Some(value) = self.requests_cache.$cache_api_name((relay_parent.clone(), $($param.clone()),+)) {
220 self.metrics.on_cached_request();
221 let _ = sender.send(Ok(value.clone()));
222 None
223 } else {
224 Some(sender)
225 }
226 }}
227 }
228
229 match request {
230 Request::Version(sender) =>
231 query!(version(), sender).map(|sender| Request::Version(sender)),
232 Request::Authorities(sender) =>
233 query!(authorities(), sender).map(|sender| Request::Authorities(sender)),
234 Request::Validators(sender) =>
235 query!(validators(), sender).map(|sender| Request::Validators(sender)),
236 Request::ValidatorGroups(sender) =>
237 query!(validator_groups(), sender).map(|sender| Request::ValidatorGroups(sender)),
238 Request::AvailabilityCores(sender) => query!(availability_cores(), sender)
239 .map(|sender| Request::AvailabilityCores(sender)),
240 Request::PersistedValidationData(para, assumption, sender) =>
241 query!(persisted_validation_data(para, assumption), sender)
242 .map(|sender| Request::PersistedValidationData(para, assumption, sender)),
243 Request::AssumedValidationData(
244 para,
245 expected_persisted_validation_data_hash,
246 sender,
247 ) => query!(
248 assumed_validation_data(para, expected_persisted_validation_data_hash),
249 sender
250 )
251 .map(|sender| {
252 Request::AssumedValidationData(
253 para,
254 expected_persisted_validation_data_hash,
255 sender,
256 )
257 }),
258 Request::CheckValidationOutputs(para, commitments, sender) =>
259 query!(check_validation_outputs(para, commitments), sender)
260 .map(|sender| Request::CheckValidationOutputs(para, commitments, sender)),
261 Request::SessionIndexForChild(sender) => query!(session_index_for_child(), sender)
262 .map(|sender| Request::SessionIndexForChild(sender)),
263 Request::ValidationCode(para, assumption, sender) =>
264 query!(validation_code(para, assumption), sender)
265 .map(|sender| Request::ValidationCode(para, assumption, sender)),
266 Request::ValidationCodeByHash(validation_code_hash, sender) =>
267 query!(validation_code_by_hash(validation_code_hash), sender)
268 .map(|sender| Request::ValidationCodeByHash(validation_code_hash, sender)),
269 Request::CandidatePendingAvailability(para, sender) =>
270 query!(candidate_pending_availability(para), sender)
271 .map(|sender| Request::CandidatePendingAvailability(para, sender)),
272 Request::CandidatesPendingAvailability(para, sender) =>
273 query!(candidates_pending_availability(para), sender)
274 .map(|sender| Request::CandidatesPendingAvailability(para, sender)),
275 Request::CandidateEvents(sender) =>
276 query!(candidate_events(), sender).map(|sender| Request::CandidateEvents(sender)),
277 Request::SessionExecutorParams(session_index, sender) => {
278 if let Some(executor_params) =
279 self.requests_cache.session_executor_params(session_index)
280 {
281 self.metrics.on_cached_request();
282 let _ = sender.send(Ok(executor_params.clone()));
283 None
284 } else {
285 Some(Request::SessionExecutorParams(session_index, sender))
286 }
287 },
288 Request::SessionInfo(index, sender) => {
289 if let Some(info) = self.requests_cache.session_info(index) {
290 self.metrics.on_cached_request();
291 let _ = sender.send(Ok(Some(info.clone())));
292 None
293 } else {
294 Some(Request::SessionInfo(index, sender))
295 }
296 },
297 Request::DmqContents(id, sender) =>
298 query!(dmq_contents(id), sender).map(|sender| Request::DmqContents(id, sender)),
299 Request::InboundHrmpChannelsContents(id, sender) =>
300 query!(inbound_hrmp_channels_contents(id), sender)
301 .map(|sender| Request::InboundHrmpChannelsContents(id, sender)),
302 Request::CurrentBabeEpoch(sender) =>
303 query!(current_babe_epoch(), sender).map(|sender| Request::CurrentBabeEpoch(sender)),
304 Request::FetchOnChainVotes(sender) =>
305 query!(on_chain_votes(), sender).map(|sender| Request::FetchOnChainVotes(sender)),
306 Request::PvfsRequirePrecheck(sender) => query!(pvfs_require_precheck(), sender)
307 .map(|sender| Request::PvfsRequirePrecheck(sender)),
308 request @ Request::SubmitPvfCheckStatement(_, _, _) => {
309 Some(request)
311 },
312 Request::ValidationCodeHash(para, assumption, sender) =>
313 query!(validation_code_hash(para, assumption), sender)
314 .map(|sender| Request::ValidationCodeHash(para, assumption, sender)),
315 Request::Disputes(sender) =>
316 query!(disputes(), sender).map(|sender| Request::Disputes(sender)),
317 Request::UnappliedSlashes(sender) =>
318 query!(unapplied_slashes(), sender).map(|sender| Request::UnappliedSlashes(sender)),
319 Request::UnappliedSlashesV2(sender) => query!(unapplied_slashes_v2(), sender)
320 .map(|sender| Request::UnappliedSlashesV2(sender)),
321 Request::KeyOwnershipProof(validator_id, sender) =>
322 query!(key_ownership_proof(validator_id), sender)
323 .map(|sender| Request::KeyOwnershipProof(validator_id, sender)),
324 Request::SubmitReportDisputeLost(dispute_proof, key_ownership_proof, sender) =>
325 query!(submit_report_dispute_lost(dispute_proof, key_ownership_proof), sender).map(
326 |sender| {
327 Request::SubmitReportDisputeLost(dispute_proof, key_ownership_proof, sender)
328 },
329 ),
330 Request::ApprovalVotingParams(session_index, sender) =>
331 query!(approval_voting_params(session_index), sender)
332 .map(|sender| Request::ApprovalVotingParams(session_index, sender)),
333 Request::DisabledValidators(sender) => query!(disabled_validators(), sender)
334 .map(|sender| Request::DisabledValidators(sender)),
335 Request::ParaBackingState(para, sender) => query!(para_backing_state(para), sender)
336 .map(|sender| Request::ParaBackingState(para, sender)),
337 Request::AsyncBackingParams(sender) => query!(async_backing_params(), sender)
338 .map(|sender| Request::AsyncBackingParams(sender)),
339 Request::MinimumBackingVotes(index, sender) => {
340 if let Some(value) = self.requests_cache.minimum_backing_votes(index) {
341 self.metrics.on_cached_request();
342 let _ = sender.send(Ok(value));
343 None
344 } else {
345 Some(Request::MinimumBackingVotes(index, sender))
346 }
347 },
348 Request::NodeFeatures(index, sender) => {
349 if let Some(value) = self.requests_cache.node_features(index) {
350 self.metrics.on_cached_request();
351 let _ = sender.send(Ok(value.clone()));
352 None
353 } else {
354 Some(Request::NodeFeatures(index, sender))
355 }
356 },
357 Request::ClaimQueue(sender) =>
358 query!(claim_queue(), sender).map(|sender| Request::ClaimQueue(sender)),
359 Request::BackingConstraints(para, sender) => query!(backing_constraints(para), sender)
360 .map(|sender| Request::BackingConstraints(para, sender)),
361 Request::SchedulingLookahead(index, sender) => {
362 if let Some(value) = self.requests_cache.scheduling_lookahead(index) {
363 self.metrics.on_cached_request();
364 let _ = sender.send(Ok(value));
365 None
366 } else {
367 Some(Request::SchedulingLookahead(index, sender))
368 }
369 },
370 Request::ValidationCodeBombLimit(index, sender) => {
371 if let Some(value) = self.requests_cache.validation_code_bomb_limit(index) {
372 self.metrics.on_cached_request();
373 let _ = sender.send(Ok(value));
374 None
375 } else {
376 Some(Request::ValidationCodeBombLimit(index, sender))
377 }
378 },
379 Request::ParaIds(index, sender) => {
380 if let Some(value) = self.requests_cache.para_ids(index) {
381 self.metrics.on_cached_request();
382 let _ = sender.send(Ok(value.clone()));
383 None
384 } else {
385 Some(Request::ParaIds(index, sender))
386 }
387 },
388 }
389 }
390
391 fn spawn_request(&mut self, relay_parent: Hash, request: Request) {
393 let client = self.client.clone();
394 let metrics = self.metrics.clone();
395 let (sender, receiver) = oneshot::channel();
396
397 let request = match self.query_cache(relay_parent, request) {
399 Some(request) => request,
400 None => return,
401 };
402
403 let request = async move {
404 let result = make_runtime_api_request(client, metrics, relay_parent, request).await;
405 let _ = sender.send(result);
406 }
407 .boxed();
408
409 self.spawn_handle
410 .spawn_blocking(API_REQUEST_TASK_NAME, Some("runtime-api"), request);
411 self.active_requests.push(receiver);
412 }
413
414 async fn poll_requests(&mut self) {
416 if self.active_requests.len() == 0 {
418 return futures::pending!();
419 }
420
421 if let Some(Ok(Some(result))) = self.active_requests.next().await {
424 self.store_cache(result);
425 }
426 }
427
428 fn is_busy(&self) -> bool {
430 self.active_requests.len() >= MAX_PARALLEL_REQUESTS
431 }
432}
433
434#[overseer::contextbounds(RuntimeApi, prefix = self::overseer)]
435async fn run<Client, Context>(
436 mut ctx: Context,
437 mut subsystem: RuntimeApiSubsystem<Client>,
438) -> SubsystemResult<()>
439where
440 Client: RuntimeApiSubsystemClient + Send + Sync + 'static,
441{
442 loop {
443 if subsystem.is_busy() {
449 let _ = subsystem.poll_requests().await;
452 }
453
454 select! {
455 req = ctx.recv().fuse() => match req? {
456 FromOrchestra::Signal(OverseerSignal::Conclude) => return Ok(()),
457 FromOrchestra::Signal(OverseerSignal::ActiveLeaves(_)) => {},
458 FromOrchestra::Signal(OverseerSignal::BlockFinalized(..)) => {},
459 FromOrchestra::Communication { msg } => match msg {
460 RuntimeApiMessage::Request(relay_parent, request) => {
461 subsystem.spawn_request(relay_parent, request);
462 },
463 }
464 },
465 _ = subsystem.poll_requests().fuse() => {},
466 }
467 }
468}
469
470async fn make_runtime_api_request<Client>(
471 client: Arc<Client>,
472 metrics: Metrics,
473 relay_parent: Hash,
474 request: Request,
475) -> Option<RequestResult>
476where
477 Client: RuntimeApiSubsystemClient + 'static,
478{
479 let _timer = metrics.time_make_runtime_api_request();
480
481 macro_rules! query {
482 ($req_variant:ident, $api_name:ident ($($param:expr),*), ver = $version:expr, $sender:expr) => {{
483 query!($req_variant, $api_name($($param),*), ver = $version, $sender, result = ( relay_parent $(, $param )* ) )
484 }};
485 ($req_variant:ident, $api_name:ident ($($param:expr),*), ver = $version:expr, $sender:expr, result = ( $($results:expr),* ) ) => {{
486 let sender = $sender;
487 let version: u32 = $version; let runtime_version = client.api_version_parachain_host(relay_parent).await
489 .unwrap_or_else(|e| {
490 gum::warn!(
491 target: LOG_TARGET,
492 api = ?stringify!($api_name),
493 "cannot query the runtime API version: {}",
494 e,
495 );
496 Some(0)
497 })
498 .unwrap_or_else(|| {
499 gum::warn!(
500 target: LOG_TARGET,
501 "no runtime version is reported"
502 );
503 0
504 });
505
506 let res = if runtime_version >= version {
507 client.$api_name(relay_parent $(, $param.clone() )*).await
508 .map_err(|e| RuntimeApiError::Execution {
509 runtime_api_name: stringify!($api_name),
510 source: std::sync::Arc::new(e),
511 })
512 } else {
513 Err(RuntimeApiError::NotSupported {
514 runtime_api_name: stringify!($api_name),
515 })
516 };
517 metrics.on_request(res.is_ok());
518 let _ = sender.send(res.clone());
519
520 res.ok().map(|res| RequestResult::$req_variant($( $results, )* res))
521 }}
522 }
523
524 match request {
525 Request::Version(sender) => {
526 let runtime_version = match client.api_version_parachain_host(relay_parent).await {
527 Ok(Some(v)) => Ok(v),
528 Ok(None) => Err(RuntimeApiError::NotSupported { runtime_api_name: "api_version" }),
529 Err(e) => Err(RuntimeApiError::Execution {
530 runtime_api_name: "api_version",
531 source: std::sync::Arc::new(e),
532 }),
533 };
534
535 let _ = sender.send(runtime_version.clone());
536 runtime_version.ok().map(|v| RequestResult::Version(relay_parent, v))
537 },
538
539 Request::Authorities(sender) => query!(Authorities, authorities(), ver = 1, sender),
540 Request::Validators(sender) => query!(Validators, validators(), ver = 1, sender),
541 Request::ValidatorGroups(sender) => {
542 query!(ValidatorGroups, validator_groups(), ver = 1, sender)
543 },
544 Request::AvailabilityCores(sender) => {
545 query!(AvailabilityCores, availability_cores(), ver = 1, sender)
546 },
547 Request::PersistedValidationData(para, assumption, sender) => query!(
548 PersistedValidationData,
549 persisted_validation_data(para, assumption),
550 ver = 1,
551 sender
552 ),
553 Request::AssumedValidationData(para, expected_persisted_validation_data_hash, sender) => {
554 query!(
555 AssumedValidationData,
556 assumed_validation_data(para, expected_persisted_validation_data_hash),
557 ver = 1,
558 sender
559 )
560 },
561 Request::CheckValidationOutputs(para, commitments, sender) => query!(
562 CheckValidationOutputs,
563 check_validation_outputs(para, commitments),
564 ver = 1,
565 sender
566 ),
567 Request::SessionIndexForChild(sender) => {
568 query!(SessionIndexForChild, session_index_for_child(), ver = 1, sender)
569 },
570 Request::ValidationCode(para, assumption, sender) => {
571 query!(ValidationCode, validation_code(para, assumption), ver = 1, sender)
572 },
573 Request::ValidationCodeByHash(validation_code_hash, sender) => query!(
574 ValidationCodeByHash,
575 validation_code_by_hash(validation_code_hash),
576 ver = 1,
577 sender
578 ),
579 Request::CandidatePendingAvailability(para, sender) => query!(
580 CandidatePendingAvailability,
581 candidate_pending_availability(para),
582 ver = 1,
583 sender
584 ),
585 Request::CandidatesPendingAvailability(para, sender) => query!(
586 CandidatesPendingAvailability,
587 candidates_pending_availability(para),
588 ver = Request::CANDIDATES_PENDING_AVAILABILITY_RUNTIME_REQUIREMENT,
589 sender
590 ),
591 Request::CandidateEvents(sender) => {
592 query!(CandidateEvents, candidate_events(), ver = 1, sender)
593 },
594 Request::SessionInfo(index, sender) => {
595 query!(SessionInfo, session_info(index), ver = 2, sender)
596 },
597 Request::SessionExecutorParams(session_index, sender) => query!(
598 SessionExecutorParams,
599 session_executor_params(session_index),
600 ver = Request::EXECUTOR_PARAMS_RUNTIME_REQUIREMENT,
601 sender
602 ),
603 Request::DmqContents(id, sender) => query!(DmqContents, dmq_contents(id), ver = 1, sender),
604 Request::InboundHrmpChannelsContents(id, sender) => {
605 query!(InboundHrmpChannelsContents, inbound_hrmp_channels_contents(id), ver = 1, sender)
606 },
607 Request::CurrentBabeEpoch(sender) => {
608 query!(CurrentBabeEpoch, current_epoch(), ver = 1, sender)
609 },
610 Request::FetchOnChainVotes(sender) => {
611 query!(FetchOnChainVotes, on_chain_votes(), ver = 1, sender)
612 },
613 Request::SubmitPvfCheckStatement(stmt, signature, sender) => {
614 query!(
615 SubmitPvfCheckStatement,
616 submit_pvf_check_statement(stmt, signature),
617 ver = 2,
618 sender,
619 result = ()
620 )
621 },
622 Request::PvfsRequirePrecheck(sender) => {
623 query!(PvfsRequirePrecheck, pvfs_require_precheck(), ver = 2, sender)
624 },
625 Request::ValidationCodeHash(para, assumption, sender) => {
626 query!(ValidationCodeHash, validation_code_hash(para, assumption), ver = 2, sender)
627 },
628 Request::Disputes(sender) => {
629 query!(Disputes, disputes(), ver = Request::DISPUTES_RUNTIME_REQUIREMENT, sender)
630 },
631 Request::UnappliedSlashes(sender) => query!(
632 UnappliedSlashes,
633 unapplied_slashes(),
634 ver = Request::UNAPPLIED_SLASHES_RUNTIME_REQUIREMENT,
635 sender
636 ),
637 Request::KeyOwnershipProof(validator_id, sender) => query!(
638 KeyOwnershipProof,
639 key_ownership_proof(validator_id),
640 ver = Request::KEY_OWNERSHIP_PROOF_RUNTIME_REQUIREMENT,
641 sender
642 ),
643 Request::ApprovalVotingParams(session_index, sender) => {
644 query!(
645 ApprovalVotingParams,
646 approval_voting_params(session_index),
647 ver = Request::APPROVAL_VOTING_PARAMS_REQUIREMENT,
648 sender
649 )
650 },
651 Request::SubmitReportDisputeLost(dispute_proof, key_ownership_proof, sender) => query!(
652 SubmitReportDisputeLost,
653 submit_report_dispute_lost(dispute_proof, key_ownership_proof),
654 ver = Request::SUBMIT_REPORT_DISPUTE_LOST_RUNTIME_REQUIREMENT,
655 sender,
656 result = ()
657 ),
658 Request::MinimumBackingVotes(index, sender) => query!(
659 MinimumBackingVotes,
660 minimum_backing_votes(index),
661 ver = Request::MINIMUM_BACKING_VOTES_RUNTIME_REQUIREMENT,
662 sender,
663 result = (index)
664 ),
665 Request::DisabledValidators(sender) => query!(
666 DisabledValidators,
667 disabled_validators(),
668 ver = Request::DISABLED_VALIDATORS_RUNTIME_REQUIREMENT,
669 sender
670 ),
671 Request::ParaBackingState(para, sender) => {
672 query!(
673 ParaBackingState,
674 para_backing_state(para),
675 ver = Request::ASYNC_BACKING_STATE_RUNTIME_REQUIREMENT,
676 sender
677 )
678 },
679 Request::AsyncBackingParams(sender) => {
680 query!(
681 AsyncBackingParams,
682 async_backing_params(),
683 ver = Request::ASYNC_BACKING_STATE_RUNTIME_REQUIREMENT,
684 sender
685 )
686 },
687 Request::NodeFeatures(index, sender) => query!(
688 NodeFeatures,
689 node_features(),
690 ver = Request::NODE_FEATURES_RUNTIME_REQUIREMENT,
691 sender,
692 result = (index)
693 ),
694 Request::ClaimQueue(sender) => query!(
695 ClaimQueue,
696 claim_queue(),
697 ver = Request::CLAIM_QUEUE_RUNTIME_REQUIREMENT,
698 sender
699 ),
700 Request::BackingConstraints(para, sender) => {
701 query!(
702 BackingConstraints,
703 backing_constraints(para),
704 ver = Request::CONSTRAINTS_RUNTIME_REQUIREMENT,
705 sender
706 )
707 },
708 Request::SchedulingLookahead(index, sender) => query!(
709 SchedulingLookahead,
710 scheduling_lookahead(),
711 ver = Request::SCHEDULING_LOOKAHEAD_RUNTIME_REQUIREMENT,
712 sender,
713 result = (index)
714 ),
715 Request::ValidationCodeBombLimit(index, sender) => query!(
716 ValidationCodeBombLimit,
717 validation_code_bomb_limit(),
718 ver = Request::VALIDATION_CODE_BOMB_LIMIT_RUNTIME_REQUIREMENT,
719 sender,
720 result = (index)
721 ),
722 Request::ParaIds(index, sender) => query!(
723 ParaIds,
724 para_ids(),
725 ver = Request::PARAIDS_RUNTIME_REQUIREMENT,
726 sender,
727 result = (index)
728 ),
729 Request::UnappliedSlashesV2(sender) => query!(
730 UnappliedSlashesV2,
731 unapplied_slashes_v2(),
732 ver = Request::UNAPPLIED_SLASHES_V2_RUNTIME_REQUIREMENT,
733 sender
734 ),
735 }
736}