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 slashing,
118 vstaging::{
119 self, async_backing::Constraints, CandidateEvent,
120 CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreState, ScrapedOnChainVotes,
121 },
122 ApprovalVotingParams, AsyncBackingParams, BlockNumber, CandidateCommitments, CandidateHash,
123 CoreIndex, DisputeState, ExecutorParams, GroupRotationInfo, Hash, NodeFeatures,
124 OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, SessionIndex, SessionInfo,
125 ValidatorId, ValidatorIndex, ValidatorSignature,
126};
127
128use alloc::{
129 collections::{btree_map::BTreeMap, vec_deque::VecDeque},
130 vec::Vec,
131};
132use polkadot_core_primitives as pcp;
133use polkadot_parachain_primitives::primitives as ppp;
134
135sp_api::decl_runtime_apis! {
136 /// The API for querying the state of parachains on-chain.
137 #[api_version(5)]
138 pub trait ParachainHost {
139 /// Get the current validators.
140 fn validators() -> Vec<ValidatorId>;
141
142 /// Returns the validator groups and rotation info localized based on the hypothetical child
143 /// of a block whose state this is invoked on. Note that `now` in the `GroupRotationInfo`
144 /// should be the successor of the number of the block.
145 fn validator_groups() -> (Vec<Vec<ValidatorIndex>>, GroupRotationInfo<BlockNumber>);
146
147 /// Yields information on all availability cores as relevant to the child block.
148 /// Cores are either free or occupied. Free cores can have paras assigned to them.
149 fn availability_cores() -> Vec<CoreState<Hash, BlockNumber>>;
150
151 /// Yields the persisted validation data for the given `ParaId` along with an assumption that
152 /// should be used if the para currently occupies a core.
153 ///
154 /// Returns `None` if either the para is not registered or the assumption is `Freed`
155 /// and the para already occupies a core.
156 fn persisted_validation_data(para_id: ppp::Id, assumption: OccupiedCoreAssumption)
157 -> Option<PersistedValidationData<Hash, BlockNumber>>;
158
159 /// Returns the persisted validation data for the given `ParaId` along with the corresponding
160 /// validation code hash. Instead of accepting assumption about the para, matches the validation
161 /// data hash against an expected one and yields `None` if they're not equal.
162 fn assumed_validation_data(
163 para_id: ppp::Id,
164 expected_persisted_validation_data_hash: Hash,
165 ) -> Option<(PersistedValidationData<Hash, BlockNumber>, ppp::ValidationCodeHash)>;
166
167 /// Checks if the given validation outputs pass the acceptance criteria.
168 fn check_validation_outputs(para_id: ppp::Id, outputs: CandidateCommitments) -> bool;
169
170 /// Returns the session index expected at a child of the block.
171 ///
172 /// This can be used to instantiate a `SigningContext`.
173 fn session_index_for_child() -> SessionIndex;
174
175 /// Fetch the validation code used by a para, making the given `OccupiedCoreAssumption`.
176 ///
177 /// Returns `None` if either the para is not registered or the assumption is `Freed`
178 /// and the para already occupies a core.
179 fn validation_code(
180 para_id: ppp::Id,
181 assumption: OccupiedCoreAssumption,
182 ) -> Option<ppp::ValidationCode>;
183
184 /// Get the receipt of a candidate pending availability. This returns `Some` for any paras
185 /// assigned to occupied cores in `availability_cores` and `None` otherwise.
186 fn candidate_pending_availability(para_id: ppp::Id) -> Option<CommittedCandidateReceipt<Hash>>;
187
188 /// Get a vector of events concerning candidates that occurred within a block.
189 fn candidate_events() -> Vec<CandidateEvent<Hash>>;
190
191 /// Get all the pending inbound messages in the downward message queue for a para.
192 fn dmq_contents(
193 recipient: ppp::Id,
194 ) -> Vec<pcp::v2::InboundDownwardMessage<BlockNumber>>;
195
196 /// Get the contents of all channels addressed to the given recipient. Channels that have no
197 /// messages in them are also included.
198 fn inbound_hrmp_channels_contents(
199 recipient: ppp::Id,
200 ) -> BTreeMap<ppp::Id, Vec<pcp::v2::InboundHrmpMessage<BlockNumber>>>;
201
202 /// Get the validation code from its hash.
203 fn validation_code_by_hash(hash: ppp::ValidationCodeHash) -> Option<ppp::ValidationCode>;
204
205 /// Scrape dispute relevant from on-chain, backing votes and resolved disputes.
206 fn on_chain_votes() -> Option<ScrapedOnChainVotes<Hash>>;
207
208 /***** Added in v2 *****/
209
210 /// Get the session info for the given session, if stored.
211 ///
212 /// NOTE: This function is only available since parachain host version 2.
213 fn session_info(index: SessionIndex) -> Option<SessionInfo>;
214
215 /// Submits a PVF pre-checking statement into the transaction pool.
216 ///
217 /// NOTE: This function is only available since parachain host version 2.
218 fn submit_pvf_check_statement(stmt: PvfCheckStatement, signature: ValidatorSignature);
219
220 /// Returns code hashes of PVFs that require pre-checking by validators in the active set.
221 ///
222 /// NOTE: This function is only available since parachain host version 2.
223 fn pvfs_require_precheck() -> Vec<ppp::ValidationCodeHash>;
224
225 /// Fetch the hash of the validation code used by a para, making the given `OccupiedCoreAssumption`.
226 ///
227 /// NOTE: This function is only available since parachain host version 2.
228 fn validation_code_hash(para_id: ppp::Id, assumption: OccupiedCoreAssumption)
229 -> Option<ppp::ValidationCodeHash>;
230
231 /// Returns all onchain disputes.
232 fn disputes() -> Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)>;
233
234 /// Returns execution parameters for the session.
235 fn session_executor_params(session_index: SessionIndex) -> Option<ExecutorParams>;
236
237 /// Returns a list of validators that lost a past session dispute and need to be slashed.
238 /// NOTE: This function is only available since parachain host version 5.
239 fn unapplied_slashes() -> Vec<(SessionIndex, CandidateHash, slashing::PendingSlashes)>;
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<vstaging::async_backing::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 }
323}