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 KeyOwnershipProof(relay_parent, validator_id, key_ownership_proof) => self
169 .requests_cache
170 .cache_key_ownership_proof((relay_parent, validator_id), key_ownership_proof),
171 ApprovalVotingParams(_relay_parent, session_index, params) =>
172 self.requests_cache.cache_approval_voting_params(session_index, params),
173 SubmitReportDisputeLost(_) => {},
174 DisabledValidators(relay_parent, disabled_validators) =>
175 self.requests_cache.cache_disabled_validators(relay_parent, disabled_validators),
176 ParaBackingState(relay_parent, para_id, constraints) => self
177 .requests_cache
178 .cache_para_backing_state((relay_parent, para_id), constraints),
179 AsyncBackingParams(relay_parent, params) =>
180 self.requests_cache.cache_async_backing_params(relay_parent, params),
181 NodeFeatures(session_index, params) =>
182 self.requests_cache.cache_node_features(session_index, params),
183 ClaimQueue(relay_parent, sender) => {
184 self.requests_cache.cache_claim_queue(relay_parent, sender);
185 },
186 BackingConstraints(relay_parent, para_id, constraints) => self
187 .requests_cache
188 .cache_backing_constraints((relay_parent, para_id), constraints),
189 SchedulingLookahead(session_index, scheduling_lookahead) => self
190 .requests_cache
191 .cache_scheduling_lookahead(session_index, scheduling_lookahead),
192 ValidationCodeBombLimit(session_index, limit) =>
193 self.requests_cache.cache_validation_code_bomb_limit(session_index, limit),
194 ParaIds(session_index, para_ids) => {
195 self.requests_cache.cache_para_ids(session_index, para_ids);
196 },
197 }
198 }
199
200 fn query_cache(&mut self, relay_parent: Hash, request: Request) -> Option<Request> {
201 macro_rules! query {
202 ($cache_api_name:ident (), $sender:expr) => {{
204 let sender = $sender;
205 if let Some(value) = self.requests_cache.$cache_api_name(&relay_parent) {
206 let _ = sender.send(Ok(value.clone()));
207 self.metrics.on_cached_request();
208 None
209 } else {
210 Some(sender)
211 }
212 }};
213 ($cache_api_name:ident ($($param:expr),+), $sender:expr) => {{
215 let sender = $sender;
216 if let Some(value) = self.requests_cache.$cache_api_name((relay_parent.clone(), $($param.clone()),+)) {
217 self.metrics.on_cached_request();
218 let _ = sender.send(Ok(value.clone()));
219 None
220 } else {
221 Some(sender)
222 }
223 }}
224 }
225
226 match request {
227 Request::Version(sender) =>
228 query!(version(), sender).map(|sender| Request::Version(sender)),
229 Request::Authorities(sender) =>
230 query!(authorities(), sender).map(|sender| Request::Authorities(sender)),
231 Request::Validators(sender) =>
232 query!(validators(), sender).map(|sender| Request::Validators(sender)),
233 Request::ValidatorGroups(sender) =>
234 query!(validator_groups(), sender).map(|sender| Request::ValidatorGroups(sender)),
235 Request::AvailabilityCores(sender) => query!(availability_cores(), sender)
236 .map(|sender| Request::AvailabilityCores(sender)),
237 Request::PersistedValidationData(para, assumption, sender) =>
238 query!(persisted_validation_data(para, assumption), sender)
239 .map(|sender| Request::PersistedValidationData(para, assumption, sender)),
240 Request::AssumedValidationData(
241 para,
242 expected_persisted_validation_data_hash,
243 sender,
244 ) => query!(
245 assumed_validation_data(para, expected_persisted_validation_data_hash),
246 sender
247 )
248 .map(|sender| {
249 Request::AssumedValidationData(
250 para,
251 expected_persisted_validation_data_hash,
252 sender,
253 )
254 }),
255 Request::CheckValidationOutputs(para, commitments, sender) =>
256 query!(check_validation_outputs(para, commitments), sender)
257 .map(|sender| Request::CheckValidationOutputs(para, commitments, sender)),
258 Request::SessionIndexForChild(sender) => query!(session_index_for_child(), sender)
259 .map(|sender| Request::SessionIndexForChild(sender)),
260 Request::ValidationCode(para, assumption, sender) =>
261 query!(validation_code(para, assumption), sender)
262 .map(|sender| Request::ValidationCode(para, assumption, sender)),
263 Request::ValidationCodeByHash(validation_code_hash, sender) =>
264 query!(validation_code_by_hash(validation_code_hash), sender)
265 .map(|sender| Request::ValidationCodeByHash(validation_code_hash, sender)),
266 Request::CandidatePendingAvailability(para, sender) =>
267 query!(candidate_pending_availability(para), sender)
268 .map(|sender| Request::CandidatePendingAvailability(para, sender)),
269 Request::CandidatesPendingAvailability(para, sender) =>
270 query!(candidates_pending_availability(para), sender)
271 .map(|sender| Request::CandidatesPendingAvailability(para, sender)),
272 Request::CandidateEvents(sender) =>
273 query!(candidate_events(), sender).map(|sender| Request::CandidateEvents(sender)),
274 Request::SessionExecutorParams(session_index, sender) => {
275 if let Some(executor_params) =
276 self.requests_cache.session_executor_params(session_index)
277 {
278 self.metrics.on_cached_request();
279 let _ = sender.send(Ok(executor_params.clone()));
280 None
281 } else {
282 Some(Request::SessionExecutorParams(session_index, sender))
283 }
284 },
285 Request::SessionInfo(index, sender) => {
286 if let Some(info) = self.requests_cache.session_info(index) {
287 self.metrics.on_cached_request();
288 let _ = sender.send(Ok(Some(info.clone())));
289 None
290 } else {
291 Some(Request::SessionInfo(index, sender))
292 }
293 },
294 Request::DmqContents(id, sender) =>
295 query!(dmq_contents(id), sender).map(|sender| Request::DmqContents(id, sender)),
296 Request::InboundHrmpChannelsContents(id, sender) =>
297 query!(inbound_hrmp_channels_contents(id), sender)
298 .map(|sender| Request::InboundHrmpChannelsContents(id, sender)),
299 Request::CurrentBabeEpoch(sender) =>
300 query!(current_babe_epoch(), sender).map(|sender| Request::CurrentBabeEpoch(sender)),
301 Request::FetchOnChainVotes(sender) =>
302 query!(on_chain_votes(), sender).map(|sender| Request::FetchOnChainVotes(sender)),
303 Request::PvfsRequirePrecheck(sender) => query!(pvfs_require_precheck(), sender)
304 .map(|sender| Request::PvfsRequirePrecheck(sender)),
305 request @ Request::SubmitPvfCheckStatement(_, _, _) => {
306 Some(request)
308 },
309 Request::ValidationCodeHash(para, assumption, sender) =>
310 query!(validation_code_hash(para, assumption), sender)
311 .map(|sender| Request::ValidationCodeHash(para, assumption, sender)),
312 Request::Disputes(sender) =>
313 query!(disputes(), sender).map(|sender| Request::Disputes(sender)),
314 Request::UnappliedSlashes(sender) =>
315 query!(unapplied_slashes(), sender).map(|sender| Request::UnappliedSlashes(sender)),
316 Request::KeyOwnershipProof(validator_id, sender) =>
317 query!(key_ownership_proof(validator_id), sender)
318 .map(|sender| Request::KeyOwnershipProof(validator_id, sender)),
319 Request::SubmitReportDisputeLost(dispute_proof, key_ownership_proof, sender) =>
320 query!(submit_report_dispute_lost(dispute_proof, key_ownership_proof), sender).map(
321 |sender| {
322 Request::SubmitReportDisputeLost(dispute_proof, key_ownership_proof, sender)
323 },
324 ),
325 Request::ApprovalVotingParams(session_index, sender) =>
326 query!(approval_voting_params(session_index), sender)
327 .map(|sender| Request::ApprovalVotingParams(session_index, sender)),
328 Request::DisabledValidators(sender) => query!(disabled_validators(), sender)
329 .map(|sender| Request::DisabledValidators(sender)),
330 Request::ParaBackingState(para, sender) => query!(para_backing_state(para), sender)
331 .map(|sender| Request::ParaBackingState(para, sender)),
332 Request::AsyncBackingParams(sender) => query!(async_backing_params(), sender)
333 .map(|sender| Request::AsyncBackingParams(sender)),
334 Request::MinimumBackingVotes(index, sender) => {
335 if let Some(value) = self.requests_cache.minimum_backing_votes(index) {
336 self.metrics.on_cached_request();
337 let _ = sender.send(Ok(value));
338 None
339 } else {
340 Some(Request::MinimumBackingVotes(index, sender))
341 }
342 },
343 Request::NodeFeatures(index, sender) => {
344 if let Some(value) = self.requests_cache.node_features(index) {
345 self.metrics.on_cached_request();
346 let _ = sender.send(Ok(value.clone()));
347 None
348 } else {
349 Some(Request::NodeFeatures(index, sender))
350 }
351 },
352 Request::ClaimQueue(sender) =>
353 query!(claim_queue(), sender).map(|sender| Request::ClaimQueue(sender)),
354 Request::BackingConstraints(para, sender) => query!(backing_constraints(para), sender)
355 .map(|sender| Request::BackingConstraints(para, sender)),
356 Request::SchedulingLookahead(index, sender) => {
357 if let Some(value) = self.requests_cache.scheduling_lookahead(index) {
358 self.metrics.on_cached_request();
359 let _ = sender.send(Ok(value));
360 None
361 } else {
362 Some(Request::SchedulingLookahead(index, sender))
363 }
364 },
365 Request::ValidationCodeBombLimit(index, sender) => {
366 if let Some(value) = self.requests_cache.validation_code_bomb_limit(index) {
367 self.metrics.on_cached_request();
368 let _ = sender.send(Ok(value));
369 None
370 } else {
371 Some(Request::ValidationCodeBombLimit(index, sender))
372 }
373 },
374 Request::ParaIds(index, sender) => {
375 if let Some(value) = self.requests_cache.para_ids(index) {
376 self.metrics.on_cached_request();
377 let _ = sender.send(Ok(value.clone()));
378 None
379 } else {
380 Some(Request::ParaIds(index, sender))
381 }
382 },
383 }
384 }
385
386 fn spawn_request(&mut self, relay_parent: Hash, request: Request) {
388 let client = self.client.clone();
389 let metrics = self.metrics.clone();
390 let (sender, receiver) = oneshot::channel();
391
392 let request = match self.query_cache(relay_parent, request) {
394 Some(request) => request,
395 None => return,
396 };
397
398 let request = async move {
399 let result = make_runtime_api_request(client, metrics, relay_parent, request).await;
400 let _ = sender.send(result);
401 }
402 .boxed();
403
404 self.spawn_handle
405 .spawn_blocking(API_REQUEST_TASK_NAME, Some("runtime-api"), request);
406 self.active_requests.push(receiver);
407 }
408
409 async fn poll_requests(&mut self) {
411 if self.active_requests.len() == 0 {
413 return futures::pending!();
414 }
415
416 if let Some(Ok(Some(result))) = self.active_requests.next().await {
419 self.store_cache(result);
420 }
421 }
422
423 fn is_busy(&self) -> bool {
425 self.active_requests.len() >= MAX_PARALLEL_REQUESTS
426 }
427}
428
429#[overseer::contextbounds(RuntimeApi, prefix = self::overseer)]
430async fn run<Client, Context>(
431 mut ctx: Context,
432 mut subsystem: RuntimeApiSubsystem<Client>,
433) -> SubsystemResult<()>
434where
435 Client: RuntimeApiSubsystemClient + Send + Sync + 'static,
436{
437 loop {
438 if subsystem.is_busy() {
444 let _ = subsystem.poll_requests().await;
447 }
448
449 select! {
450 req = ctx.recv().fuse() => match req? {
451 FromOrchestra::Signal(OverseerSignal::Conclude) => return Ok(()),
452 FromOrchestra::Signal(OverseerSignal::ActiveLeaves(_)) => {},
453 FromOrchestra::Signal(OverseerSignal::BlockFinalized(..)) => {},
454 FromOrchestra::Communication { msg } => match msg {
455 RuntimeApiMessage::Request(relay_parent, request) => {
456 subsystem.spawn_request(relay_parent, request);
457 },
458 }
459 },
460 _ = subsystem.poll_requests().fuse() => {},
461 }
462 }
463}
464
465async fn make_runtime_api_request<Client>(
466 client: Arc<Client>,
467 metrics: Metrics,
468 relay_parent: Hash,
469 request: Request,
470) -> Option<RequestResult>
471where
472 Client: RuntimeApiSubsystemClient + 'static,
473{
474 let _timer = metrics.time_make_runtime_api_request();
475
476 macro_rules! query {
477 ($req_variant:ident, $api_name:ident ($($param:expr),*), ver = $version:expr, $sender:expr) => {{
478 query!($req_variant, $api_name($($param),*), ver = $version, $sender, result = ( relay_parent $(, $param )* ) )
479 }};
480 ($req_variant:ident, $api_name:ident ($($param:expr),*), ver = $version:expr, $sender:expr, result = ( $($results:expr),* ) ) => {{
481 let sender = $sender;
482 let version: u32 = $version; let runtime_version = client.api_version_parachain_host(relay_parent).await
484 .unwrap_or_else(|e| {
485 gum::warn!(
486 target: LOG_TARGET,
487 api = ?stringify!($api_name),
488 "cannot query the runtime API version: {}",
489 e,
490 );
491 Some(0)
492 })
493 .unwrap_or_else(|| {
494 gum::warn!(
495 target: LOG_TARGET,
496 "no runtime version is reported"
497 );
498 0
499 });
500
501 let res = if runtime_version >= version {
502 client.$api_name(relay_parent $(, $param.clone() )*).await
503 .map_err(|e| RuntimeApiError::Execution {
504 runtime_api_name: stringify!($api_name),
505 source: std::sync::Arc::new(e),
506 })
507 } else {
508 Err(RuntimeApiError::NotSupported {
509 runtime_api_name: stringify!($api_name),
510 })
511 };
512 metrics.on_request(res.is_ok());
513 let _ = sender.send(res.clone());
514
515 res.ok().map(|res| RequestResult::$req_variant($( $results, )* res))
516 }}
517 }
518
519 match request {
520 Request::Version(sender) => {
521 let runtime_version = match client.api_version_parachain_host(relay_parent).await {
522 Ok(Some(v)) => Ok(v),
523 Ok(None) => Err(RuntimeApiError::NotSupported { runtime_api_name: "api_version" }),
524 Err(e) => Err(RuntimeApiError::Execution {
525 runtime_api_name: "api_version",
526 source: std::sync::Arc::new(e),
527 }),
528 };
529
530 let _ = sender.send(runtime_version.clone());
531 runtime_version.ok().map(|v| RequestResult::Version(relay_parent, v))
532 },
533
534 Request::Authorities(sender) => query!(Authorities, authorities(), ver = 1, sender),
535 Request::Validators(sender) => query!(Validators, validators(), ver = 1, sender),
536 Request::ValidatorGroups(sender) => {
537 query!(ValidatorGroups, validator_groups(), ver = 1, sender)
538 },
539 Request::AvailabilityCores(sender) => {
540 query!(AvailabilityCores, availability_cores(), ver = 1, sender)
541 },
542 Request::PersistedValidationData(para, assumption, sender) => query!(
543 PersistedValidationData,
544 persisted_validation_data(para, assumption),
545 ver = 1,
546 sender
547 ),
548 Request::AssumedValidationData(para, expected_persisted_validation_data_hash, sender) => {
549 query!(
550 AssumedValidationData,
551 assumed_validation_data(para, expected_persisted_validation_data_hash),
552 ver = 1,
553 sender
554 )
555 },
556 Request::CheckValidationOutputs(para, commitments, sender) => query!(
557 CheckValidationOutputs,
558 check_validation_outputs(para, commitments),
559 ver = 1,
560 sender
561 ),
562 Request::SessionIndexForChild(sender) => {
563 query!(SessionIndexForChild, session_index_for_child(), ver = 1, sender)
564 },
565 Request::ValidationCode(para, assumption, sender) => {
566 query!(ValidationCode, validation_code(para, assumption), ver = 1, sender)
567 },
568 Request::ValidationCodeByHash(validation_code_hash, sender) => query!(
569 ValidationCodeByHash,
570 validation_code_by_hash(validation_code_hash),
571 ver = 1,
572 sender
573 ),
574 Request::CandidatePendingAvailability(para, sender) => query!(
575 CandidatePendingAvailability,
576 candidate_pending_availability(para),
577 ver = 1,
578 sender
579 ),
580 Request::CandidatesPendingAvailability(para, sender) => query!(
581 CandidatesPendingAvailability,
582 candidates_pending_availability(para),
583 ver = Request::CANDIDATES_PENDING_AVAILABILITY_RUNTIME_REQUIREMENT,
584 sender
585 ),
586 Request::CandidateEvents(sender) => {
587 query!(CandidateEvents, candidate_events(), ver = 1, sender)
588 },
589 Request::SessionInfo(index, sender) => {
590 query!(SessionInfo, session_info(index), ver = 2, sender)
591 },
592 Request::SessionExecutorParams(session_index, sender) => query!(
593 SessionExecutorParams,
594 session_executor_params(session_index),
595 ver = Request::EXECUTOR_PARAMS_RUNTIME_REQUIREMENT,
596 sender
597 ),
598 Request::DmqContents(id, sender) => query!(DmqContents, dmq_contents(id), ver = 1, sender),
599 Request::InboundHrmpChannelsContents(id, sender) => {
600 query!(InboundHrmpChannelsContents, inbound_hrmp_channels_contents(id), ver = 1, sender)
601 },
602 Request::CurrentBabeEpoch(sender) => {
603 query!(CurrentBabeEpoch, current_epoch(), ver = 1, sender)
604 },
605 Request::FetchOnChainVotes(sender) => {
606 query!(FetchOnChainVotes, on_chain_votes(), ver = 1, sender)
607 },
608 Request::SubmitPvfCheckStatement(stmt, signature, sender) => {
609 query!(
610 SubmitPvfCheckStatement,
611 submit_pvf_check_statement(stmt, signature),
612 ver = 2,
613 sender,
614 result = ()
615 )
616 },
617 Request::PvfsRequirePrecheck(sender) => {
618 query!(PvfsRequirePrecheck, pvfs_require_precheck(), ver = 2, sender)
619 },
620 Request::ValidationCodeHash(para, assumption, sender) => {
621 query!(ValidationCodeHash, validation_code_hash(para, assumption), ver = 2, sender)
622 },
623 Request::Disputes(sender) => {
624 query!(Disputes, disputes(), ver = Request::DISPUTES_RUNTIME_REQUIREMENT, sender)
625 },
626 Request::UnappliedSlashes(sender) => query!(
627 UnappliedSlashes,
628 unapplied_slashes(),
629 ver = Request::UNAPPLIED_SLASHES_RUNTIME_REQUIREMENT,
630 sender
631 ),
632 Request::KeyOwnershipProof(validator_id, sender) => query!(
633 KeyOwnershipProof,
634 key_ownership_proof(validator_id),
635 ver = Request::KEY_OWNERSHIP_PROOF_RUNTIME_REQUIREMENT,
636 sender
637 ),
638 Request::ApprovalVotingParams(session_index, sender) => {
639 query!(
640 ApprovalVotingParams,
641 approval_voting_params(session_index),
642 ver = Request::APPROVAL_VOTING_PARAMS_REQUIREMENT,
643 sender
644 )
645 },
646 Request::SubmitReportDisputeLost(dispute_proof, key_ownership_proof, sender) => query!(
647 SubmitReportDisputeLost,
648 submit_report_dispute_lost(dispute_proof, key_ownership_proof),
649 ver = Request::SUBMIT_REPORT_DISPUTE_LOST_RUNTIME_REQUIREMENT,
650 sender,
651 result = ()
652 ),
653 Request::MinimumBackingVotes(index, sender) => query!(
654 MinimumBackingVotes,
655 minimum_backing_votes(index),
656 ver = Request::MINIMUM_BACKING_VOTES_RUNTIME_REQUIREMENT,
657 sender,
658 result = (index)
659 ),
660 Request::DisabledValidators(sender) => query!(
661 DisabledValidators,
662 disabled_validators(),
663 ver = Request::DISABLED_VALIDATORS_RUNTIME_REQUIREMENT,
664 sender
665 ),
666 Request::ParaBackingState(para, sender) => {
667 query!(
668 ParaBackingState,
669 para_backing_state(para),
670 ver = Request::ASYNC_BACKING_STATE_RUNTIME_REQUIREMENT,
671 sender
672 )
673 },
674 Request::AsyncBackingParams(sender) => {
675 query!(
676 AsyncBackingParams,
677 async_backing_params(),
678 ver = Request::ASYNC_BACKING_STATE_RUNTIME_REQUIREMENT,
679 sender
680 )
681 },
682 Request::NodeFeatures(index, sender) => query!(
683 NodeFeatures,
684 node_features(),
685 ver = Request::NODE_FEATURES_RUNTIME_REQUIREMENT,
686 sender,
687 result = (index)
688 ),
689 Request::ClaimQueue(sender) => query!(
690 ClaimQueue,
691 claim_queue(),
692 ver = Request::CLAIM_QUEUE_RUNTIME_REQUIREMENT,
693 sender
694 ),
695 Request::BackingConstraints(para, sender) => {
696 query!(
697 BackingConstraints,
698 backing_constraints(para),
699 ver = Request::CONSTRAINTS_RUNTIME_REQUIREMENT,
700 sender
701 )
702 },
703 Request::SchedulingLookahead(index, sender) => query!(
704 SchedulingLookahead,
705 scheduling_lookahead(),
706 ver = Request::SCHEDULING_LOOKAHEAD_RUNTIME_REQUIREMENT,
707 sender,
708 result = (index)
709 ),
710 Request::ValidationCodeBombLimit(index, sender) => query!(
711 ValidationCodeBombLimit,
712 validation_code_bomb_limit(),
713 ver = Request::VALIDATION_CODE_BOMB_LIMIT_RUNTIME_REQUIREMENT,
714 sender,
715 result = (index)
716 ),
717 Request::ParaIds(index, sender) => query!(
718 ParaIds,
719 para_ids(),
720 ver = Request::PARAIDS_RUNTIME_REQUIREMENT,
721 sender,
722 result = (index)
723 ),
724 }
725}