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
//! ```rust(ignore)
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

            
116
use crate::{
117
	async_backing, slashing, ApprovalVotingParams, AsyncBackingParams, BlockNumber,
118
	CandidateCommitments, CandidateEvent, CandidateHash, CommittedCandidateReceipt, CoreIndex,
119
	CoreState, DisputeState, ExecutorParams, GroupRotationInfo, Hash, NodeFeatures,
120
	OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes,
121
	SessionIndex, SessionInfo, ValidatorId, ValidatorIndex, ValidatorSignature,
122
};
123

            
124
use alloc::{
125
	collections::{btree_map::BTreeMap, vec_deque::VecDeque},
126
	vec::Vec,
127
};
128
use polkadot_core_primitives as pcp;
129
use polkadot_parachain_primitives::primitives as ppp;
130

            
131
sp_api::decl_runtime_apis! {
132
	/// The API for querying the state of parachains on-chain.
133
	#[api_version(5)]
134
	pub trait ParachainHost {
135
		/// Get the current validators.
136
		fn validators() -> Vec<ValidatorId>;
137

            
138
		/// Returns the validator groups and rotation info localized based on the hypothetical child
139
		///  of a block whose state  this is invoked on. Note that `now` in the `GroupRotationInfo`
140
		/// should be the successor of the number of the block.
141
		fn validator_groups() -> (Vec<Vec<ValidatorIndex>>, GroupRotationInfo<BlockNumber>);
142

            
143
		/// Yields information on all availability cores as relevant to the child block.
144
		/// Cores are either free or occupied. Free cores can have paras assigned to them.
145
		fn availability_cores() -> Vec<CoreState<Hash, BlockNumber>>;
146

            
147
		/// Yields the persisted validation data for the given `ParaId` along with an assumption that
148
		/// should be used if the para currently occupies a core.
149
		///
150
		/// Returns `None` if either the para is not registered or the assumption is `Freed`
151
		/// and the para already occupies a core.
152
		fn persisted_validation_data(para_id: ppp::Id, assumption: OccupiedCoreAssumption)
153
			-> Option<PersistedValidationData<Hash, BlockNumber>>;
154

            
155
		/// Returns the persisted validation data for the given `ParaId` along with the corresponding
156
		/// validation code hash. Instead of accepting assumption about the para, matches the validation
157
		/// data hash against an expected one and yields `None` if they're not equal.
158
		fn assumed_validation_data(
159
			para_id: ppp::Id,
160
			expected_persisted_validation_data_hash: Hash,
161
		) -> Option<(PersistedValidationData<Hash, BlockNumber>, ppp::ValidationCodeHash)>;
162

            
163
		/// Checks if the given validation outputs pass the acceptance criteria.
164
		fn check_validation_outputs(para_id: ppp::Id, outputs: CandidateCommitments) -> bool;
165

            
166
		/// Returns the session index expected at a child of the block.
167
		///
168
		/// This can be used to instantiate a `SigningContext`.
169
		fn session_index_for_child() -> SessionIndex;
170

            
171
		/// Fetch the validation code used by a para, making the given `OccupiedCoreAssumption`.
172
		///
173
		/// Returns `None` if either the para is not registered or the assumption is `Freed`
174
		/// and the para already occupies a core.
175
		fn validation_code(
176
			para_id: ppp::Id,
177
			assumption: OccupiedCoreAssumption,
178
		) -> Option<ppp::ValidationCode>;
179

            
180
		/// Get the receipt of a candidate pending availability. This returns `Some` for any paras
181
		/// assigned to occupied cores in `availability_cores` and `None` otherwise.
182
		fn candidate_pending_availability(para_id: ppp::Id) -> Option<CommittedCandidateReceipt<Hash>>;
183

            
184
		/// Get a vector of events concerning candidates that occurred within a block.
185
		fn candidate_events() -> Vec<CandidateEvent<Hash>>;
186

            
187
		/// Get all the pending inbound messages in the downward message queue for a para.
188
		fn dmq_contents(
189
			recipient: ppp::Id,
190
		) -> Vec<pcp::v2::InboundDownwardMessage<BlockNumber>>;
191

            
192
		/// Get the contents of all channels addressed to the given recipient. Channels that have no
193
		/// messages in them are also included.
194
		fn inbound_hrmp_channels_contents(
195
			recipient: ppp::Id,
196
		) -> BTreeMap<ppp::Id, Vec<pcp::v2::InboundHrmpMessage<BlockNumber>>>;
197

            
198
		/// Get the validation code from its hash.
199
		fn validation_code_by_hash(hash: ppp::ValidationCodeHash) -> Option<ppp::ValidationCode>;
200

            
201
		/// Scrape dispute relevant from on-chain, backing votes and resolved disputes.
202
		fn on_chain_votes() -> Option<ScrapedOnChainVotes<Hash>>;
203

            
204
		/***** Added in v2 *****/
205

            
206
		/// Get the session info for the given session, if stored.
207
		///
208
		/// NOTE: This function is only available since parachain host version 2.
209
		fn session_info(index: SessionIndex) -> Option<SessionInfo>;
210

            
211
		/// Submits a PVF pre-checking statement into the transaction pool.
212
		///
213
		/// NOTE: This function is only available since parachain host version 2.
214
		fn submit_pvf_check_statement(stmt: PvfCheckStatement, signature: ValidatorSignature);
215

            
216
		/// Returns code hashes of PVFs that require pre-checking by validators in the active set.
217
		///
218
		/// NOTE: This function is only available since parachain host version 2.
219
		fn pvfs_require_precheck() -> Vec<ppp::ValidationCodeHash>;
220

            
221
		/// Fetch the hash of the validation code used by a para, making the given `OccupiedCoreAssumption`.
222
		///
223
		/// NOTE: This function is only available since parachain host version 2.
224
		fn validation_code_hash(para_id: ppp::Id, assumption: OccupiedCoreAssumption)
225
			-> Option<ppp::ValidationCodeHash>;
226

            
227
		/// Returns all onchain disputes.
228
		fn disputes() -> Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)>;
229

            
230
		/// Returns execution parameters for the session.
231
		fn session_executor_params(session_index: SessionIndex) -> Option<ExecutorParams>;
232

            
233
		/// Returns a list of validators that lost a past session dispute and need to be slashed.
234
		/// NOTE: This function is only available since parachain host version 5.
235
		fn unapplied_slashes() -> Vec<(SessionIndex, CandidateHash, slashing::PendingSlashes)>;
236

            
237
		/// Returns a merkle proof of a validator session key.
238
		/// NOTE: This function is only available since parachain host version 5.
239
		fn key_ownership_proof(
240
			validator_id: ValidatorId,
241
		) -> Option<slashing::OpaqueKeyOwnershipProof>;
242

            
243
		/// Submit an unsigned extrinsic to slash validators who lost a dispute about
244
		/// a candidate of a past session.
245
		/// NOTE: This function is only available since parachain host version 5.
246
		fn submit_report_dispute_lost(
247
			dispute_proof: slashing::DisputeProof,
248
			key_ownership_proof: slashing::OpaqueKeyOwnershipProof,
249
		) -> Option<()>;
250

            
251
		/***** Added in v6 *****/
252

            
253
		/// Get the minimum number of backing votes for a parachain candidate.
254
		/// This is a staging method! Do not use on production runtimes!
255
		#[api_version(6)]
256
		fn minimum_backing_votes() -> u32;
257

            
258

            
259
		/***** Added in v7: Asynchronous backing *****/
260

            
261
		/// Returns the state of parachain backing for a given para.
262
		#[api_version(7)]
263
		fn para_backing_state(_: ppp::Id) -> Option<async_backing::BackingState<Hash, BlockNumber>>;
264

            
265
		/// Returns candidate's acceptance limitations for asynchronous backing for a relay parent.
266
		#[api_version(7)]
267
		fn async_backing_params() -> AsyncBackingParams;
268

            
269
		/***** Added in v8 *****/
270

            
271
		/// Returns a list of all disabled validators at the given block.
272
		#[api_version(8)]
273
		fn disabled_validators() -> Vec<ValidatorIndex>;
274

            
275
		/***** Added in v9 *****/
276

            
277
		/// Get node features.
278
		/// This is a staging method! Do not use on production runtimes!
279
		#[api_version(9)]
280
		fn node_features() -> NodeFeatures;
281

            
282
		/***** Added in v10 *****/
283
		/// Approval voting configuration parameters
284
		#[api_version(10)]
285
		fn approval_voting_params() -> ApprovalVotingParams;
286

            
287
		/***** Added in v11 *****/
288
		/// Claim queue
289
		#[api_version(11)]
290
		fn claim_queue() -> BTreeMap<CoreIndex, VecDeque<ppp::Id>>;
291

            
292
		/***** Added in v11 *****/
293
		/// Elastic scaling support
294
		#[api_version(11)]
295
		fn candidates_pending_availability(para_id: ppp::Id) -> Vec<CommittedCandidateReceipt<Hash>>;
296
	}
297
}