polkadot_node_core_pvf_checker/
runtime_api.rs1use crate::LOG_TARGET;
18use futures::channel::oneshot;
19use polkadot_node_subsystem::{
20 errors::RuntimeApiError as RuntimeApiSubsystemError,
21 messages::{RuntimeApiMessage, RuntimeApiRequest},
22 SubsystemSender,
23};
24use polkadot_primitives::{
25 Hash, PvfCheckStatement, SessionIndex, ValidationCodeHash, ValidatorId, ValidatorSignature,
26};
27
28pub(crate) async fn session_index_for_child(
29 sender: &mut impl SubsystemSender<RuntimeApiMessage>,
30 relay_parent: Hash,
31) -> Result<SessionIndex, RuntimeRequestError> {
32 let (tx, rx) = oneshot::channel();
33 runtime_api_request(sender, relay_parent, RuntimeApiRequest::SessionIndexForChild(tx), rx).await
34}
35
36pub(crate) async fn validators(
37 sender: &mut impl SubsystemSender<RuntimeApiMessage>,
38 relay_parent: Hash,
39) -> Result<Vec<ValidatorId>, RuntimeRequestError> {
40 let (tx, rx) = oneshot::channel();
41 runtime_api_request(sender, relay_parent, RuntimeApiRequest::Validators(tx), rx).await
42}
43
44pub(crate) async fn submit_pvf_check_statement(
45 sender: &mut impl SubsystemSender<RuntimeApiMessage>,
46 relay_parent: Hash,
47 stmt: PvfCheckStatement,
48 signature: ValidatorSignature,
49) -> Result<(), RuntimeRequestError> {
50 let (tx, rx) = oneshot::channel();
51 runtime_api_request(
52 sender,
53 relay_parent,
54 RuntimeApiRequest::SubmitPvfCheckStatement(stmt, signature, tx),
55 rx,
56 )
57 .await
58}
59
60pub(crate) async fn pvfs_require_precheck(
61 sender: &mut impl SubsystemSender<RuntimeApiMessage>,
62 relay_parent: Hash,
63) -> Result<Vec<ValidationCodeHash>, RuntimeRequestError> {
64 let (tx, rx) = oneshot::channel();
65 runtime_api_request(sender, relay_parent, RuntimeApiRequest::PvfsRequirePrecheck(tx), rx).await
66}
67
68#[derive(Debug)]
69pub(crate) enum RuntimeRequestError {
70 NotSupported,
71 ApiError,
72 CommunicationError,
73}
74
75pub(crate) async fn runtime_api_request<T>(
76 sender: &mut impl SubsystemSender<RuntimeApiMessage>,
77 relay_parent: Hash,
78 request: RuntimeApiRequest,
79 receiver: oneshot::Receiver<Result<T, RuntimeApiSubsystemError>>,
80) -> Result<T, RuntimeRequestError> {
81 sender
82 .send_message(RuntimeApiMessage::Request(relay_parent, request).into())
83 .await;
84
85 receiver
86 .await
87 .map_err(|_| {
88 gum::debug!(target: LOG_TARGET, ?relay_parent, "Runtime API request dropped");
89 RuntimeRequestError::CommunicationError
90 })
91 .and_then(|res| {
92 res.map_err(|e| {
93 use RuntimeApiSubsystemError::*;
94 match e {
95 Execution { .. } => {
96 gum::debug!(
97 target: LOG_TARGET,
98 ?relay_parent,
99 err = ?e,
100 "Runtime API request internal error"
101 );
102 RuntimeRequestError::ApiError
103 },
104 NotSupported { .. } => RuntimeRequestError::NotSupported,
105 }
106 })
107 })
108}