parachain.rs 13 KB
Newer Older
Gav's avatar
Gav committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.

// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.

Gav Wood's avatar
Gav Wood committed
17
18
19
20
//! Polkadot parachain types.

use rstd::prelude::*;
use rstd::cmp::Ordering;
21
use parity_codec::{Encode, Decode};
22
use bitvec::vec::BitVec;
23
use super::{Hash, Balance, BlockNumber};
24

25
26
27
#[cfg(feature = "std")]
use serde::{Serialize, Deserialize};

Gav's avatar
Gav committed
28
29
#[cfg(feature = "std")]
use primitives::bytes;
Gav Wood's avatar
Gav Wood committed
30
use primitives::ed25519;
Gav Wood's avatar
Gav Wood committed
31

32
pub use polkadot_parachain::{
33
	Id, AccountIdConversion, ParachainDispatchOrigin, UpwardMessage,
34
};
35

Gav Wood's avatar
Gav Wood committed
36
37
38
/// Identity that collators use.
pub type CollatorId = ed25519::Public;

39
/// Signature on candidate's block data by a collator.
Gav Wood's avatar
Gav Wood committed
40
41
42
43
44
45
46
47
pub type CollatorSignature = ed25519::Signature;

/// Identity that parachain validators use when signing validation messages.
///
/// For now we assert that parachain validator set is exactly equivalent to the (Aura) authority set, and
/// so we define it to be the same type as `SessionKey`. In the future it may have different crypto.
pub type ValidatorId = super::SessionKey;

48
49
50
/// Index of the validator is used as a lightweight replacement of the `ValidatorId` when appropriate.
pub type ValidatorIndex = u32;

51
 /// Signature with which parachain validators sign blocks.
Gav Wood's avatar
Gav Wood committed
52
53
54
55
///
/// For now we assert that parachain validator set is exactly equivalent to the (Aura) authority set, and
/// so we define it to be the same type as `SessionKey`. In the future it may have different crypto.
pub type ValidatorSignature = super::SessionSignature;
Gav's avatar
Gav committed
56

57
/// Identifier for a chain, either one of a number of parachains or the relay chain.
58
#[derive(Copy, Clone, PartialEq, Encode, Decode)]
59
60
61
62
63
64
65
66
67
#[cfg_attr(feature = "std", derive(Debug))]
pub enum Chain {
	/// The relay chain.
	Relay,
	/// A parachain of the given index.
	Parachain(Id),
}

/// The duty roster specifying what jobs each validator must do.
68
#[derive(Clone, PartialEq, Encode, Decode)]
69
70
71
72
73
74
#[cfg_attr(feature = "std", derive(Default, Debug))]
pub struct DutyRoster {
	/// Lookup from validator index to chain on which that validator has a duty to validate.
	pub validator_duty: Vec<Chain>,
}

75
/// An outgoing message
76
77
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
pub struct OutgoingMessage {
	/// The target parachain.
	pub target: Id,
	/// The message data.
	pub data: Vec<u8>,
}

impl PartialOrd for OutgoingMessage {
	fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
		Some(self.target.cmp(&other.target))
	}
}

impl Ord for OutgoingMessage {
	fn cmp(&self, other: &Self) -> Ordering {
		self.target.cmp(&other.target)
	}
}

/// Extrinsic data for a parachain candidate.
///
/// This is data produced by evaluating the candidate. It contains
/// full records of all outgoing messages to other parachains.
103
104
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
105
106
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
107
108
109
110
111
112
pub struct Extrinsic {
	/// The outgoing messages from the execution of the parachain.
	///
	/// This must be sorted in ascending order by parachain ID.
	pub outgoing_messages: Vec<OutgoingMessage>
}
113

Gav's avatar
Gav committed
114
/// Candidate receipt type.
115
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
Gav Wood's avatar
Gav Wood committed
116
#[cfg_attr(feature = "std", derive(Debug))]
Gav's avatar
Gav committed
117
118
119
pub struct CandidateReceipt {
	/// The ID of the parachain this is a candidate for.
	pub parachain_index: Id,
120
	/// The collator's relay-chain account ID
Gav Wood's avatar
Gav Wood committed
121
	pub collator: CollatorId,
122
	/// Signature on blake2-256 of the block data by collator.
Gav Wood's avatar
Gav Wood committed
123
	pub signature: CollatorSignature,
Gav's avatar
Gav committed
124
125
	/// The head-data
	pub head_data: HeadData,
126
127
	/// Egress queue roots. Must be sorted lexicographically (ascending)
	/// by parachain ID.
Gav Wood's avatar
Gav Wood committed
128
	pub egress_queue_roots: Vec<(Id, Hash)>,
Gav's avatar
Gav committed
129
	/// Fees paid from the chain to the relay chain validators
130
	pub fees: Balance,
131
132
	/// blake2-256 Hash of block data.
	pub block_data_hash: Hash,
133
134
	/// Messages destined to be interpreted by the Relay chain itself.
	pub upward_messages: Vec<UpwardMessage>,
Gav's avatar
Gav committed
135
136
}

137
138
139
impl CandidateReceipt {
	/// Get the blake2_256 hash
	pub fn hash(&self) -> Hash {
140
		use runtime_primitives::traits::{BlakeTwo256, Hash};
Gav Wood's avatar
Gav Wood committed
141
		BlakeTwo256::hash_of(self)
142
	}
143
144
145
146
147

	/// Check integrity vs. provided block data.
	pub fn check_signature(&self) -> Result<(), ()> {
		use runtime_primitives::traits::Verify;

148
		if self.signature.verify(self.block_data_hash.as_ref(), &self.collator) {
149
150
151
152
153
			Ok(())
		} else {
			Err(())
		}
	}
154
155
156
157
158
159
160
161
162
163
164
}

impl PartialOrd for CandidateReceipt {
	fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
		Some(self.cmp(other))
	}
}

impl Ord for CandidateReceipt {
	fn cmp(&self, other: &Self) -> Ordering {
		// TODO: compare signatures or something more sane
165
		// https://github.com/paritytech/polkadot/issues/222
166
167
168
169
170
		self.parachain_index.cmp(&other.parachain_index)
			.then_with(|| self.head_data.cmp(&other.head_data))
	}
}

171
/// A full collation.
172
173
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Debug, Encode, Decode))]
174
175
176
pub struct Collation {
	/// Candidate receipt itself.
	pub receipt: CandidateReceipt,
177
178
	/// A proof-of-validation for the receipt.
	pub pov: PoVBlock,
179
180
}

181
/// A Proof-of-Validation block.
Gav's avatar
Gav committed
182
#[derive(PartialEq, Eq, Clone)]
183
184
185
186
187
188
189
190
191
192
193
#[cfg_attr(feature = "std", derive(Debug, Encode, Decode))]
pub struct PoVBlock {
	/// Block data.
	pub block_data: BlockData,
	/// Ingress for the parachain.
	pub ingress: ConsolidatedIngress,
}

/// Parachain ingress queue message.
#[derive(PartialEq, Eq, Clone, Decode)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Encode, Debug))]
Gav's avatar
Gav committed
194
195
pub struct Message(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);

196
/// All ingress roots at one block.
197
///
198
199
200
201
202
203
204
205
206
/// This is an ordered vector of other parachain's egress queue roots from a specific block.
/// empty roots are omitted. Each parachain may appear once at most.
#[derive(Default, PartialEq, Eq, Clone, Encode)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Decode))]
pub struct BlockIngressRoots(pub Vec<(Id, Hash)>);

/// All ingress roots, grouped by block number (ascending). To properly
/// interpret this struct, the user must have knowledge of which fork of the relay
/// chain all block numbers correspond to.
207
208
#[derive(Default, PartialEq, Eq, Clone, Encode)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Decode))]
209
210
211
212
213
214
215
216
pub struct StructuredUnroutedIngress(pub Vec<(BlockNumber, BlockIngressRoots)>);

#[cfg(feature = "std")]
impl StructuredUnroutedIngress {
	/// Get the length of all the ingress roots across all blocks.
	pub fn len(&self) -> usize {
		self.0.iter().fold(0, |a, (_, roots)| a + roots.0.len())
	}
217

218
219
220
221
222
223
224
	/// Returns an iterator over all ingress roots. The block number indicates
	/// the height at which that root was posted to the relay chain. The parachain ID is the
	/// message sender.
	pub fn iter(&self) -> impl Iterator<Item=(BlockNumber, &Id, &Hash)> {
		self.0.iter().flat_map(|&(n, ref roots)|
			roots.0.iter().map(move |&(ref from, ref root)| (n, from, root))
		)
225
226
227
	}
}

Gav's avatar
Gav committed
228
229
230
/// Consolidated ingress queue data.
///
/// This is just an ordered vector of other parachains' egress queues,
231
/// obtained according to the routing rules. The same parachain may appear
232
/// more than once.
233
234
#[derive(Default, PartialEq, Eq, Clone, Decode)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Encode, Debug))]
Gav's avatar
Gav committed
235
236
237
238
239
pub struct ConsolidatedIngress(pub Vec<(Id, Vec<Message>)>);

/// Parachain block data.
///
/// contains everything required to validate para-block, may contain block and witness data
240
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
Gav Wood's avatar
Gav Wood committed
241
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
Gav's avatar
Gav committed
242
243
pub struct BlockData(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);

244
245
246
247
impl BlockData {
	/// Compute hash of block data.
	#[cfg(feature = "std")]
	pub fn hash(&self) -> Hash {
248
		use runtime_primitives::traits::{BlakeTwo256, Hash};
249
250
251
		BlakeTwo256::hash(&self.0[..])
	}
}
Gav's avatar
Gav committed
252
253
/// Parachain header raw bytes wrapper type.
#[derive(PartialEq, Eq)]
Gav Wood's avatar
Gav Wood committed
254
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
Gav's avatar
Gav committed
255
256
257
pub struct Header(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);

/// Parachain head data included in the chain.
258
#[derive(PartialEq, Eq, Clone, PartialOrd, Ord, Encode, Decode)]
Gav Wood's avatar
Gav Wood committed
259
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
Gav's avatar
Gav committed
260
261
262
263
pub struct HeadData(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);

/// Parachain validation code.
#[derive(PartialEq, Eq)]
Gav Wood's avatar
Gav Wood committed
264
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
Gav's avatar
Gav committed
265
266
pub struct ValidationCode(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);

267
/// Activity bit field
268
#[derive(PartialEq, Eq, Clone, Default, Encode, Decode)]
Gav Wood's avatar
Gav Wood committed
269
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
Gav's avatar
Gav committed
270
271
pub struct Activity(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);

272
/// Statements which can be made about parachain candidates.
273
274
#[derive(Clone, PartialEq, Eq, Encode)]
#[cfg_attr(feature = "std", derive(Debug))]
275
276
pub enum Statement {
	/// Proposal of a parachain candidate.
277
	#[codec(index = "1")]
278
279
	Candidate(CandidateReceipt),
	/// State that a parachain candidate is valid.
280
	#[codec(index = "2")]
281
	Valid(Hash),
282
283
	/// State a candidate is invalid.
	#[codec(index = "3")]
284
285
	Invalid(Hash),
}
286

287
288
289
290
291
292
293
294
/// An either implicit or explicit attestation to the validity of a parachain
/// candidate.
#[derive(Clone, PartialEq, Decode, Encode)]
#[cfg_attr(feature = "std", derive(Debug))]
pub enum ValidityAttestation {
	/// implicit validity attestation by issuing.
	/// This corresponds to issuance of a `Candidate` statement.
	#[codec(index = "1")]
Gav Wood's avatar
Gav Wood committed
295
	Implicit(CollatorSignature),
296
297
298
	/// An explicit attestation. This corresponds to issuance of a
	/// `Valid` statement.
	#[codec(index = "2")]
Gav Wood's avatar
Gav Wood committed
299
	Explicit(CollatorSignature),
300
301
302
303
304
305
306
307
308
}

/// An attested candidate.
#[derive(Clone, PartialEq, Decode, Encode)]
#[cfg_attr(feature = "std", derive(Debug))]
pub struct AttestedCandidate {
	/// The candidate data.
	pub candidate: CandidateReceipt,
	/// Validity attestations.
309
310
311
	pub validity_votes: Vec<ValidityAttestation>,
	/// Indices of the corresponding validity votes.
	pub validator_indices: BitVec,
312
313
314
315
316
317
318
319
320
321
322
323
324
325
}

impl AttestedCandidate {
	/// Get the candidate.
	pub fn candidate(&self) -> &CandidateReceipt {
		&self.candidate
	}

	/// Get the group ID of the candidate.
	pub fn parachain_index(&self) -> Id {
		self.candidate.parachain_index
	}
}

326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
/// A fee schedule for messages. This is a linear function in the number of bytes of a message.
#[derive(PartialEq, Eq, PartialOrd, Hash, Default, Clone, Copy, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
pub struct FeeSchedule {
	/// The base fee charged for all messages.
	pub base: Balance,
	/// The per-byte fee charged on top of that.
	pub per_byte: Balance,
}

impl FeeSchedule {
	/// Compute the fee for a message of given size.
	pub fn compute_fee(&self, n_bytes: usize) -> Balance {
		use rstd::mem;
		debug_assert!(mem::size_of::<Balance>() >= mem::size_of::<usize>());

		let n_bytes = n_bytes as Balance;
		self.base.saturating_add(n_bytes.saturating_mul(self.per_byte))
	}
}

/// Current Status of a parachain.
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
pub struct Status {
	/// The head of the parachain.
	pub head_data: HeadData,
	/// The current balance of the parachain.
	pub balance: Balance,
	/// The fee schedule for messages coming from this parachain.
	pub fee_schedule: FeeSchedule,
}

359
substrate_client::decl_runtime_apis! {
360
361
362
	/// The API for querying the state of parachains on-chain.
	pub trait ParachainHost {
		/// Get the current validators.
Gav Wood's avatar
Gav Wood committed
363
		fn validators() -> Vec<ValidatorId>;
364
365
366
367
		/// Get the current duty roster.
		fn duty_roster() -> DutyRoster;
		/// Get the currently active parachains.
		fn active_parachains() -> Vec<Id>;
368
369
		/// Get the given parachain's status.
		fn parachain_status(id: Id) -> Option<Status>;
370
371
		/// Get the given parachain's head code blob.
		fn parachain_code(id: Id) -> Option<Vec<u8>>;
372
373
374
		/// Get all the unrouted ingress roots at the given block that
		/// are targeting the given parachain.
		fn ingress(to: Id) -> Option<StructuredUnroutedIngress>;
375
376
377
378
379
380
381
382
383
384
	}
}

/// Runtime ID module.
pub mod id {
	use sr_version::ApiId;

	/// Parachain host runtime API id.
	pub const PARACHAIN_HOST: ApiId = *b"parahost";
}
385
386
387
388
389
390
391
392
393
394
395
396
397

#[cfg(test)]
mod tests {
	use super::*;

	#[test]
	fn balance_bigger_than_usize() {
		let zero_b: Balance = 0;
		let zero_u: usize = 0;

		assert!(zero_b.leading_zeros() >= zero_u.leading_zeros());
	}
}