lib.rs 13.5 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/>.

17
//! The Polkadot runtime. This can be compiled with ``#[no_std]`, ready for Wasm.
Gav's avatar
Gav committed
18
19
20

#![cfg_attr(not(feature = "std"), no_std)]

Gav Wood's avatar
Gav Wood committed
21
22
23
24
25
26
27
#[cfg(feature = "std")]
#[macro_use]
extern crate serde_derive;

#[cfg(feature = "std")]
extern crate serde;

28
#[macro_use]
29
extern crate sr_io as runtime_io;
30
31

#[macro_use]
32
extern crate srml_support;
33
34

#[macro_use]
35
extern crate sr_primitives as runtime_primitives;
36

37
#[cfg(test)]
38
39
40
#[macro_use]
extern crate hex_literal;

41
42
43
44
45
#[cfg(test)]
extern crate substrate_serializer;

extern crate substrate_primitives;

Gav Wood's avatar
Gav Wood committed
46
#[macro_use]
47
extern crate sr_std as rstd;
Gav's avatar
Gav committed
48
#[macro_use]
49
extern crate parity_codec_derive;
Gav Wood's avatar
Gav Wood committed
50
51

extern crate polkadot_primitives as primitives;
52
53
54
55
56
57
58
59
60
61
62
extern crate parity_codec as codec;
extern crate srml_balances as balances;
extern crate srml_consensus as consensus;
extern crate srml_council as council;
extern crate srml_democracy as democracy;
extern crate srml_executive as executive;
extern crate srml_session as session;
extern crate srml_staking as staking;
extern crate srml_system as system;
extern crate srml_timestamp as timestamp;
extern crate srml_treasury as treasury;
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
63
#[macro_use]
64
extern crate sr_version as version;
Gav's avatar
Gav committed
65

Gav Wood's avatar
Gav Wood committed
66
67
#[cfg(feature = "std")]
mod checked_block;
68
mod parachains;
Gav Wood's avatar
Gav Wood committed
69
70
71
72
73
mod utils;

#[cfg(feature = "std")]
pub use checked_block::CheckedBlock;
pub use utils::{inherent_extrinsics, check_extrinsic};
Gav's avatar
Gav committed
74
pub use balances::address::Address as RawAddress;
75

76
77
78
79
80
use rstd::prelude::*;
use codec::{Encode, Decode, Input};
use substrate_primitives::u32_trait::{_2, _4};
use primitives::{AccountId, AccountIndex, Balance, BlockNumber, Hash, Index, SessionKey, Signature};
use runtime_primitives::{generic, traits::{Convert, BlakeTwo256, DigestItem}};
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
81
use version::RuntimeVersion;
82
use council::{motions as council_motions, voting as council_voting};
83
84

#[cfg(feature = "std")]
Gav Wood's avatar
Gav Wood committed
85
pub use runtime_primitives::BuildStorage;
86
87
88
89
90
91
92
93
94

pub use consensus::Call as ConsensusCall;
pub use timestamp::Call as TimestampCall;
pub use parachains::Call as ParachainsCall;

/// The position of the timestamp set extrinsic.
pub const TIMESTAMP_SET_POSITION: u32 = 0;
/// The position of the parachains set extrinsic.
pub const PARACHAINS_SET_POSITION: u32 = 1;
Gav's avatar
Gav committed
95
/// The position of the note_offline in the block, if it exists.
96
pub const NOTE_OFFLINE_POSITION: u32 = 2;
97

98
99
/// Block header type as expected by this runtime.
pub type Header = generic::Header<BlockNumber, BlakeTwo256, Log>;
Gav Wood's avatar
Gav Wood committed
100
/// The address format for describing accounts.
101
pub type Address = balances::Address<Runtime>;
Gav Wood's avatar
Gav Wood committed
102
103
104
/// Block Id type for this block.
pub type BlockId = generic::BlockId<Block>;
/// Unchecked extrinsic type as expected by this runtime.
Gav Wood's avatar
Gav Wood committed
105
pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Index, Call, Signature>;
106
107
/// Extrinsic type that has already been checked.
pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, Index, Call>;
Gav Wood's avatar
Gav Wood committed
108
109
110
/// Block type as expected by this runtime.
pub type Block = generic::Block<Header, UncheckedExtrinsic>;

111
/// Runtime runtime type used to parameterize the various modules.
Gav Wood's avatar
Gav Wood committed
112
113
114
// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted.
#[derive(Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
115
pub struct Runtime;
116

Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
117
118
119
120
/// Polkadot runtime version.
pub const VERSION: RuntimeVersion = RuntimeVersion {
	spec_name: ver_str!("polkadot"),
	impl_name: ver_str!("parity-polkadot"),
Gav Wood's avatar
Gav Wood committed
121
	authoring_version: 1,
122
	spec_version: 101,
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
123
124
125
	impl_version: 0,
};

126
127
impl system::Trait for Runtime {
	type Origin = Origin;
128
129
130
131
132
133
	type Index = Index;
	type BlockNumber = BlockNumber;
	type Hash = Hash;
	type Hashing = BlakeTwo256;
	type Digest = generic::Digest<Log>;
	type AccountId = AccountId;
Gav Wood's avatar
Gav Wood committed
134
	type Header = Header;
Gav's avatar
Gav committed
135
	type Event = Event;
136
137
}
/// System module for this concrete runtime.
138
pub type System = system::Module<Runtime>;
139

140
impl balances::Trait for Runtime {
Gav's avatar
Gav committed
141
142
143
	type Balance = Balance;
	type AccountIndex = AccountIndex;
	type OnFreeBalanceZero = Staking;
Gav's avatar
Fix    
Gav committed
144
	type EnsureAccountLiquid = Staking;
Gav's avatar
Gav committed
145
146
147
	type Event = Event;
}
/// Staking module for this concrete runtime.
148
pub type Balances = balances::Module<Runtime>;
Gav's avatar
Gav committed
149

150
impl consensus::Trait for Runtime {
Gav's avatar
Gav committed
151
	const NOTE_OFFLINE_POSITION: u32 = NOTE_OFFLINE_POSITION;
152
	type Log = Log;
153
	type SessionKey = SessionKey;
Gav's avatar
Gav committed
154
	type OnOfflineValidator = Staking;
155
156
}
/// Consensus module for this concrete runtime.
157
pub type Consensus = consensus::Module<Runtime>;
158

159
impl timestamp::Trait for Runtime {
160
161
	const TIMESTAMP_SET_POSITION: u32 = TIMESTAMP_SET_POSITION;
	type Moment = u64;
162
163
}
/// Timestamp module for this concrete runtime.
164
pub type Timestamp = timestamp::Module<Runtime>;
165

Gav Wood's avatar
Gav Wood committed
166
167
168
169
/// Session key conversion.
pub struct SessionKeyConversion;
impl Convert<AccountId, SessionKey> for SessionKeyConversion {
	fn convert(a: AccountId) -> SessionKey {
170
		a.0.into()
Gav Wood's avatar
Gav Wood committed
171
172
173
	}
}

174
impl session::Trait for Runtime {
Gav Wood's avatar
Gav Wood committed
175
	type ConvertAccountIdToSessionKey = SessionKeyConversion;
176
	type OnSessionChange = Staking;
Gav's avatar
Gav committed
177
	type Event = Event;
178
179
}
/// Session module for this concrete runtime.
180
pub type Session = session::Module<Runtime>;
181

182
183
impl staking::Trait for Runtime {
	type OnRewardMinted = Treasury;
Gav's avatar
Gav committed
184
	type Event = Event;
185
186
}
/// Staking module for this concrete runtime.
187
pub type Staking = staking::Module<Runtime>;
188

189
190
191
impl democracy::Trait for Runtime {
	type Proposal = Call;
	type Event = Event;
192
193
}
/// Democracy module for this concrete runtime.
194
195
196
197
198
pub type Democracy = democracy::Module<Runtime>;

impl council::Trait for Runtime {
	type Event = Event;
}
199
200

/// Council module for this concrete runtime.
201
202
203
204
205
206
pub type Council = council::Module<Runtime>;

impl council::voting::Trait for Runtime {
	type Event = Event;
}

207
/// Council voting module for this concrete runtime.
208
pub type CouncilVoting = council::voting::Module<Runtime>;
209

210
211
212
213
214
215
216
217
impl council::motions::Trait for Runtime {
	type Origin = Origin;
	type Proposal = Call;
	type Event = Event;
}

/// Council motions module for this concrete runtime.
pub type CouncilMotions = council_motions::Module<Runtime>;
218

219
220
221
222
impl treasury::Trait for Runtime {
	type ApproveOrigin = council_motions::EnsureMembers<_4>;
	type RejectOrigin = council_motions::EnsureMembers<_2>;
	type Event = Event;
223
}
224
225
226
227
228
229
230
231

/// Treasury module for this concrete runtime.
pub type Treasury = treasury::Module<Runtime>;

impl parachains::Trait for Runtime {
	const SET_POSITION: u32 = PARACHAINS_SET_POSITION;
}
pub type Parachains = parachains::Module<Runtime>;
232

Gav's avatar
Gav committed
233
impl_outer_event! {
234
235
236
237
238
239
240
241
242
243
244
	pub enum Event for Runtime {
		//consensus,
		balances,
		//timetstamp,
		session,
		staking,
		democracy,
		council,
		council_voting,
		council_motions,
		treasury
Gav's avatar
Gav committed
245
246
247
	}
}

248
249
250
impl_outer_log! {
	pub enum Log(InternalLog: DigestItem<SessionKey>) for Runtime {
		consensus(AuthoritiesChange)
251
	}
252
}
253

254
255
256
impl_outer_origin! {
	pub enum Origin for Runtime {
		council_motions
257
258
259
	}
}

260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
impl_outer_dispatch! {
	/// Call type for polkadot transactions.
	pub enum Call where origin: <Runtime as system::Trait>::Origin {
		Consensus,
		Balances,
		Session,
		Staking,
		Timestamp,
		Democracy,
		Council,
		CouncilVoting,
		CouncilMotions,
		Parachains,
		Treasury,
	}
}
276
277

impl_outer_config! {
278
	pub struct GenesisConfig for Runtime {
279
280
		ConsensusConfig => consensus,
		SystemConfig => system,
Gav's avatar
Gav committed
281
		BalancesConfig => balances,
282
283
284
285
		SessionConfig => session,
		StakingConfig => staking,
		DemocracyConfig => democracy,
		CouncilConfig => council,
286
		TimestampConfig => timestamp,
287
		TreasuryConfig => treasury,
288
289
290
291
		ParachainsConfig => parachains,
	}
}

292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
type AllModules = (
	Consensus,
	Balances,
	Session,
	Staking,
	Timestamp,
	Democracy,
	Council,
	CouncilVoting,
	CouncilMotions,
	Parachains,
	Treasury,
);

impl_json_metadata!(
	for Runtime with modules
		system::Module with Storage,
		consensus::Module with Storage,
		balances::Module with Storage,
		timestamp::Module with Storage,
		session::Module with Storage,
		staking::Module with Storage,
		democracy::Module with Storage,
		council::Module with Storage,
		council_voting::Module with Storage,
		council_motions::Module with Storage,
		treasury::Module with Storage,
		parachains::Module with Storage,
);

impl DigestItem for Log {
	type AuthorityId = SessionKey;

	fn as_authorities_change(&self) -> Option<&[Self::AuthorityId]> {
		match self.0 {
			InternalLog::consensus(ref item) => item.as_authorities_change(),
		}
	}
}

/// Executive: handles dispatch to the various modules.
pub type Executive = executive::Executive<Runtime, Block, Balances, Balances, AllModules>;

335
336
pub mod api {
	impl_stubs!(
337
338
		version => |()| super::VERSION,
		json_metadata => |()| super::Runtime::json_metadata(),
339
340
341
342
343
		authorities => |()| super::Consensus::authorities(),
		initialise_block => |header| super::Executive::initialise_block(&header),
		apply_extrinsic => |extrinsic| super::Executive::apply_extrinsic(extrinsic),
		execute_block => |block| super::Executive::execute_block(block),
		finalise_block => |()| super::Executive::finalise_block(),
Gav's avatar
Gav committed
344
		inherent_extrinsics => |(inherent, spec_version)| super::inherent_extrinsics(inherent, spec_version),
345
		validator_count => |()| super::Session::validator_count(),
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
346
347
348
349
		validators => |()| super::Session::validators(),
		timestamp => |()| super::Timestamp::get(),
		random_seed => |()| super::System::random_seed(),
		account_nonce => |account| super::System::account_nonce(&account),
350
351
352
353
354
		lookup_address => |address| super::Balances::lookup_address(address),
		duty_roster => |()| super::Parachains::calculate_duty_roster(),
		active_parachains => |()| super::Parachains::active_parachains(),
		parachain_head => |id| super::Parachains::parachain_head(&id),
		parachain_code => |id| super::Parachains::parachain_code(&id)
355
356
	);
}
357
358

#[cfg(test)]
359
360
361
mod tests {
	use super::*;
	use substrate_primitives as primitives;
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
362
	use codec::{Encode, Decode};
363
364
	use substrate_primitives::hexdisplay::HexDisplay;
	use substrate_serializer as ser;
365
	use runtime_primitives::traits::Header as HeaderT;
366
367
368
369
370
371
372
373
374
	type Digest = generic::Digest<Log>;

	#[test]
	fn test_header_serialization() {
		let header = Header {
			parent_hash: 5.into(),
			number: 67,
			state_root: 3.into(),
			extrinsics_root: 6.into(),
375
			digest: Digest::default(),
376
377
378
379
380
381
382
383
		};

		assert_eq!(ser::to_string_pretty(&header), r#"{
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000005",
  "number": 67,
  "stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000003",
  "extrinsicsRoot": "0x0000000000000000000000000000000000000000000000000000000000000006",
  "digest": {
384
    "logs": []
385
386
387
388
389
  }
}"#);

		let v = header.encode();
		assert_eq!(Header::decode(&mut &v[..]).unwrap(), header);
Gav's avatar
Gav committed
390
391
	}

392
393
394
395
396
	#[test]
	fn block_encoding_round_trip() {
		let mut block = Block {
			header: Header::new(1, Default::default(), Default::default(), Default::default(), Default::default()),
			extrinsics: vec![
397
				UncheckedExtrinsic::new_unsigned(
Gav Wood's avatar
Gav Wood committed
398
					Default::default(),
399
					Call::Timestamp(timestamp::Call::set(100_000_000))
Gav Wood's avatar
Gav Wood committed
400
				)
401
402
403
404
405
406
407
408
			],
		};

		let raw = block.encode();
		let decoded = Block::decode(&mut &raw[..]).unwrap();

		assert_eq!(block, decoded);

409
410
411
		block.extrinsics.push(UncheckedExtrinsic::new_unsigned(
			10101,
			Call::Staking(staking::Call::stake())
Gav Wood's avatar
Gav Wood committed
412
		));
413
414
415

		let raw = block.encode();
		let decoded = Block::decode(&mut &raw[..]).unwrap();
Gav's avatar
Gav committed
416

417
		assert_eq!(block, decoded);
Gav's avatar
Gav committed
418
419
	}

420
421
422
423
424
	#[test]
	fn block_encoding_substrate_round_trip() {
		let mut block = Block {
			header: Header::new(1, Default::default(), Default::default(), Default::default(), Default::default()),
			extrinsics: vec![
425
				UncheckedExtrinsic::new_unsigned(
Gav Wood's avatar
Gav Wood committed
426
					Default::default(),
427
					Call::Timestamp(timestamp::Call::set(100_000_000))
Gav Wood's avatar
Gav Wood committed
428
				)
429
430
431
			],
		};

432
433
434
		block.extrinsics.push(UncheckedExtrinsic::new_unsigned(
			10101,
			Call::Staking(staking::Call::stake())
Gav Wood's avatar
Gav Wood committed
435
		));
436
437

		let raw = block.encode();
Gav Wood's avatar
Gav Wood committed
438
439
440
		let decoded_primitive = ::primitives::Block::decode(&mut &raw[..]).unwrap();
		let encoded_primitive = decoded_primitive.encode();
		let decoded = Block::decode(&mut &encoded_primitive[..]).unwrap();
441
442
443
444
445
446

		assert_eq!(block, decoded);
	}

	#[test]
	fn serialize_unchecked() {
447
448
449
450
		let tx = UncheckedExtrinsic::new_signed(
			999,
			Call::Timestamp(TimestampCall::set(135135)),
			AccountId::from([1; 32]).into(),
Gav Wood's avatar
Gav Wood committed
451
452
453
454
455
456
457
			runtime_primitives::Ed25519Signature(primitives::hash::H512([0; 64])).into()
		);

		// 6f000000
		// ff0101010101010101010101010101010101010101010101010101010101010101
		// e7030000
		// 0300
458
459
460
		// df0f0200
		// 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
461
		let v = Encode::encode(&tx);
462
		assert_eq!(&v[..], &hex!["7000000001ff010101010101010101010101010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e70300000400df0f020000000000"][..]);
463
464
		println!("{}", HexDisplay::from(&v));
		assert_eq!(UncheckedExtrinsic::decode(&mut &v[..]).unwrap(), tx);
Gav's avatar
Gav committed
465
	}
466

467
468
	#[test]
	fn parachain_calls_are_privcall() {
469
470
		let _register = Call::Parachains(parachains::Call::register_parachain(0.into(), vec![1, 2, 3], vec![]));
		let _deregister = Call::Parachains(parachains::Call::deregister_parachain(0.into()));
471
	}
Gav's avatar
Gav committed
472
}