Skip to main content

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}