polkadot_primitives/runtime_api.rs
1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Polkadot.
3
4// Polkadot is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Polkadot is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
16
17//! Runtime API module declares the `trait ParachainHost` which is part
18//! of the Runtime API exposed from the Runtime to the Host.
19//!
20//! The functions in trait ParachainHost` can be part of the stable API
21//! (which is versioned) or they can be staging (aka unstable/testing
22//! functions).
23//!
24//! The separation outlined above is achieved with the versioned API feature
25//! of `decl_runtime_apis!` and `impl_runtime_apis!`. Before moving on let's
26//! see a quick example about how API versioning works.
27//!
28//! # Runtime API versioning crash course
29//!
30//! The versioning is achieved with the `api_version` attribute. It can be
31//! placed on:
32//! * trait declaration - represents the base version of the API.
33//! * method declaration (inside a trait declaration) - represents a versioned method, which is not
34//! available in the base version.
35//! * trait implementation - represents which version of the API is being implemented.
36//!
37//! Let's see a quick example:
38//!
39//! ```nocompile
40//! sp_api::decl_runtime_apis! {
41//! #[api_version(2)]
42//! pub trait MyApi {
43//! fn fn1();
44//! fn fn2();
45//! #[api_version(3)]
46//! fn fn3();
47//! #[api_version(4)]
48//! fn fn4();
49//! }
50//! }
51//!
52//! struct Runtime {}
53//!
54//! sp_api::impl_runtime_apis! {
55//! #[api_version(3)]
56//! impl self::MyApi<Block> for Runtime {
57//! fn fn1() {}
58//! fn fn2() {}
59//! fn fn3() {}
60//! }
61//! }
62//! ```
63//! A new API named `MyApi` is declared with `decl_runtime_apis!`. The trait declaration
64//! has got an `api_version` attribute which represents its base version - 2 in this case.
65//!
66//! The API has got three methods - `fn1`, `fn2`, `fn3` and `fn4`. `fn3` and `fn4` has got
67//! an `api_version` attribute which makes them versioned methods. These methods do not exist
68//! in the base version of the API. Behind the scenes the declaration above creates three
69//! runtime APIs:
70//! * `MyApiV2` with `fn1` and `fn2`
71//! * `MyApiV3` with `fn1`, `fn2` and `fn3`.
72//! * `MyApiV4` with `fn1`, `fn2`, `fn3` and `fn4`.
73//!
74//! Please note that `v4` contains all methods from `v3`, `v3` all methods from `v2` and so on.
75//!
76//! Back to our example. At the end runtime API is implemented for `struct Runtime` with
77//! `impl_runtime_apis` macro. `api_version` attribute is attached to the `impl` block which
78//! means that a version different from the base one is being implemented - in our case this
79//! is `v3`.
80//!
81//! This version of the API contains three methods so the `impl` block has got definitions
82//! for them. Note that `fn4` is not implemented as it is not part of this version of the API.
83//! `impl_runtime_apis` generates a default implementation for it calling `unimplemented!()`.
84//!
85//! Hopefully this should be all you need to know in order to use versioned methods in the node.
86//! For more details about how the API versioning works refer to `spi_api`
87//! documentation [here](https://docs.substrate.io/rustdocs/latest/sp_api/macro.decl_runtime_apis.html).
88//!
89//! # How versioned methods are used for `ParachainHost`
90//!
91//! Let's introduce two types of `ParachainHost` API implementation:
92//! * stable - used on stable production networks like Polkadot and Kusama. There is only one stable
93//! API at a single point in time.
94//! * staging - methods that are ready for production, but will be released on Rococo first. We can
95//! batch together multiple changes and then release all of them to production, by making staging
96//! production (bump base version). We can not change or remove any method in staging after a
97//! release, as this would break Rococo. It should be ok to keep adding methods to staging across
98//! several releases. For experimental methods, you have to keep them on a separate branch until
99//! ready.
100//!
101//! The stable version of `ParachainHost` is indicated by the base version of the API. Any staging
102//! method must use `api_version` attribute so that it is assigned to a specific version of a
103//! staging API. This way in a single declaration one can see what's the stable version of
104//! `ParachainHost` and what staging versions/functions are available.
105//!
106//! All stable API functions should use primitives from the latest version.
107//! In the time of writing of this document - this is `v2`. So for example:
108//! ```ignore
109//! fn validators() -> Vec<v2::ValidatorId>;
110//! ```
111//! indicates a function from the stable `v2` API.
112//!
113//! All staging API functions should use primitives from `vstaging`. They should be clearly
114//! separated from the stable primitives.
115
116use crate::{
117 async_backing::{BackingState, Constraints},
118 slashing,
119 vstaging::RelayParentInfo,
120 ApprovalVotingParams, AsyncBackingParams, BlockNumber, CandidateCommitments, CandidateEvent,
121 CandidateHash, CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreIndex, CoreState,
122 DisputeState, ExecutorParams, GroupRotationInfo, Hash, NodeFeatures, OccupiedCoreAssumption,
123 PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes, SessionIndex, SessionInfo,
124 ValidatorId, ValidatorIndex, ValidatorSignature,
125};
126
127use alloc::{
128 collections::{btree_map::BTreeMap, vec_deque::VecDeque},
129 vec::Vec,
130};
131use polkadot_core_primitives as pcp;
132use polkadot_parachain_primitives::primitives as ppp;
133
134sp_api::decl_runtime_apis! {
135 /// The API for querying the state of parachains on-chain.
136 #[api_version(5)]
137 pub trait ParachainHost {
138 /// Get the current validators.
139 fn validators() -> Vec<ValidatorId>;
140
141 /// Returns the validator groups and rotation info localized based on the hypothetical child
142 /// of a block whose state this is invoked on. Note that `now` in the `GroupRotationInfo`
143 /// should be the successor of the number of the block.
144 fn validator_groups() -> (Vec<Vec<ValidatorIndex>>, GroupRotationInfo<BlockNumber>);
145
146 /// Yields information on all availability cores as relevant to the child block.
147 /// Cores are either free or occupied. Free cores can have paras assigned to them.
148 fn availability_cores() -> Vec<CoreState<Hash, BlockNumber>>;
149
150 /// Yields the persisted validation data for the given `ParaId` along with an assumption that
151 /// should be used if the para currently occupies a core.
152 ///
153 /// Returns `None` if either the para is not registered or the assumption is `Freed`
154 /// and the para already occupies a core.
155 fn persisted_validation_data(para_id: ppp::Id, assumption: OccupiedCoreAssumption)
156 -> Option<PersistedValidationData<Hash, BlockNumber>>;
157
158 /// Returns the persisted validation data for the given `ParaId` along with the corresponding
159 /// validation code hash. Instead of accepting assumption about the para, matches the validation
160 /// data hash against an expected one and yields `None` if they're not equal.
161 fn assumed_validation_data(
162 para_id: ppp::Id,
163 expected_persisted_validation_data_hash: Hash,
164 ) -> Option<(PersistedValidationData<Hash, BlockNumber>, ppp::ValidationCodeHash)>;
165
166 /// Checks if the given validation outputs pass the acceptance criteria.
167 fn check_validation_outputs(para_id: ppp::Id, outputs: CandidateCommitments) -> bool;
168
169 /// Returns the session index expected at a child of the block.
170 ///
171 /// This can be used to instantiate a `SigningContext`.
172 fn session_index_for_child() -> SessionIndex;
173
174 /// Fetch the validation code used by a para, making the given `OccupiedCoreAssumption`.
175 ///
176 /// Returns `None` if either the para is not registered or the assumption is `Freed`
177 /// and the para already occupies a core.
178 fn validation_code(
179 para_id: ppp::Id,
180 assumption: OccupiedCoreAssumption,
181 ) -> Option<ppp::ValidationCode>;
182
183 /// Get the receipt of a candidate pending availability. This returns `Some` for any paras
184 /// assigned to occupied cores in `availability_cores` and `None` otherwise.
185 fn candidate_pending_availability(para_id: ppp::Id) -> Option<CommittedCandidateReceipt<Hash>>;
186
187 /// Get a vector of events concerning candidates that occurred within a block.
188 fn candidate_events() -> Vec<CandidateEvent<Hash>>;
189
190 /// Get all the pending inbound messages in the downward message queue for a para.
191 fn dmq_contents(
192 recipient: ppp::Id,
193 ) -> Vec<pcp::v2::InboundDownwardMessage<BlockNumber>>;
194
195 /// Get the contents of all channels addressed to the given recipient. Channels that have no
196 /// messages in them are also included.
197 fn inbound_hrmp_channels_contents(
198 recipient: ppp::Id,
199 ) -> BTreeMap<ppp::Id, Vec<pcp::v2::InboundHrmpMessage<BlockNumber>>>;
200
201 /// Get the validation code from its hash.
202 fn validation_code_by_hash(hash: ppp::ValidationCodeHash) -> Option<ppp::ValidationCode>;
203
204 /// Scrape dispute relevant from on-chain, backing votes and resolved disputes.
205 fn on_chain_votes() -> Option<ScrapedOnChainVotes<Hash>>;
206
207 /***** Added in v2 *****/
208
209 /// Get the session info for the given session, if stored.
210 ///
211 /// NOTE: This function is only available since parachain host version 2.
212 fn session_info(index: SessionIndex) -> Option<SessionInfo>;
213
214 /// Submits a PVF pre-checking statement into the transaction pool.
215 ///
216 /// NOTE: This function is only available since parachain host version 2.
217 fn submit_pvf_check_statement(stmt: PvfCheckStatement, signature: ValidatorSignature);
218
219 /// Returns code hashes of PVFs that require pre-checking by validators in the active set.
220 ///
221 /// NOTE: This function is only available since parachain host version 2.
222 fn pvfs_require_precheck() -> Vec<ppp::ValidationCodeHash>;
223
224 /// Fetch the hash of the validation code used by a para, making the given `OccupiedCoreAssumption`.
225 ///
226 /// NOTE: This function is only available since parachain host version 2.
227 fn validation_code_hash(para_id: ppp::Id, assumption: OccupiedCoreAssumption)
228 -> Option<ppp::ValidationCodeHash>;
229
230 /// Returns all onchain disputes.
231 fn disputes() -> Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)>;
232
233 /// Returns execution parameters for the session.
234 fn session_executor_params(session_index: SessionIndex) -> Option<ExecutorParams>;
235
236 /// Returns a list of validators that lost a past session dispute and need to be slashed.
237 ///
238 /// Deprecated. Use `unapplied_slashes_v2` instead.
239 fn unapplied_slashes() -> Vec<(SessionIndex, CandidateHash, slashing::LegacyPendingSlashes)>;
240
241 /// Returns a merkle proof of a validator session key.
242 /// NOTE: This function is only available since parachain host version 5.
243 fn key_ownership_proof(
244 validator_id: ValidatorId,
245 ) -> Option<slashing::OpaqueKeyOwnershipProof>;
246
247 /// Submit an unsigned extrinsic to slash validators who lost a dispute about
248 /// a candidate of a past session.
249 /// NOTE: This function is only available since parachain host version 5.
250 fn submit_report_dispute_lost(
251 dispute_proof: slashing::DisputeProof,
252 key_ownership_proof: slashing::OpaqueKeyOwnershipProof,
253 ) -> Option<()>;
254
255 /***** Added in v6 *****/
256
257 /// Get the minimum number of backing votes for a parachain candidate.
258 /// This is a staging method! Do not use on production runtimes!
259 #[api_version(6)]
260 fn minimum_backing_votes() -> u32;
261
262
263 /***** Added in v7: Asynchronous backing *****/
264
265 /// Returns the state of parachain backing for a given para.
266 #[api_version(7)]
267 fn para_backing_state(_: ppp::Id) -> Option<BackingState<Hash, BlockNumber>>;
268
269 /// Returns candidate's acceptance limitations for asynchronous backing for a relay parent.
270 #[api_version(7)]
271 fn async_backing_params() -> AsyncBackingParams;
272
273 /***** Added in v8 *****/
274
275 /// Returns a list of all disabled validators at the given block.
276 #[api_version(8)]
277 fn disabled_validators() -> Vec<ValidatorIndex>;
278
279 /***** Added in v9 *****/
280
281 /// Get node features.
282 /// This is a staging method! Do not use on production runtimes!
283 #[api_version(9)]
284 fn node_features() -> NodeFeatures;
285
286 /***** Added in v10 *****/
287 /// Approval voting configuration parameters
288 #[api_version(10)]
289 fn approval_voting_params() -> ApprovalVotingParams;
290
291 /***** Added in v11 *****/
292 /// Claim queue
293 #[api_version(11)]
294 fn claim_queue() -> BTreeMap<CoreIndex, VecDeque<ppp::Id>>;
295
296 /***** Added in v11 *****/
297 /// Elastic scaling support
298 #[api_version(11)]
299 fn candidates_pending_availability(para_id: ppp::Id) -> Vec<CommittedCandidateReceipt<Hash>>;
300
301 /***** Added in v12 *****/
302 /// Retrieve the maximum uncompressed code size.
303 #[api_version(12)]
304 fn validation_code_bomb_limit() -> u32;
305
306 /***** Added in v13 *****/
307 /// Returns the constraints on the actions that can be taken by a new parachain
308 /// block.
309 #[api_version(13)]
310 fn backing_constraints(para_id: ppp::Id) -> Option<Constraints>;
311
312 /***** Added in v13 *****/
313 /// Retrieve the scheduling lookahead
314 #[api_version(13)]
315 fn scheduling_lookahead() -> u32;
316
317 /***** Added in v14 *****/
318 /// Retrieve paraids at relay parent
319 #[api_version(14)]
320 fn para_ids() -> Vec<ppp::Id>;
321
322 /***** Added in v15 *****/
323 /// Returns a list of validators that lost a past session dispute and need to be slashed.
324 #[api_version(15)]
325 fn unapplied_slashes_v2() -> Vec<(SessionIndex, CandidateHash, slashing::PendingSlashes)>;
326
327 /***** Added in v16 *****/
328 /// Retrieve the maximum relay parent session age allowed for parachain blocks.
329 #[api_version(16)]
330 fn max_relay_parent_session_age() -> u32;
331
332 /// Look up relay parent info for a block that is an **ancestor** of the block
333 /// this API is called at. Returns `None` if the relay parent is not found
334 /// in the allowed relay parents for the given session.
335 ///
336 /// NOTE: A block is not in its own `AllowedRelayParents` storage (it gets
337 /// added during the next block's inherent). Querying a block about itself
338 /// will always return `None`. Use the node-side `check_relay_parent_session`
339 /// utility for a general-purpose check that handles both the self and
340 /// ancestor cases.
341 #[api_version(16)]
342 fn ancestor_relay_parent_info(
343 session_index: SessionIndex,
344 relay_parent: Hash,
345 ) -> Option<RelayParentInfo<Hash, BlockNumber>>;
346 }
347}